moonbridge

changeset 105:11d03470ef19

Refined buffer model for reading in I/O library
author jbe
date Wed Apr 08 19:37:09 2015 +0200 (2015-04-08)
parents 5e8eeb5b6c84
children 8fce76ef321f
files moonbridge_io.c
line diff
     1.1 --- a/moonbridge_io.c	Wed Apr 08 18:38:14 2015 +0200
     1.2 +++ b/moonbridge_io.c	Wed Apr 08 19:37:09 2015 +0200
     1.3 @@ -35,7 +35,8 @@
     1.4    int nonblocking;
     1.5    int nopush;
     1.6    int readerr;
     1.7 -  int readbufcnt;
     1.8 +  int readbufin;
     1.9 +  int readbufout;
    1.10    int writeerr;
    1.11    size_t writeleft;
    1.12  #if LUA_VERSION_NUM >= 503
    1.13 @@ -123,7 +124,7 @@
    1.14    char terminator;
    1.15    luaL_Buffer luabuf;
    1.16    size_t luabufcnt = 0;
    1.17 -  int endcnt;
    1.18 +  int remaining;
    1.19    char *terminatorpos;
    1.20    ssize_t bytesread;
    1.21    handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY);
    1.22 @@ -140,66 +141,91 @@
    1.23      lua_pushliteral(L, "Previous read error");
    1.24      return 2;
    1.25    }
    1.26 +  handle->readerr = 1;
    1.27    if (handle->fd < 0) goto moonbr_io_read_impl_eof;  /* fake EOF to simulate shutdown */
    1.28 -  handle->readerr = 1;
    1.29    moonbr_io_handle_set_nonblocking(L, handle, nonblocking);
    1.30    if (!drain) luaL_buffinit(L, &luabuf);
    1.31    while (1) {
    1.32 -    endcnt = -1;
    1.33 -    if (maxread > 0 && handle->readbufcnt >= (size_t)maxread - luabufcnt) {
    1.34 -      endcnt = maxread - luabufcnt;
    1.35 +    remaining = -1;
    1.36 +    if (
    1.37 +      maxread > 0 &&
    1.38 +      handle->readbufin - handle->readbufout >= (size_t)maxread - luabufcnt
    1.39 +    ) {
    1.40 +      remaining = maxread - luabufcnt;
    1.41      } else if (terminatorlen) {
    1.42 -      terminatorpos = memchr(handle->readbuf, terminator, handle->readbufcnt);
    1.43 -      if (terminatorpos) endcnt = 1 + (terminatorpos - handle->readbuf);
    1.44 +      terminatorpos = memchr(
    1.45 +        handle->readbuf + handle->readbufout,
    1.46 +        terminator,
    1.47 +        handle->readbufin - handle->readbufout
    1.48 +      );
    1.49 +      if (terminatorpos) remaining = 1 + (
    1.50 +        terminatorpos - (handle->readbuf + handle->readbufout)
    1.51 +      );
    1.52      }
    1.53 -    if (endcnt >= 0) {
    1.54 +    if (remaining >= 0) {
    1.55        if (!drain) {
    1.56 -        luaL_addlstring(&luabuf, handle->readbuf, endcnt);
    1.57 +        luaL_addlstring(
    1.58 +          &luabuf,
    1.59 +          handle->readbuf + handle->readbufout,
    1.60 +          remaining
    1.61 +        );
    1.62          luaL_pushresult(&luabuf);
    1.63        } else {
    1.64 -        luabufcnt += handle->readbufcnt;
    1.65 -        lua_pushinteger(L, luabufcnt);
    1.66 +        luaL_pushresult(&luabuf);
    1.67 +        lua_pop(L, 1);
    1.68 +        lua_pushinteger(L, luabufcnt + remaining);
    1.69        }
    1.70 -      handle->readbufcnt -= endcnt;
    1.71 -      memmove(handle->readbuf, handle->readbuf + endcnt, handle->readbufcnt);
    1.72 +      handle->readbufout += remaining;
    1.73 +      if (handle->readbufout == handle->readbufin) {
    1.74 +        handle->readbufin = 0;
    1.75 +        handle->readbufout =0;
    1.76 +      }
    1.77        handle->readerr = 0;
    1.78        return 1;
    1.79      }
    1.80 -    if (!drain) luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt);
    1.81 -    luabufcnt += handle->readbufcnt;
    1.82 -    handle->readbufcnt = 0;
    1.83 +    if (!drain) luaL_addlstring(
    1.84 +      &luabuf,
    1.85 +      handle->readbuf + handle->readbufout,
    1.86 +      handle->readbufin - handle->readbufout
    1.87 +    );
    1.88 +    luabufcnt += handle->readbufin - handle->readbufout;
    1.89      do {
    1.90        bytesread = read(handle->fd, handle->readbuf, MOONBR_IO_READBUFLEN);
    1.91      } while (bytesread < 0 && (errno == EINTR));
    1.92 -    if (bytesread == 0 || (nonblocking && bytesread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))) break;
    1.93 +    if (
    1.94 +      bytesread == 0 || (
    1.95 +        nonblocking &&
    1.96 +        bytesread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)
    1.97 +      )
    1.98 +    ) {
    1.99 +      handle->readbufin = 0;
   1.100 +      handle->readbufout = 0;
   1.101 +      if (!drain) {
   1.102 +        luaL_pushresult(&luabuf);
   1.103 +        if (!luabufcnt && bytesread == 0) {
   1.104 +          lua_pop(L, 1);
   1.105 +          moonbr_io_read_impl_eof:
   1.106 +          lua_pushboolean(L, 0);
   1.107 +          lua_pushliteral(L, "End of file");
   1.108 +          handle->readerr = 0;
   1.109 +          return 2;
   1.110 +        }
   1.111 +      } else {
   1.112 +        if (!luabufcnt && bytesread == 0) lua_pushboolean(L, 1);
   1.113 +        else lua_pushboolean(L, luabufcnt);
   1.114 +      }
   1.115 +      handle->readerr = 0;
   1.116 +      return 1;
   1.117 +    }
   1.118      if (bytesread < 0) {
   1.119        moonbr_io_errmsg();
   1.120        lua_pushnil(L);
   1.121        lua_pushstring(L, errmsg);
   1.122        return 2;
   1.123      }
   1.124 -    handle->readbufcnt += bytesread;
   1.125 -  }
   1.126 -  if (!drain) {
   1.127 -    luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt);
   1.128 -    luaL_pushresult(&luabuf);
   1.129 +    handle->readbufin = bytesread;
   1.130 +    handle->readbufout = 0;
   1.131    }
   1.132 -  luabufcnt += handle->readbufcnt;
   1.133 -  handle->readbufcnt = 0;
   1.134 -  if (!drain) {
   1.135 -    if (!luabufcnt && bytesread == 0) {
   1.136 -      handle->readerr = 0;
   1.137 -      moonbr_io_read_impl_eof:
   1.138 -      lua_pushboolean(L, 0);
   1.139 -      lua_pushliteral(L, "End of file");
   1.140 -      return 2;
   1.141 -    }
   1.142 -  } else {
   1.143 -    if (!luabufcnt && bytesread == 0) lua_pushboolean(L, 1);
   1.144 -    else lua_pushboolean(L, luabufcnt);
   1.145 -  }
   1.146 -  handle->readerr = 0;
   1.147 -  return 1;
   1.148  }
   1.149  
   1.150  static int moonbr_io_read(lua_State *L) {
   1.151 @@ -454,7 +480,8 @@
   1.152    handle->nonblocking = -1;
   1.153    handle->nopush = -1;
   1.154    handle->readerr = 0;
   1.155 -  handle->readbufcnt = 0;
   1.156 +  handle->readbufin = 0;
   1.157 +  handle->readbufout = 0;
   1.158    handle->writeerr = 0;
   1.159    handle->writeleft = 0;
   1.160    handle->writeqin = 0;

Impressum / About Us