moonbridge

changeset 103:4f9e4c6109f4

Different buffering model for I/O writer
author jbe
date Wed Apr 08 17:43:31 2015 +0200 (2015-04-08)
parents 51ff6ad11677
children 5e8eeb5b6c84
files moonbridge_io.c
line diff
     1.1 --- a/moonbridge_io.c	Wed Apr 08 05:26:15 2015 +0200
     1.2 +++ b/moonbridge_io.c	Wed Apr 08 17:43:31 2015 +0200
     1.3 @@ -46,7 +46,8 @@
     1.4    int writeqout;
     1.5  #endif
     1.6    size_t writeqoff;
     1.7 -  int writebufcnt;
     1.8 +  int writebufin;
     1.9 +  int writebufout;
    1.10    char readbuf[MOONBR_IO_READBUFLEN];
    1.11    char writebuf[MOONBR_IO_WRITEBUFLEN];
    1.12  } moonbr_io_handle_t;
    1.13 @@ -126,7 +127,7 @@
    1.14    size_t luabufcnt = 0;
    1.15    int endcnt;
    1.16    char *terminatorpos;
    1.17 -  ssize_t result;
    1.18 +  ssize_t bytesread;
    1.19    handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY);
    1.20    maxread = luaL_optinteger(L, 2, 0);
    1.21    terminatorstr = luaL_optlstring(L, 3, "", &terminatorlen);
    1.22 @@ -168,17 +169,17 @@
    1.23      luabufcnt += handle->readbufcnt;
    1.24      handle->readbufcnt = 0;
    1.25      do {
    1.26 -      result = read(handle->fd, handle->readbuf, MOONBR_IO_READBUFLEN);
    1.27 -    } while (result < 0 && (errno == EINTR));
    1.28 -    if (result == 0 || (nonblocking && result < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))) break;
    1.29 -    if (result < 0) {
    1.30 +      bytesread = read(handle->fd, handle->readbuf, MOONBR_IO_READBUFLEN);
    1.31 +    } while (bytesread < 0 && (errno == EINTR));
    1.32 +    if (bytesread == 0 || (nonblocking && bytesread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))) break;
    1.33 +    if (bytesread < 0) {
    1.34        moonbr_io_errmsg();
    1.35        handle->readerr = 1;
    1.36        lua_pushnil(L);
    1.37        lua_pushstring(L, errmsg);
    1.38        return 2;
    1.39      }
    1.40 -    handle->readbufcnt += result;
    1.41 +    handle->readbufcnt += bytesread;
    1.42    }
    1.43    if (!drain) {
    1.44      luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt);
    1.45 @@ -187,14 +188,14 @@
    1.46    luabufcnt += handle->readbufcnt;
    1.47    handle->readbufcnt = 0;
    1.48    if (!drain) {
    1.49 -    if (!luabufcnt && result == 0) {
    1.50 +    if (!luabufcnt && bytesread == 0) {
    1.51        moonbr_io_read_impl_eof:
    1.52        lua_pushboolean(L, 0);
    1.53        lua_pushliteral(L, "End of file");
    1.54        return 2;
    1.55      }
    1.56    } else {
    1.57 -    if (!luabufcnt && result == 0) lua_pushboolean(L, 1);
    1.58 +    if (!luabufcnt && bytesread == 0) lua_pushboolean(L, 1);
    1.59      else lua_pushboolean(L, luabufcnt);
    1.60    }
    1.61    return 1;
    1.62 @@ -221,8 +222,7 @@
    1.63    int i, top;
    1.64    const char *str;
    1.65    size_t strlen;
    1.66 -  size_t written;
    1.67 -  ssize_t result;
    1.68 +  ssize_t written;
    1.69    handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY);
    1.70    if (handle->closed) luaL_error(L, "Attempt to write to a closed I/O handle");
    1.71    if (handle->finished) luaL_error(L, "Attempt to write to a finished I/O handle");
    1.72 @@ -231,10 +231,11 @@
    1.73      lua_pushliteral(L, "Previous write error");
    1.74      return 2;
    1.75    }
    1.76 +  handle->writeerr = 1;
    1.77    moonbr_io_handle_set_nonblocking(L, handle, nonblocking);
    1.78    top = lua_gettop(L);
    1.79    lua_getuservalue(L, 1);
    1.80 -  lua_getfield(L, -1, "writebuf");
    1.81 +  lua_getfield(L, -1, "writequeue");
    1.82    for (i=2; i<=top; i++) {
    1.83      luaL_checklstring(L, i, &strlen);
    1.84      lua_pushvalue(L, i);
    1.85 @@ -245,39 +246,48 @@
    1.86      lua_rawgeti(L, -1, handle->writeqout);
    1.87      str = lua_tolstring(L, -1, &strlen);
    1.88      while (handle->writeqoff < strlen) {
    1.89 -      if (strlen - handle->writeqoff <= MOONBR_IO_WRITEBUFLEN - handle->writebufcnt) {
    1.90 -        memcpy(handle->writebuf + handle->writebufcnt, str + handle->writeqoff, strlen - handle->writeqoff);
    1.91 -        handle->writebufcnt += strlen - handle->writeqoff;
    1.92 +      if (
    1.93 +        strlen - handle->writeqoff <=
    1.94 +        MOONBR_IO_WRITEBUFLEN - handle->writebufin
    1.95 +      ) {
    1.96 +        memcpy(
    1.97 +          handle->writebuf + handle->writebufin,
    1.98 +          str + handle->writeqoff,
    1.99 +          strlen - handle->writeqoff
   1.100 +        );
   1.101 +        handle->writebufin += strlen - handle->writeqoff;
   1.102          break;
   1.103        } else {
   1.104          moonbr_io_handle_set_nopush(L, handle, 1);
   1.105 -        written = 0;
   1.106 -        memcpy(handle->writebuf + handle->writebufcnt, str + handle->writeqoff, MOONBR_IO_WRITEBUFLEN - handle->writebufcnt);
   1.107 -        handle->writeqoff += MOONBR_IO_WRITEBUFLEN - handle->writebufcnt;
   1.108 -        while (written < MOONBR_IO_WRITEBUFLEN) {
   1.109 -          result = write(handle->fd, handle->writebuf + written, MOONBR_IO_WRITEBUFLEN - written);
   1.110 -          if (result < 0) {
   1.111 +        memcpy(
   1.112 +          handle->writebuf + handle->writebufin,
   1.113 +          str + handle->writeqoff,
   1.114 +          MOONBR_IO_WRITEBUFLEN - handle->writebufin
   1.115 +        );
   1.116 +        handle->writeqoff += MOONBR_IO_WRITEBUFLEN - handle->writebufin;
   1.117 +        while (handle->writebufout < MOONBR_IO_WRITEBUFLEN) {
   1.118 +          written = write(
   1.119 +            handle->fd,
   1.120 +            handle->writebuf + handle->writebufout,
   1.121 +            MOONBR_IO_WRITEBUFLEN - handle->writebufout
   1.122 +          );
   1.123 +          if (written < 0) {
   1.124              if (nonblocking && (errno == EAGAIN || errno == EWOULDBLOCK)) {
   1.125 -              if (written) {
   1.126 -                handle->writebufcnt -= written;
   1.127 -                memmove(handle->writebuf, handle->writebuf + written, handle->writebufcnt);
   1.128 -                goto moonbr_io_write_impl_continue;
   1.129 -              }
   1.130                goto moonbr_io_write_impl_block;
   1.131              } else if (errno != EINTR) {
   1.132                moonbr_io_errmsg();
   1.133 -              handle->writeerr = 1;
   1.134                lua_pushnil(L);
   1.135                lua_pushstring(L, errmsg);
   1.136                return 2;
   1.137              }
   1.138 +          } else {
   1.139 +            handle->writebufout += written;
   1.140 +            handle->writeleft -= written;
   1.141            }
   1.142 -          written += result;
   1.143 -          handle->writeleft -= result;
   1.144          }
   1.145 -        handle->writebufcnt = 0;
   1.146 +        handle->writebufin = 0;
   1.147 +        handle->writebufout = 0;
   1.148        }
   1.149 -      moonbr_io_write_impl_continue:;
   1.150      }
   1.151      handle->writeqoff = 0;
   1.152      lua_pop(L, 1);
   1.153 @@ -286,37 +296,36 @@
   1.154    }
   1.155    if (flush) {
   1.156      moonbr_io_handle_set_nopush(L, handle, 0);
   1.157 -    written = 0;
   1.158 -    while (written < handle->writebufcnt) {
   1.159 -      result = write(handle->fd, handle->writebuf + written, handle->writebufcnt - written);
   1.160 -      if (result < 0) {
   1.161 +    while (handle->writebufout < handle->writebufin) {
   1.162 +      written = write(
   1.163 +        handle->fd,
   1.164 +        handle->writebuf + handle->writebufout,
   1.165 +        handle->writebufin - handle->writebufout
   1.166 +      );
   1.167 +      if (written < 0) {
   1.168          if (nonblocking && (errno == EAGAIN || errno == EWOULDBLOCK)) {
   1.169 -          if (written) {
   1.170 -            handle->writebufcnt -= written;
   1.171 -            memmove(handle->writebuf, handle->writebuf + written, handle->writebufcnt);
   1.172 -          }
   1.173            goto moonbr_io_write_impl_block;
   1.174          } else if (errno != EINTR) {
   1.175            moonbr_io_errmsg();
   1.176 -          handle->writeerr = -1;
   1.177            lua_pushnil(L);
   1.178            lua_pushstring(L, errmsg);
   1.179            return 2;
   1.180          }
   1.181        } else {
   1.182 -        written += result;
   1.183 -        handle->writeleft -= result;
   1.184 +        handle->writebufout += written;
   1.185 +        handle->writeleft -= written;
   1.186        }
   1.187      }
   1.188 -    handle->writebufcnt = 0;
   1.189 -    if (nonblocking) lua_pushinteger(L, 0);
   1.190 -  } else {
   1.191 -    if (nonblocking) lua_pushinteger(L, handle->writeleft);
   1.192 +    handle->writebufin = 0;
   1.193 +    handle->writebufout = 0;
   1.194    }
   1.195 -  if (!nonblocking) lua_pushvalue(L, 1);
   1.196 +  if (nonblocking) lua_pushinteger(L, 0);
   1.197 +  else lua_pushvalue(L, 1);
   1.198 +  handle->writeerr = 0;
   1.199    return 1;
   1.200    moonbr_io_write_impl_block:
   1.201    lua_pushinteger(L, handle->writeleft);
   1.202 +  handle->writeerr = 0;
   1.203    return 1;
   1.204  }
   1.205  
   1.206 @@ -450,13 +459,14 @@
   1.207    handle->writeqin = 0;
   1.208    handle->writeqout = 0;
   1.209    handle->writeqoff = 0;
   1.210 -  handle->writebufcnt = 0;
   1.211 +  handle->writebufin = 0;
   1.212 +  handle->writebufout = 0;
   1.213    moonbr_io_handle_set_linger(L, handle, 0);
   1.214    luaL_getmetatable(L, MOONBR_IO_HANDLE_MT_REGKEY);
   1.215    lua_setmetatable(L, -2);
   1.216    lua_newtable(L);  // uservalue
   1.217    lua_newtable(L);
   1.218 -  lua_setfield(L, -2, "writebuf");
   1.219 +  lua_setfield(L, -2, "writequeue");
   1.220    lua_newtable(L);  // public
   1.221    luaL_getmetatable(L, MOONBR_IO_HANDLE_PUBLIC_MT_REGKEY);
   1.222    lua_setmetatable(L, -2);

Impressum / About Us