# HG changeset patch # User jbe # Date 1474327888 -7200 # Node ID 6c634c96805bd1a171c92105ab86249fc6030da5 # Parent 1dc7293438303daaef6be510afebc9acc9520b8c Work on non-blocking close (for TLS) diff -r 1dc729343830 -r 6c634c96805b moonbridge_io.c --- a/moonbridge_io.c Mon Sep 19 01:12:38 2016 +0200 +++ b/moonbridge_io.c Tue Sep 20 01:31:28 2016 +0200 @@ -102,6 +102,7 @@ struct tls *tls; struct tls *servertls; int tlshandshake; + int tlsclosing; #endif } moonbr_io_handle_t; @@ -754,13 +755,13 @@ return 1; } -static int moonbr_io_close_impl(lua_State *L, int reset) { +static int moonbr_io_close_impl(lua_State *L, int nonblocking, int reset) { moonbr_io_handle_t *handle; handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); if (handle->closed) luaL_error(L, "Attempt to close a closed I/O handle"); if (!reset && handle->fd >= 0) { if (handle->writeleft) { - lua_pushcfunction(L, moonbr_io_flush); + lua_pushcfunction(L, nonblocking ? moonbr_io_flush_nb : moonbr_io_flush); lua_pushvalue(L, 1); if (lua_pcall(L, 1, 2, 0)) { handle->closed = 1; @@ -768,21 +769,35 @@ handle->fd = -1; lua_error(L); } - handle->closed = 1; + if (!nonblocking) handle->closed = 1; /* TODO: handle nonblocking case */ if (!lua_toboolean(L, -2)) { close(handle->fd); handle->fd = -1; return 2; } +#if LUA_VERSION_NUM >= 503 + if (nonblocking && lua_tointeger(L, -2)) { +#else + if (nonblocking && lua_tonumber(L, -2)) { +#endif + lua_pushliteral(L, "flush"); + lua_pushvalue(L, -3); + return 2; + } } else { handle->closed = 1; } #ifdef MOONBR_IO_USE_TLS if (handle->tls) { int status; - if (moonbr_io_handle_set_nonblocking(L, handle, 1)) moonbr_io_return_errmsg(); + if (moonbr_io_handle_set_nonblocking(L, handle, nonblocking)) moonbr_io_return_errmsg(); do status = tls_close(handle->tls); - while (status == TLS_WANT_POLLIN || status == TLS_WANT_POLLOUT); + while (!nonblocking && (status == TLS_WANT_POLLIN || status == TLS_WANT_POLLOUT)); + if (status == TLS_WANT_POLLIN || status == TLS_WANT_POLLOUT) { + handle->tlsclosing = status; /* TODO: handle polling */ + lua_pushliteral(L, "close"); + return 1; + } if (status) { close(handle->fd); handle->fd = -1; @@ -814,11 +829,11 @@ } static int moonbr_io_close(lua_State *L) { - return moonbr_io_close_impl(L, 0); + return moonbr_io_close_impl(L, 0, 0); } static int moonbr_io_reset(lua_State *L) { - return moonbr_io_close_impl(L, 1); + return moonbr_io_close_impl(L, 0, 1); } static int moonbr_io_handlegc(lua_State *L) { @@ -891,6 +906,7 @@ handle->tls = NULL; handle->servertls = NULL; handle->tlshandshake = 0; + handle->tlsclosing = 0; #endif handle->fd = *fd; /* required for set_linger call */ if (moonbr_io_handle_set_linger(L, handle, 0)) {