moonbridge
changeset 103:4f9e4c6109f4
Different buffering model for I/O writer
author | jbe |
---|---|
date | Wed Apr 08 17:43:31 2015 +0200 (2015-04-08) |
parents | 51ff6ad11677 |
children | 5e8eeb5b6c84 |
files | moonbridge_io.c |
line diff
1.1 --- a/moonbridge_io.c Wed Apr 08 05:26:15 2015 +0200 1.2 +++ b/moonbridge_io.c Wed Apr 08 17:43:31 2015 +0200 1.3 @@ -46,7 +46,8 @@ 1.4 int writeqout; 1.5 #endif 1.6 size_t writeqoff; 1.7 - int writebufcnt; 1.8 + int writebufin; 1.9 + int writebufout; 1.10 char readbuf[MOONBR_IO_READBUFLEN]; 1.11 char writebuf[MOONBR_IO_WRITEBUFLEN]; 1.12 } moonbr_io_handle_t; 1.13 @@ -126,7 +127,7 @@ 1.14 size_t luabufcnt = 0; 1.15 int endcnt; 1.16 char *terminatorpos; 1.17 - ssize_t result; 1.18 + ssize_t bytesread; 1.19 handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); 1.20 maxread = luaL_optinteger(L, 2, 0); 1.21 terminatorstr = luaL_optlstring(L, 3, "", &terminatorlen); 1.22 @@ -168,17 +169,17 @@ 1.23 luabufcnt += handle->readbufcnt; 1.24 handle->readbufcnt = 0; 1.25 do { 1.26 - result = read(handle->fd, handle->readbuf, MOONBR_IO_READBUFLEN); 1.27 - } while (result < 0 && (errno == EINTR)); 1.28 - if (result == 0 || (nonblocking && result < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))) break; 1.29 - if (result < 0) { 1.30 + bytesread = read(handle->fd, handle->readbuf, MOONBR_IO_READBUFLEN); 1.31 + } while (bytesread < 0 && (errno == EINTR)); 1.32 + if (bytesread == 0 || (nonblocking && bytesread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))) break; 1.33 + if (bytesread < 0) { 1.34 moonbr_io_errmsg(); 1.35 handle->readerr = 1; 1.36 lua_pushnil(L); 1.37 lua_pushstring(L, errmsg); 1.38 return 2; 1.39 } 1.40 - handle->readbufcnt += result; 1.41 + handle->readbufcnt += bytesread; 1.42 } 1.43 if (!drain) { 1.44 luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt); 1.45 @@ -187,14 +188,14 @@ 1.46 luabufcnt += handle->readbufcnt; 1.47 handle->readbufcnt = 0; 1.48 if (!drain) { 1.49 - if (!luabufcnt && result == 0) { 1.50 + if (!luabufcnt && bytesread == 0) { 1.51 moonbr_io_read_impl_eof: 1.52 lua_pushboolean(L, 0); 1.53 lua_pushliteral(L, "End of file"); 1.54 return 2; 1.55 } 1.56 } else { 1.57 - if (!luabufcnt && result == 0) lua_pushboolean(L, 1); 1.58 + if (!luabufcnt && bytesread == 0) lua_pushboolean(L, 1); 1.59 else lua_pushboolean(L, luabufcnt); 1.60 } 1.61 return 1; 1.62 @@ -221,8 +222,7 @@ 1.63 int i, top; 1.64 const char *str; 1.65 size_t strlen; 1.66 - size_t written; 1.67 - ssize_t result; 1.68 + ssize_t written; 1.69 handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); 1.70 if (handle->closed) luaL_error(L, "Attempt to write to a closed I/O handle"); 1.71 if (handle->finished) luaL_error(L, "Attempt to write to a finished I/O handle"); 1.72 @@ -231,10 +231,11 @@ 1.73 lua_pushliteral(L, "Previous write error"); 1.74 return 2; 1.75 } 1.76 + handle->writeerr = 1; 1.77 moonbr_io_handle_set_nonblocking(L, handle, nonblocking); 1.78 top = lua_gettop(L); 1.79 lua_getuservalue(L, 1); 1.80 - lua_getfield(L, -1, "writebuf"); 1.81 + lua_getfield(L, -1, "writequeue"); 1.82 for (i=2; i<=top; i++) { 1.83 luaL_checklstring(L, i, &strlen); 1.84 lua_pushvalue(L, i); 1.85 @@ -245,39 +246,48 @@ 1.86 lua_rawgeti(L, -1, handle->writeqout); 1.87 str = lua_tolstring(L, -1, &strlen); 1.88 while (handle->writeqoff < strlen) { 1.89 - if (strlen - handle->writeqoff <= MOONBR_IO_WRITEBUFLEN - handle->writebufcnt) { 1.90 - memcpy(handle->writebuf + handle->writebufcnt, str + handle->writeqoff, strlen - handle->writeqoff); 1.91 - handle->writebufcnt += strlen - handle->writeqoff; 1.92 + if ( 1.93 + strlen - handle->writeqoff <= 1.94 + MOONBR_IO_WRITEBUFLEN - handle->writebufin 1.95 + ) { 1.96 + memcpy( 1.97 + handle->writebuf + handle->writebufin, 1.98 + str + handle->writeqoff, 1.99 + strlen - handle->writeqoff 1.100 + ); 1.101 + handle->writebufin += strlen - handle->writeqoff; 1.102 break; 1.103 } else { 1.104 moonbr_io_handle_set_nopush(L, handle, 1); 1.105 - written = 0; 1.106 - memcpy(handle->writebuf + handle->writebufcnt, str + handle->writeqoff, MOONBR_IO_WRITEBUFLEN - handle->writebufcnt); 1.107 - handle->writeqoff += MOONBR_IO_WRITEBUFLEN - handle->writebufcnt; 1.108 - while (written < MOONBR_IO_WRITEBUFLEN) { 1.109 - result = write(handle->fd, handle->writebuf + written, MOONBR_IO_WRITEBUFLEN - written); 1.110 - if (result < 0) { 1.111 + memcpy( 1.112 + handle->writebuf + handle->writebufin, 1.113 + str + handle->writeqoff, 1.114 + MOONBR_IO_WRITEBUFLEN - handle->writebufin 1.115 + ); 1.116 + handle->writeqoff += MOONBR_IO_WRITEBUFLEN - handle->writebufin; 1.117 + while (handle->writebufout < MOONBR_IO_WRITEBUFLEN) { 1.118 + written = write( 1.119 + handle->fd, 1.120 + handle->writebuf + handle->writebufout, 1.121 + MOONBR_IO_WRITEBUFLEN - handle->writebufout 1.122 + ); 1.123 + if (written < 0) { 1.124 if (nonblocking && (errno == EAGAIN || errno == EWOULDBLOCK)) { 1.125 - if (written) { 1.126 - handle->writebufcnt -= written; 1.127 - memmove(handle->writebuf, handle->writebuf + written, handle->writebufcnt); 1.128 - goto moonbr_io_write_impl_continue; 1.129 - } 1.130 goto moonbr_io_write_impl_block; 1.131 } else if (errno != EINTR) { 1.132 moonbr_io_errmsg(); 1.133 - handle->writeerr = 1; 1.134 lua_pushnil(L); 1.135 lua_pushstring(L, errmsg); 1.136 return 2; 1.137 } 1.138 + } else { 1.139 + handle->writebufout += written; 1.140 + handle->writeleft -= written; 1.141 } 1.142 - written += result; 1.143 - handle->writeleft -= result; 1.144 } 1.145 - handle->writebufcnt = 0; 1.146 + handle->writebufin = 0; 1.147 + handle->writebufout = 0; 1.148 } 1.149 - moonbr_io_write_impl_continue:; 1.150 } 1.151 handle->writeqoff = 0; 1.152 lua_pop(L, 1); 1.153 @@ -286,37 +296,36 @@ 1.154 } 1.155 if (flush) { 1.156 moonbr_io_handle_set_nopush(L, handle, 0); 1.157 - written = 0; 1.158 - while (written < handle->writebufcnt) { 1.159 - result = write(handle->fd, handle->writebuf + written, handle->writebufcnt - written); 1.160 - if (result < 0) { 1.161 + while (handle->writebufout < handle->writebufin) { 1.162 + written = write( 1.163 + handle->fd, 1.164 + handle->writebuf + handle->writebufout, 1.165 + handle->writebufin - handle->writebufout 1.166 + ); 1.167 + if (written < 0) { 1.168 if (nonblocking && (errno == EAGAIN || errno == EWOULDBLOCK)) { 1.169 - if (written) { 1.170 - handle->writebufcnt -= written; 1.171 - memmove(handle->writebuf, handle->writebuf + written, handle->writebufcnt); 1.172 - } 1.173 goto moonbr_io_write_impl_block; 1.174 } else if (errno != EINTR) { 1.175 moonbr_io_errmsg(); 1.176 - handle->writeerr = -1; 1.177 lua_pushnil(L); 1.178 lua_pushstring(L, errmsg); 1.179 return 2; 1.180 } 1.181 } else { 1.182 - written += result; 1.183 - handle->writeleft -= result; 1.184 + handle->writebufout += written; 1.185 + handle->writeleft -= written; 1.186 } 1.187 } 1.188 - handle->writebufcnt = 0; 1.189 - if (nonblocking) lua_pushinteger(L, 0); 1.190 - } else { 1.191 - if (nonblocking) lua_pushinteger(L, handle->writeleft); 1.192 + handle->writebufin = 0; 1.193 + handle->writebufout = 0; 1.194 } 1.195 - if (!nonblocking) lua_pushvalue(L, 1); 1.196 + if (nonblocking) lua_pushinteger(L, 0); 1.197 + else lua_pushvalue(L, 1); 1.198 + handle->writeerr = 0; 1.199 return 1; 1.200 moonbr_io_write_impl_block: 1.201 lua_pushinteger(L, handle->writeleft); 1.202 + handle->writeerr = 0; 1.203 return 1; 1.204 } 1.205 1.206 @@ -450,13 +459,14 @@ 1.207 handle->writeqin = 0; 1.208 handle->writeqout = 0; 1.209 handle->writeqoff = 0; 1.210 - handle->writebufcnt = 0; 1.211 + handle->writebufin = 0; 1.212 + handle->writebufout = 0; 1.213 moonbr_io_handle_set_linger(L, handle, 0); 1.214 luaL_getmetatable(L, MOONBR_IO_HANDLE_MT_REGKEY); 1.215 lua_setmetatable(L, -2); 1.216 lua_newtable(L); // uservalue 1.217 lua_newtable(L); 1.218 - lua_setfield(L, -2, "writebuf"); 1.219 + lua_setfield(L, -2, "writequeue"); 1.220 lua_newtable(L); // public 1.221 luaL_getmetatable(L, MOONBR_IO_HANDLE_PUBLIC_MT_REGKEY); 1.222 lua_setmetatable(L, -2);