moonbridge
changeset 83:697cdf8e2000
Code cleanup and fixes in optionally non-blocking write/write_nb method; Allow to mark I/O handles as closed
author | jbe |
---|---|
date | Mon Apr 06 15:02:15 2015 +0200 (2015-04-06) |
parents | 069ee3f5ab17 |
children | 8a6e2a80fcad |
files | moonbridge_io.c moonbridge_io.h |
line diff
1.1 --- a/moonbridge_io.c Mon Apr 06 03:41:30 2015 +0200 1.2 +++ b/moonbridge_io.c Mon Apr 06 15:02:15 2015 +0200 1.3 @@ -30,12 +30,31 @@ 1.4 int fd; 1.5 int nonblocking; 1.6 int writeerr; 1.7 - int writeleft; 1.8 - int writeqoff; 1.9 + size_t writeleft; 1.10 +#if LUA_VERSION_NUM >= 503 1.11 + lua_Integer writeqin; 1.12 + lua_Integer writeqout; 1.13 +#else 1.14 + int writeqin; 1.15 + int writeqout; 1.16 +#endif 1.17 + size_t writeqoff; 1.18 int writebufcnt; 1.19 char writebuf[MOONBR_IO_WRITEBUFLEN]; 1.20 } moonbr_io_handle_t; 1.21 1.22 +int moonbr_io_isclosed(lua_State *L, int idx) { 1.23 + moonbr_io_handle_t *handle; 1.24 + handle = luaL_checkudata(L, idx, MOONBR_IO_HANDLE_MT_REGKEY); 1.25 + return handle->fd < 0; 1.26 +} 1.27 + 1.28 +void moonbr_io_markclosed(lua_State *L, int idx) { 1.29 + moonbr_io_handle_t *handle; 1.30 + handle = luaL_checkudata(L, idx, MOONBR_IO_HANDLE_MT_REGKEY); 1.31 + handle->fd = -1; 1.32 +} 1.33 + 1.34 static void moonbr_io_handle_set_nonblocking(lua_State *L, moonbr_io_handle_t *handle, int nonblocking) { 1.35 if (handle->nonblocking != nonblocking) { 1.36 int flags; 1.37 @@ -53,31 +72,15 @@ 1.38 } 1.39 } 1.40 1.41 -static int moonbr_io_close(lua_State *L) { 1.42 - moonbr_io_handle_t *handle; 1.43 - handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); 1.44 - if (handle->fd < 0) luaL_error(L, "Attempt to close a closed I/O handle"); 1.45 - if (close(handle->fd)) { 1.46 - handle->fd = -1; 1.47 - moonbr_io_errmsg(); 1.48 - lua_pushnil(L); 1.49 - lua_pushstring(L, errmsg); 1.50 - return 2; 1.51 - } 1.52 - handle->fd = -1; 1.53 - lua_pushboolean(L, 1); 1.54 - return 1; 1.55 -} 1.56 - 1.57 static int moonbr_io_write_impl(lua_State *L, int nonblocking, int flush) { 1.58 moonbr_io_handle_t *handle; 1.59 int i, top; 1.60 - lua_Integer qlen, qpos, qpos2; 1.61 const char *str; 1.62 size_t strlen, strpos; 1.63 size_t written; 1.64 ssize_t result; 1.65 handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); 1.66 + if (handle->fd < 0) luaL_error(L, "Attempt to write to a closed I/O handle"); 1.67 if (handle->writeerr) { 1.68 lua_pushnil(L); 1.69 lua_pushliteral(L, "Previous write error"); 1.70 @@ -87,17 +90,16 @@ 1.71 if (!flush) top = lua_gettop(L); 1.72 lua_getuservalue(L, 1); 1.73 lua_getfield(L, -1, "writebuf"); 1.74 - qlen = lua_rawlen(L, -1); 1.75 if (!flush) { 1.76 for (i=2; i<=top; i++) { 1.77 luaL_checklstring(L, i, &strlen); 1.78 lua_pushvalue(L, i); 1.79 - lua_rawseti(L, -2, ++qlen); 1.80 + lua_rawseti(L, -2, handle->writeqin++); 1.81 handle->writeleft += strlen; 1.82 } 1.83 } 1.84 - for (qpos=1; qpos<=qlen; qpos++) { 1.85 - lua_rawgeti(L, -1, qpos); 1.86 + while (handle->writeqout != handle->writeqin) { 1.87 + lua_rawgeti(L, -1, handle->writeqout); 1.88 str = lua_tolstring(L, -1, &strlen); 1.89 strpos = handle->writeqoff; 1.90 while (strpos < strlen) { 1.91 @@ -117,13 +119,6 @@ 1.92 handle->writebufcnt -= written; 1.93 memmove(handle->writebuf, handle->writebuf + written, handle->writebufcnt); 1.94 } 1.95 - if (i > 1) { 1.96 - for (qpos2=1; qpos2<=qlen; qpos2++) { 1.97 - if (qpos2+qpos-1 <= qlen) lua_rawgeti(L, -1, qpos2+qpos-1); 1.98 - else lua_pushnil(L); 1.99 - lua_rawseti(L, -2, qpos2); 1.100 - } 1.101 - } 1.102 handle->writeqoff = strpos; 1.103 goto moonbr_io_write_impl_block; 1.104 } else if (errno != EINTR) { 1.105 @@ -144,7 +139,7 @@ 1.106 handle->writeqoff = 0; 1.107 lua_pop(L, 1); 1.108 lua_pushnil(L); 1.109 - lua_rawseti(L, -2, qpos); 1.110 + lua_rawseti(L, -2, handle->writeqout++); 1.111 } 1.112 if (flush) { 1.113 written = 0; 1.114 @@ -198,6 +193,32 @@ 1.115 return moonbr_io_write_impl(L, 1, 1); 1.116 } 1.117 1.118 +static int moonbr_io_close(lua_State *L) { 1.119 + moonbr_io_handle_t *handle; 1.120 + handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); 1.121 + if (handle->fd < 0) luaL_error(L, "Attempt to close a closed I/O handle"); 1.122 + if (handle->writeleft) { 1.123 + lua_pushcfunction(L, moonbr_io_flush); 1.124 + lua_pushvalue(L, 1); 1.125 + lua_call(L, 1, 2); 1.126 + if (!lua_toboolean(L, -2)) { 1.127 + close(handle->fd); 1.128 + handle->fd = -1; 1.129 + return 2; 1.130 + } 1.131 + } 1.132 + if (close(handle->fd)) { 1.133 + moonbr_io_errmsg(); 1.134 + handle->fd = -1; 1.135 + lua_pushnil(L); 1.136 + lua_pushstring(L, errmsg); 1.137 + return 2; 1.138 + } 1.139 + handle->fd = -1; 1.140 + lua_pushboolean(L, 1); 1.141 + return 1; 1.142 +} 1.143 + 1.144 void moonbr_io_pushhandle(lua_State *L, int fd, int gc_idx) { 1.145 moonbr_io_handle_t *handle; 1.146 handle = lua_newuserdata(L, sizeof(moonbr_io_handle_t)); 1.147 @@ -205,6 +226,8 @@ 1.148 handle->nonblocking = -1; 1.149 handle->writeerr = 0; 1.150 handle->writeleft = 0; 1.151 + handle->writeqin = 0; 1.152 + handle->writeqout = 0; 1.153 handle->writeqoff = 0; 1.154 handle->writebufcnt = 0; 1.155 luaL_getmetatable(L, MOONBR_IO_HANDLE_MT_REGKEY);
2.1 --- a/moonbridge_io.h Mon Apr 06 03:41:30 2015 +0200 2.2 +++ b/moonbridge_io.h Mon Apr 06 15:02:15 2015 +0200 2.3 @@ -1,4 +1,6 @@ 2.4 2.5 void moonbr_io_pushhandle(lua_State *L, int fd, int gc_idx); 2.6 +int moonbr_io_isclosed(lua_State *L, int idx); 2.7 +void moonbr_io_markclosed(lua_State *L, int idx); 2.8 int luaopen_moonbridge_io(lua_State *L); 2.9