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  

Impressum / About Us