moonbridge

changeset 145:bd88dfa4f294

Yielding write and flush methods for I/O
author jbe
date Sat May 02 16:25:33 2015 +0200 (2015-05-02)
parents e7fac0918f9c
children 6dfe5b424b18
files moonbridge_io.c reference.txt
line diff
     1.1 --- a/moonbridge_io.c	Sat May 02 14:31:55 2015 +0200
     1.2 +++ b/moonbridge_io.c	Sat May 02 16:25:33 2015 +0200
     1.3 @@ -83,6 +83,18 @@
     1.4    return lua_gettop(L);
     1.5  }
     1.6  
     1.7 +#define moonbr_io_yield_wrapper(yieldfunc, callfunc) \
     1.8 +  static int yieldfunc(lua_State *L) { \
     1.9 +    int args; \
    1.10 +    lua_pushcfunction(L, callfunc); \
    1.11 +    lua_insert(L, 1); \
    1.12 +    args = lua_gettop(L); \
    1.13 +    lua_pushcfunction(L, moonbr_io_yield); \
    1.14 +    lua_insert(L, 3); \
    1.15 +    lua_callk(L, args, LUA_MULTRET, 0, moonbr_io_cont_returnall); \
    1.16 +    return lua_gettop(L); \
    1.17 +  }
    1.18 +
    1.19  static void moonbr_io_handle_set_nonblocking(lua_State *L, moonbr_io_handle_t *handle, int nonblocking) {
    1.20    int flags;
    1.21    if (handle->nonblocking == nonblocking) return;
    1.22 @@ -351,16 +363,7 @@
    1.23  #endif
    1.24  }
    1.25  
    1.26 -static int moonbr_io_read_yield(lua_State *L) {
    1.27 -  int args;
    1.28 -  lua_pushcfunction(L, moonbr_io_read_call);
    1.29 -  lua_insert(L, 1);
    1.30 -  args = lua_gettop(L);
    1.31 -  lua_pushcfunction(L, moonbr_io_yield);
    1.32 -  lua_insert(L, 3);
    1.33 -  lua_callk(L, args, LUA_MULTRET, 0, moonbr_io_cont_returnall);
    1.34 -  return lua_gettop(L);
    1.35 -}
    1.36 +moonbr_io_yield_wrapper(moonbr_io_read_yield, moonbr_io_read_call);
    1.37  
    1.38  #if LUA_VERSION_NUM >= 503
    1.39  static int moonbr_io_drain_cont(lua_State *L, int status, lua_KContext ctx) {
    1.40 @@ -410,16 +413,7 @@
    1.41  #endif
    1.42  }
    1.43  
    1.44 -static int moonbr_io_drain_yield(lua_State *L) {
    1.45 -  int args;
    1.46 -  lua_pushcfunction(L, moonbr_io_drain_call);
    1.47 -  lua_insert(L, 1);
    1.48 -  args = lua_gettop(L);
    1.49 -  lua_pushcfunction(L, moonbr_io_yield);
    1.50 -  lua_insert(L, 3);
    1.51 -  lua_callk(L, args, LUA_MULTRET, 0, moonbr_io_cont_returnall);
    1.52 -  return lua_gettop(L);
    1.53 -}
    1.54 +moonbr_io_yield_wrapper(moonbr_io_drain_yield, moonbr_io_drain_call);
    1.55  
    1.56  static int moonbr_io_write_impl(lua_State *L, int nonblocking, int flush) {
    1.57    moonbr_io_handle_t *handle;
    1.58 @@ -566,6 +560,68 @@
    1.59    return moonbr_io_write_impl(L, 1, 1);
    1.60  }
    1.61  
    1.62 +#if LUA_VERSION_NUM >= 503
    1.63 +static int moonbr_io_write_cont(lua_State *L, int status, lua_KContext ctx) {
    1.64 +#else
    1.65 +static int moonbr_io_write_cont(lua_State *L) {
    1.66 +#endif
    1.67 +  while (1) {
    1.68 +    lua_pushcfunction(L, moonbr_io_write_nb);
    1.69 +    lua_pushvalue(L, 1);
    1.70 +    lua_call(L, 1, 2);
    1.71 +    if (lua_isnil(L, -2)) return 2;
    1.72 +    if (!lua_tointeger(L, -2)) {
    1.73 +      lua_pushvalue(L, 1);
    1.74 +      return 1;
    1.75 +    }
    1.76 +    lua_pop(L, 2);
    1.77 +    lua_pushvalue(L, 2);
    1.78 +    lua_pushvalue(L, 1);
    1.79 +    lua_pushliteral(L, "w");
    1.80 +    lua_callk(L, 2, 0, 0, moonbr_io_write_cont);
    1.81 +  }
    1.82 +}
    1.83 +
    1.84 +static int moonbr_io_write_call(lua_State *L) {
    1.85 +  lua_pushcfunction(L, moonbr_io_write_nb);
    1.86 +  lua_insert(L, 3);
    1.87 +  lua_pushvalue(L, 1);
    1.88 +  lua_insert(L, 4);
    1.89 +  lua_call(L, lua_gettop(L) - 3, 2);
    1.90 +  if (lua_isnil(L, -2)) return 2;
    1.91 +  if (!lua_tointeger(L, -2)) {
    1.92 +    lua_pushvalue(L, 1);
    1.93 +    return 1;
    1.94 +  }
    1.95 +#if LUA_VERSION_NUM >= 503
    1.96 +  return moonbr_io_write_cont(L, 0, 0);
    1.97 +#else
    1.98 +  return moonbr_io_write_cont(L);
    1.99 +#endif
   1.100 +}
   1.101 +
   1.102 +moonbr_io_yield_wrapper(moonbr_io_write_yield, moonbr_io_write_call);
   1.103 +
   1.104 +static int moonbr_io_flush_call(lua_State *L) {
   1.105 +  lua_pushcfunction(L, moonbr_io_flush_nb);
   1.106 +  lua_insert(L, 3);
   1.107 +  lua_pushvalue(L, 1);
   1.108 +  lua_insert(L, 4);
   1.109 +  lua_call(L, lua_gettop(L) - 3, 2);
   1.110 +  if (lua_isnil(L, -2)) return 2;
   1.111 +  if (!lua_tointeger(L, -2)) {
   1.112 +    lua_pushvalue(L, 1);
   1.113 +    return 1;
   1.114 +  }
   1.115 +#if LUA_VERSION_NUM >= 503
   1.116 +  return moonbr_io_write_cont(L, 0, 0);
   1.117 +#else
   1.118 +  return moonbr_io_write_cont(L);
   1.119 +#endif
   1.120 +}
   1.121 +
   1.122 +moonbr_io_yield_wrapper(moonbr_io_flush_yield, moonbr_io_flush_call);
   1.123 +
   1.124  static int moonbr_io_finish(lua_State *L) {
   1.125    moonbr_io_handle_t *handle;
   1.126    handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY);
   1.127 @@ -1280,8 +1336,12 @@
   1.128    {"drain_yield", moonbr_io_drain_yield},
   1.129    {"write", moonbr_io_write},
   1.130    {"write_nb", moonbr_io_write_nb},
   1.131 +  {"write_call", moonbr_io_write_call},
   1.132 +  {"write_yield", moonbr_io_write_yield},
   1.133    {"flush", moonbr_io_flush},
   1.134    {"flush_nb", moonbr_io_flush_nb},
   1.135 +  {"flush_call", moonbr_io_flush_call},
   1.136 +  {"flush_yield", moonbr_io_flush_yield},
   1.137    {"finish", moonbr_io_finish},
   1.138    {"close", moonbr_io_close},
   1.139    {"reset", moonbr_io_reset},
     2.1 --- a/reference.txt	Sat May 02 14:31:55 2015 +0200
     2.2 +++ b/reference.txt	Sat May 02 16:25:33 2015 +0200
     2.3 @@ -119,6 +119,12 @@
     2.4  returned.
     2.5  
     2.6  
     2.7 +### socket:flush_call(waitfunc, ...)
     2.8 +
     2.9 +Same as socket:flush(...), but calls waitfunc(socket, "w") (in an infinite
    2.10 +loop) as long as the writing is blocked.
    2.11 +
    2.12 +
    2.13  ### socket:flush_nb(...)
    2.14  
    2.15  Same as socket:write_nb(...) but additionally flushes the socket (i.e. all
    2.16 @@ -130,6 +136,11 @@
    2.17  second return value) are returned.
    2.18  
    2.19  
    2.20 +### socket:flush_yield(...)
    2.21 +
    2.22 +Alias for socket:flush_call(coroutine.yield, ...)
    2.23 +
    2.24 +
    2.25  ### socket.interval
    2.26  
    2.27  Set to the name of an interval timer if the "connect" handler was called due to
    2.28 @@ -242,6 +253,12 @@
    2.29  returned.
    2.30  
    2.31  
    2.32 +### socket:write_call(waitfunc, ...)
    2.33 +
    2.34 +Same as socket:write(...), but calls waitfunc(socket, "w") (in an infinite
    2.35 +loop) as long as the writing is blocked.
    2.36 +
    2.37 +
    2.38  ### socket:write_nb(...)
    2.39  
    2.40  Takes a variable number of strings and sends them to the peer. The operation is
    2.41 @@ -258,6 +275,11 @@
    2.42  second return value) are returned.
    2.43  
    2.44  
    2.45 +### socket:write_yield(...)
    2.46 +
    2.47 +Alias for socket:write_call(coroutine.yield, ...)
    2.48 +
    2.49 +
    2.50  
    2.51  I/O library
    2.52  -----------

Impressum / About Us