# HG changeset patch # User jbe # Date 1428325335 -7200 # Node ID 697cdf8e20003b704dc90a4f6f79769fe79b7edb # Parent 069ee3f5ab1745d40e1d007ddaebc0cc18d72fc4 Code cleanup and fixes in optionally non-blocking write/write_nb method; Allow to mark I/O handles as closed diff -r 069ee3f5ab17 -r 697cdf8e2000 moonbridge_io.c --- a/moonbridge_io.c Mon Apr 06 03:41:30 2015 +0200 +++ b/moonbridge_io.c Mon Apr 06 15:02:15 2015 +0200 @@ -30,12 +30,31 @@ int fd; int nonblocking; int writeerr; - int writeleft; - int writeqoff; + size_t writeleft; +#if LUA_VERSION_NUM >= 503 + lua_Integer writeqin; + lua_Integer writeqout; +#else + int writeqin; + int writeqout; +#endif + size_t writeqoff; int writebufcnt; char writebuf[MOONBR_IO_WRITEBUFLEN]; } moonbr_io_handle_t; +int moonbr_io_isclosed(lua_State *L, int idx) { + moonbr_io_handle_t *handle; + handle = luaL_checkudata(L, idx, MOONBR_IO_HANDLE_MT_REGKEY); + return handle->fd < 0; +} + +void moonbr_io_markclosed(lua_State *L, int idx) { + moonbr_io_handle_t *handle; + handle = luaL_checkudata(L, idx, MOONBR_IO_HANDLE_MT_REGKEY); + handle->fd = -1; +} + static void moonbr_io_handle_set_nonblocking(lua_State *L, moonbr_io_handle_t *handle, int nonblocking) { if (handle->nonblocking != nonblocking) { int flags; @@ -53,31 +72,15 @@ } } -static int moonbr_io_close(lua_State *L) { - moonbr_io_handle_t *handle; - handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); - if (handle->fd < 0) luaL_error(L, "Attempt to close a closed I/O handle"); - if (close(handle->fd)) { - handle->fd = -1; - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } - handle->fd = -1; - lua_pushboolean(L, 1); - return 1; -} - static int moonbr_io_write_impl(lua_State *L, int nonblocking, int flush) { moonbr_io_handle_t *handle; int i, top; - lua_Integer qlen, qpos, qpos2; const char *str; size_t strlen, strpos; size_t written; ssize_t result; handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); + if (handle->fd < 0) luaL_error(L, "Attempt to write to a closed I/O handle"); if (handle->writeerr) { lua_pushnil(L); lua_pushliteral(L, "Previous write error"); @@ -87,17 +90,16 @@ if (!flush) top = lua_gettop(L); lua_getuservalue(L, 1); lua_getfield(L, -1, "writebuf"); - qlen = lua_rawlen(L, -1); if (!flush) { for (i=2; i<=top; i++) { luaL_checklstring(L, i, &strlen); lua_pushvalue(L, i); - lua_rawseti(L, -2, ++qlen); + lua_rawseti(L, -2, handle->writeqin++); handle->writeleft += strlen; } } - for (qpos=1; qpos<=qlen; qpos++) { - lua_rawgeti(L, -1, qpos); + while (handle->writeqout != handle->writeqin) { + lua_rawgeti(L, -1, handle->writeqout); str = lua_tolstring(L, -1, &strlen); strpos = handle->writeqoff; while (strpos < strlen) { @@ -117,13 +119,6 @@ handle->writebufcnt -= written; memmove(handle->writebuf, handle->writebuf + written, handle->writebufcnt); } - if (i > 1) { - for (qpos2=1; qpos2<=qlen; qpos2++) { - if (qpos2+qpos-1 <= qlen) lua_rawgeti(L, -1, qpos2+qpos-1); - else lua_pushnil(L); - lua_rawseti(L, -2, qpos2); - } - } handle->writeqoff = strpos; goto moonbr_io_write_impl_block; } else if (errno != EINTR) { @@ -144,7 +139,7 @@ handle->writeqoff = 0; lua_pop(L, 1); lua_pushnil(L); - lua_rawseti(L, -2, qpos); + lua_rawseti(L, -2, handle->writeqout++); } if (flush) { written = 0; @@ -198,6 +193,32 @@ return moonbr_io_write_impl(L, 1, 1); } +static int moonbr_io_close(lua_State *L) { + moonbr_io_handle_t *handle; + handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); + if (handle->fd < 0) luaL_error(L, "Attempt to close a closed I/O handle"); + if (handle->writeleft) { + lua_pushcfunction(L, moonbr_io_flush); + lua_pushvalue(L, 1); + lua_call(L, 1, 2); + if (!lua_toboolean(L, -2)) { + close(handle->fd); + handle->fd = -1; + return 2; + } + } + if (close(handle->fd)) { + moonbr_io_errmsg(); + handle->fd = -1; + lua_pushnil(L); + lua_pushstring(L, errmsg); + return 2; + } + handle->fd = -1; + lua_pushboolean(L, 1); + return 1; +} + void moonbr_io_pushhandle(lua_State *L, int fd, int gc_idx) { moonbr_io_handle_t *handle; handle = lua_newuserdata(L, sizeof(moonbr_io_handle_t)); @@ -205,6 +226,8 @@ handle->nonblocking = -1; handle->writeerr = 0; handle->writeleft = 0; + handle->writeqin = 0; + handle->writeqout = 0; handle->writeqoff = 0; handle->writebufcnt = 0; luaL_getmetatable(L, MOONBR_IO_HANDLE_MT_REGKEY); diff -r 069ee3f5ab17 -r 697cdf8e2000 moonbridge_io.h --- a/moonbridge_io.h Mon Apr 06 03:41:30 2015 +0200 +++ b/moonbridge_io.h Mon Apr 06 15:02:15 2015 +0200 @@ -1,4 +1,6 @@ void moonbr_io_pushhandle(lua_State *L, int fd, int gc_idx); +int moonbr_io_isclosed(lua_State *L, int idx); +void moonbr_io_markclosed(lua_State *L, int idx); int luaopen_moonbridge_io(lua_State *L);