# HG changeset patch # User jbe # Date 1430576733 -7200 # Node ID bd88dfa4f294e27f8cc9871bfd4646f54b6e9402 # Parent e7fac0918f9c95b5613498ded77e1259085ee1ce Yielding write and flush methods for I/O diff -r e7fac0918f9c -r bd88dfa4f294 moonbridge_io.c --- a/moonbridge_io.c Sat May 02 14:31:55 2015 +0200 +++ b/moonbridge_io.c Sat May 02 16:25:33 2015 +0200 @@ -83,6 +83,18 @@ return lua_gettop(L); } +#define moonbr_io_yield_wrapper(yieldfunc, callfunc) \ + static int yieldfunc(lua_State *L) { \ + int args; \ + lua_pushcfunction(L, callfunc); \ + lua_insert(L, 1); \ + args = lua_gettop(L); \ + lua_pushcfunction(L, moonbr_io_yield); \ + lua_insert(L, 3); \ + lua_callk(L, args, LUA_MULTRET, 0, moonbr_io_cont_returnall); \ + return lua_gettop(L); \ + } + static void moonbr_io_handle_set_nonblocking(lua_State *L, moonbr_io_handle_t *handle, int nonblocking) { int flags; if (handle->nonblocking == nonblocking) return; @@ -351,16 +363,7 @@ #endif } -static int moonbr_io_read_yield(lua_State *L) { - int args; - lua_pushcfunction(L, moonbr_io_read_call); - lua_insert(L, 1); - args = lua_gettop(L); - lua_pushcfunction(L, moonbr_io_yield); - lua_insert(L, 3); - lua_callk(L, args, LUA_MULTRET, 0, moonbr_io_cont_returnall); - return lua_gettop(L); -} +moonbr_io_yield_wrapper(moonbr_io_read_yield, moonbr_io_read_call); #if LUA_VERSION_NUM >= 503 static int moonbr_io_drain_cont(lua_State *L, int status, lua_KContext ctx) { @@ -410,16 +413,7 @@ #endif } -static int moonbr_io_drain_yield(lua_State *L) { - int args; - lua_pushcfunction(L, moonbr_io_drain_call); - lua_insert(L, 1); - args = lua_gettop(L); - lua_pushcfunction(L, moonbr_io_yield); - lua_insert(L, 3); - lua_callk(L, args, LUA_MULTRET, 0, moonbr_io_cont_returnall); - return lua_gettop(L); -} +moonbr_io_yield_wrapper(moonbr_io_drain_yield, moonbr_io_drain_call); static int moonbr_io_write_impl(lua_State *L, int nonblocking, int flush) { moonbr_io_handle_t *handle; @@ -566,6 +560,68 @@ return moonbr_io_write_impl(L, 1, 1); } +#if LUA_VERSION_NUM >= 503 +static int moonbr_io_write_cont(lua_State *L, int status, lua_KContext ctx) { +#else +static int moonbr_io_write_cont(lua_State *L) { +#endif + while (1) { + lua_pushcfunction(L, moonbr_io_write_nb); + lua_pushvalue(L, 1); + lua_call(L, 1, 2); + if (lua_isnil(L, -2)) return 2; + if (!lua_tointeger(L, -2)) { + lua_pushvalue(L, 1); + return 1; + } + lua_pop(L, 2); + lua_pushvalue(L, 2); + lua_pushvalue(L, 1); + lua_pushliteral(L, "w"); + lua_callk(L, 2, 0, 0, moonbr_io_write_cont); + } +} + +static int moonbr_io_write_call(lua_State *L) { + lua_pushcfunction(L, moonbr_io_write_nb); + lua_insert(L, 3); + lua_pushvalue(L, 1); + lua_insert(L, 4); + lua_call(L, lua_gettop(L) - 3, 2); + if (lua_isnil(L, -2)) return 2; + if (!lua_tointeger(L, -2)) { + lua_pushvalue(L, 1); + return 1; + } +#if LUA_VERSION_NUM >= 503 + return moonbr_io_write_cont(L, 0, 0); +#else + return moonbr_io_write_cont(L); +#endif +} + +moonbr_io_yield_wrapper(moonbr_io_write_yield, moonbr_io_write_call); + +static int moonbr_io_flush_call(lua_State *L) { + lua_pushcfunction(L, moonbr_io_flush_nb); + lua_insert(L, 3); + lua_pushvalue(L, 1); + lua_insert(L, 4); + lua_call(L, lua_gettop(L) - 3, 2); + if (lua_isnil(L, -2)) return 2; + if (!lua_tointeger(L, -2)) { + lua_pushvalue(L, 1); + return 1; + } +#if LUA_VERSION_NUM >= 503 + return moonbr_io_write_cont(L, 0, 0); +#else + return moonbr_io_write_cont(L); +#endif +} + +moonbr_io_yield_wrapper(moonbr_io_flush_yield, moonbr_io_flush_call); + static int moonbr_io_finish(lua_State *L) { moonbr_io_handle_t *handle; handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); @@ -1280,8 +1336,12 @@ {"drain_yield", moonbr_io_drain_yield}, {"write", moonbr_io_write}, {"write_nb", moonbr_io_write_nb}, + {"write_call", moonbr_io_write_call}, + {"write_yield", moonbr_io_write_yield}, {"flush", moonbr_io_flush}, {"flush_nb", moonbr_io_flush_nb}, + {"flush_call", moonbr_io_flush_call}, + {"flush_yield", moonbr_io_flush_yield}, {"finish", moonbr_io_finish}, {"close", moonbr_io_close}, {"reset", moonbr_io_reset}, diff -r e7fac0918f9c -r bd88dfa4f294 reference.txt --- a/reference.txt Sat May 02 14:31:55 2015 +0200 +++ b/reference.txt Sat May 02 16:25:33 2015 +0200 @@ -119,6 +119,12 @@ returned. +### socket:flush_call(waitfunc, ...) + +Same as socket:flush(...), but calls waitfunc(socket, "w") (in an infinite +loop) as long as the writing is blocked. + + ### socket:flush_nb(...) Same as socket:write_nb(...) but additionally flushes the socket (i.e. all @@ -130,6 +136,11 @@ second return value) are returned. +### socket:flush_yield(...) + +Alias for socket:flush_call(coroutine.yield, ...) + + ### socket.interval Set to the name of an interval timer if the "connect" handler was called due to @@ -242,6 +253,12 @@ returned. +### socket:write_call(waitfunc, ...) + +Same as socket:write(...), but calls waitfunc(socket, "w") (in an infinite +loop) as long as the writing is blocked. + + ### socket:write_nb(...) Takes a variable number of strings and sends them to the peer. The operation is @@ -258,6 +275,11 @@ second return value) are returned. +### socket:write_yield(...) + +Alias for socket:write_call(coroutine.yield, ...) + + I/O library -----------