From bb4be12fda4d2d3fa634fa6b3eb93075fdc8169b Mon Sep 17 00:00:00 2001 From: Unbit Date: Fri, 13 Dec 2013 11:51:05 +0100 Subject: [PATCH] implemented more async api in lua --- core/io.c | 11 +++++ plugins/lua/lua_plugin.c | 34 +++++++++++++++ plugins/psgi/uwsgi_plmodule.c | 9 ++++ plugins/python/uwsgi_pymodule.c | 76 +++------------------------------ uwsgi.h | 2 + 5 files changed, 62 insertions(+), 70 deletions(-) diff --git a/core/io.c b/core/io.c index f5c98e07..4f2a061d 100644 --- a/core/io.c +++ b/core/io.c @@ -1216,3 +1216,14 @@ void uwsgi_remap_fd(int fd, char *filename) { } } +int uwsgi_is_connected(int fd) { + int soopt; + socklen_t solen = sizeof(int); + + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *) (&soopt), &solen) < 0) { + return 0; + } + /* is something bad ? */ + if (soopt) return 0; + return 1; +} diff --git a/plugins/lua/lua_plugin.c b/plugins/lua/lua_plugin.c index 7be839ab..c7445c19 100644 --- a/plugins/lua/lua_plugin.c +++ b/plugins/lua/lua_plugin.c @@ -341,7 +341,38 @@ end: return 1; } +static int uwsgi_api_is_connected(lua_State *L) { + uint8_t argc = lua_gettop(L); + if (argc == 0) goto end; + int fd = lua_tonumber(L, 1); + if (uwsgi_is_connected(fd)) { + lua_pushboolean(L, 1); + return 1; + } + lua_pushboolean(L, 0); + return 1; +end: + lua_pushnil(L); + return 1; +} +static int uwsgi_api_close(lua_State *L) { + uint8_t argc = lua_gettop(L); + if (argc == 0) goto end; + int fd = lua_tonumber(L, 1); + close(fd); +end: + lua_pushnil(L); + return 1; +} + + +static int uwsgi_api_ready_fd(lua_State *L) { + struct wsgi_request *wsgi_req = current_wsgi_req(); + int fd = uwsgi_ready_fd(wsgi_req); + lua_pushnumber(L, fd); + return 1; +} static int uwsgi_api_websocket_handshake(lua_State *L) { uint8_t argc = lua_gettop(L); @@ -592,8 +623,11 @@ static const luaL_Reg uwsgi_api[] = { {"async_sleep", uwsgi_api_async_sleep}, {"async_connect", uwsgi_api_async_connect}, + {"is_connected", uwsgi_api_is_connected}, + {"close", uwsgi_api_close}, {"wait_fd_read", uwsgi_api_wait_fd_read}, {"wait_fd_write", uwsgi_api_wait_fd_write}, + {"ready_fd", uwsgi_api_ready_fd}, {NULL, NULL} }; diff --git a/plugins/psgi/uwsgi_plmodule.c b/plugins/psgi/uwsgi_plmodule.c index a28c3222..d7e65890 100644 --- a/plugins/psgi/uwsgi_plmodule.c +++ b/plugins/psgi/uwsgi_plmodule.c @@ -321,6 +321,14 @@ XS(XS_async_connect) { XSRETURN(1); } +XS(XS_ready_fd) { + dXSARGS; + psgi_check_args(0); + struct wsgi_request *wsgi_req = current_wsgi_req(); + ST(0) = newSViv(uwsgi_ready_fd(wsgi_req)); + XSRETURN(1); +} + XS(XS_call) { dXSARGS; @@ -888,6 +896,7 @@ void init_perl_embedded_module() { psgi_xs(wait_fd_read); psgi_xs(wait_fd_write); psgi_xs(async_sleep); + psgi_xs(ready_fd); psgi_xs(log); psgi_xs(async_connect); psgi_xs(suspend); diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index acf3f8c7..55fdc336 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -187,7 +187,6 @@ static PyObject *py_uwsgi_close(PyObject * self, PyObject * args) { close(fd); - Py_INCREF(Py_None); return Py_None; @@ -604,59 +603,6 @@ PyObject *py_uwsgi_set_logvar(PyObject * self, PyObject * args) { return Py_None; } -PyObject *py_uwsgi_recv_block(PyObject * self, PyObject * args) { - - char buf[4096]; - char *bufptr; - ssize_t rlen = 0, len; - int fd, size, remains, ret, timeout = -1; - - - if (!PyArg_ParseTuple(args, "ii|i:recv_block", &fd, &size, &timeout)) { - return NULL; - } - - if (fd < 0) - goto clear; - - UWSGI_RELEASE_GIL - // security check - if (size > 4096) - size = 4096; - - remains = size; - - bufptr = buf; - while (remains > 0) { - uwsgi_log("%d %d %d\n", remains, size, timeout); - ret = uwsgi_waitfd(fd, timeout); - if (ret > 0) { - len = read(fd, bufptr, UMIN(remains, size)); - if (len > 0) { - bufptr += len; - rlen += len; - remains -= len; - } - else { - break; - } - } - else { - uwsgi_log("error waiting for block data\n"); - break; - } - } - - UWSGI_GET_GIL if (rlen == size) { - return PyString_FromStringAndSize(buf, rlen); - } - - clear: - - Py_INCREF(Py_None); - return Py_None; -} - PyObject *py_uwsgi_recv(PyObject * self, PyObject * args) { int fd, max_size = 4096; @@ -685,28 +631,19 @@ PyObject *py_uwsgi_recv(PyObject * self, PyObject * args) { PyObject *py_uwsgi_is_connected(PyObject * self, PyObject * args) { - int fd, soopt; - socklen_t solen = sizeof(int); + int fd = -1; if (!PyArg_ParseTuple(args, "i:is_connected", &fd)) { return NULL; } - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *) (&soopt), &solen) < 0) { - uwsgi_error("getsockopt()"); - goto clear; + if (uwsgi_is_connected(fd)) { + Py_INCREF(Py_True); + return Py_True; } - /* is something bad ? */ - if (soopt) - goto clear; - Py_INCREF(Py_True); - return Py_True; - - clear: - - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(Py_False); + return Py_False; } @@ -2562,7 +2499,6 @@ static PyMethodDef uwsgi_advanced_methods[] = { {"is_connected", py_uwsgi_is_connected, METH_VARARGS, ""}, {"send", py_uwsgi_send, METH_VARARGS, ""}, {"recv", py_uwsgi_recv, METH_VARARGS, ""}, - {"recv_block", py_uwsgi_recv_block, METH_VARARGS, ""}, {"close", py_uwsgi_close, METH_VARARGS, ""}, {"i_am_the_spooler", py_uwsgi_i_am_the_spooler, METH_VARARGS, ""}, diff --git a/uwsgi.h b/uwsgi.h index c2146324..ecda9187 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -4622,6 +4622,8 @@ void uwsgi_register_logchunks(void); void uwsgi_setup(int, char **, char **); int uwsgi_run(void); +int uwsgi_is_connected(int); + #ifdef __cplusplus } #endif