# HG changeset patch # User jbe # Date 1428507811 -7200 # Node ID 4f9e4c6109f46e904d87d6c30feb0796d65edfb4 # Parent 51ff6ad11677d342361b88df6914231fd0f179e5 Different buffering model for I/O writer diff -r 51ff6ad11677 -r 4f9e4c6109f4 moonbridge_io.c --- a/moonbridge_io.c Wed Apr 08 05:26:15 2015 +0200 +++ b/moonbridge_io.c Wed Apr 08 17:43:31 2015 +0200 @@ -46,7 +46,8 @@ int writeqout; #endif size_t writeqoff; - int writebufcnt; + int writebufin; + int writebufout; char readbuf[MOONBR_IO_READBUFLEN]; char writebuf[MOONBR_IO_WRITEBUFLEN]; } moonbr_io_handle_t; @@ -126,7 +127,7 @@ size_t luabufcnt = 0; int endcnt; char *terminatorpos; - ssize_t result; + ssize_t bytesread; handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); maxread = luaL_optinteger(L, 2, 0); terminatorstr = luaL_optlstring(L, 3, "", &terminatorlen); @@ -168,17 +169,17 @@ luabufcnt += handle->readbufcnt; handle->readbufcnt = 0; do { - result = read(handle->fd, handle->readbuf, MOONBR_IO_READBUFLEN); - } while (result < 0 && (errno == EINTR)); - if (result == 0 || (nonblocking && result < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))) break; - if (result < 0) { + bytesread = read(handle->fd, handle->readbuf, MOONBR_IO_READBUFLEN); + } while (bytesread < 0 && (errno == EINTR)); + if (bytesread == 0 || (nonblocking && bytesread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))) break; + if (bytesread < 0) { moonbr_io_errmsg(); handle->readerr = 1; lua_pushnil(L); lua_pushstring(L, errmsg); return 2; } - handle->readbufcnt += result; + handle->readbufcnt += bytesread; } if (!drain) { luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt); @@ -187,14 +188,14 @@ luabufcnt += handle->readbufcnt; handle->readbufcnt = 0; if (!drain) { - if (!luabufcnt && result == 0) { + if (!luabufcnt && bytesread == 0) { moonbr_io_read_impl_eof: lua_pushboolean(L, 0); lua_pushliteral(L, "End of file"); return 2; } } else { - if (!luabufcnt && result == 0) lua_pushboolean(L, 1); + if (!luabufcnt && bytesread == 0) lua_pushboolean(L, 1); else lua_pushboolean(L, luabufcnt); } return 1; @@ -221,8 +222,7 @@ int i, top; const char *str; size_t strlen; - size_t written; - ssize_t result; + ssize_t written; handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); if (handle->closed) luaL_error(L, "Attempt to write to a closed I/O handle"); if (handle->finished) luaL_error(L, "Attempt to write to a finished I/O handle"); @@ -231,10 +231,11 @@ lua_pushliteral(L, "Previous write error"); return 2; } + handle->writeerr = 1; moonbr_io_handle_set_nonblocking(L, handle, nonblocking); top = lua_gettop(L); lua_getuservalue(L, 1); - lua_getfield(L, -1, "writebuf"); + lua_getfield(L, -1, "writequeue"); for (i=2; i<=top; i++) { luaL_checklstring(L, i, &strlen); lua_pushvalue(L, i); @@ -245,39 +246,48 @@ lua_rawgeti(L, -1, handle->writeqout); str = lua_tolstring(L, -1, &strlen); while (handle->writeqoff < strlen) { - if (strlen - handle->writeqoff <= MOONBR_IO_WRITEBUFLEN - handle->writebufcnt) { - memcpy(handle->writebuf + handle->writebufcnt, str + handle->writeqoff, strlen - handle->writeqoff); - handle->writebufcnt += strlen - handle->writeqoff; + if ( + strlen - handle->writeqoff <= + MOONBR_IO_WRITEBUFLEN - handle->writebufin + ) { + memcpy( + handle->writebuf + handle->writebufin, + str + handle->writeqoff, + strlen - handle->writeqoff + ); + handle->writebufin += strlen - handle->writeqoff; break; } else { moonbr_io_handle_set_nopush(L, handle, 1); - written = 0; - memcpy(handle->writebuf + handle->writebufcnt, str + handle->writeqoff, MOONBR_IO_WRITEBUFLEN - handle->writebufcnt); - handle->writeqoff += MOONBR_IO_WRITEBUFLEN - handle->writebufcnt; - while (written < MOONBR_IO_WRITEBUFLEN) { - result = write(handle->fd, handle->writebuf + written, MOONBR_IO_WRITEBUFLEN - written); - if (result < 0) { + memcpy( + handle->writebuf + handle->writebufin, + str + handle->writeqoff, + MOONBR_IO_WRITEBUFLEN - handle->writebufin + ); + handle->writeqoff += MOONBR_IO_WRITEBUFLEN - handle->writebufin; + while (handle->writebufout < MOONBR_IO_WRITEBUFLEN) { + written = write( + handle->fd, + handle->writebuf + handle->writebufout, + MOONBR_IO_WRITEBUFLEN - handle->writebufout + ); + if (written < 0) { if (nonblocking && (errno == EAGAIN || errno == EWOULDBLOCK)) { - if (written) { - handle->writebufcnt -= written; - memmove(handle->writebuf, handle->writebuf + written, handle->writebufcnt); - goto moonbr_io_write_impl_continue; - } goto moonbr_io_write_impl_block; } else if (errno != EINTR) { moonbr_io_errmsg(); - handle->writeerr = 1; lua_pushnil(L); lua_pushstring(L, errmsg); return 2; } + } else { + handle->writebufout += written; + handle->writeleft -= written; } - written += result; - handle->writeleft -= result; } - handle->writebufcnt = 0; + handle->writebufin = 0; + handle->writebufout = 0; } - moonbr_io_write_impl_continue:; } handle->writeqoff = 0; lua_pop(L, 1); @@ -286,37 +296,36 @@ } if (flush) { moonbr_io_handle_set_nopush(L, handle, 0); - written = 0; - while (written < handle->writebufcnt) { - result = write(handle->fd, handle->writebuf + written, handle->writebufcnt - written); - if (result < 0) { + while (handle->writebufout < handle->writebufin) { + written = write( + handle->fd, + handle->writebuf + handle->writebufout, + handle->writebufin - handle->writebufout + ); + if (written < 0) { if (nonblocking && (errno == EAGAIN || errno == EWOULDBLOCK)) { - if (written) { - handle->writebufcnt -= written; - memmove(handle->writebuf, handle->writebuf + written, handle->writebufcnt); - } goto moonbr_io_write_impl_block; } else if (errno != EINTR) { moonbr_io_errmsg(); - handle->writeerr = -1; lua_pushnil(L); lua_pushstring(L, errmsg); return 2; } } else { - written += result; - handle->writeleft -= result; + handle->writebufout += written; + handle->writeleft -= written; } } - handle->writebufcnt = 0; - if (nonblocking) lua_pushinteger(L, 0); - } else { - if (nonblocking) lua_pushinteger(L, handle->writeleft); + handle->writebufin = 0; + handle->writebufout = 0; } - if (!nonblocking) lua_pushvalue(L, 1); + if (nonblocking) lua_pushinteger(L, 0); + else lua_pushvalue(L, 1); + handle->writeerr = 0; return 1; moonbr_io_write_impl_block: lua_pushinteger(L, handle->writeleft); + handle->writeerr = 0; return 1; } @@ -450,13 +459,14 @@ handle->writeqin = 0; handle->writeqout = 0; handle->writeqoff = 0; - handle->writebufcnt = 0; + handle->writebufin = 0; + handle->writebufout = 0; moonbr_io_handle_set_linger(L, handle, 0); luaL_getmetatable(L, MOONBR_IO_HANDLE_MT_REGKEY); lua_setmetatable(L, -2); lua_newtable(L); // uservalue lua_newtable(L); - lua_setfield(L, -2, "writebuf"); + lua_setfield(L, -2, "writequeue"); lua_newtable(L); // public luaL_getmetatable(L, MOONBR_IO_HANDLE_PUBLIC_MT_REGKEY); lua_setmetatable(L, -2);