From 60580a01955d314b8ebf99b55a7cf56fefaa6a0b Mon Sep 17 00:00:00 2001 From: Unbit Date: Mon, 4 Feb 2013 08:55:19 +0100 Subject: [PATCH] prepare for ruby websockets + fibers support --- core/async.c | 23 ++++++++++++++--------- plugins/fiber/fiber.c | 2 +- plugins/greenlet/greenlet.c | 2 +- plugins/psgi/uwsgi_plmodule.c | 12 +++++------- plugins/python/wsgi_handlers.c | 8 ++++---- plugins/rack/rack_api.c | 8 ++++---- uwsgi.h | 4 ++-- 7 files changed, 31 insertions(+), 28 deletions(-) diff --git a/core/async.c b/core/async.c index 0a5fe374..cb134575 100644 --- a/core/async.c +++ b/core/async.c @@ -138,12 +138,12 @@ void async_expire_timeouts() { } -void async_add_fd_read(struct wsgi_request *wsgi_req, int fd, int timeout) { +int async_add_fd_read(struct wsgi_request *wsgi_req, int fd, int timeout) { struct uwsgi_async_fd *last_uad = NULL, *uad = wsgi_req->waiting_fds; if (fd < 0) - return; + return -1; // find first slot while (uad) { @@ -168,12 +168,15 @@ void async_add_fd_read(struct wsgi_request *wsgi_req, int fd, int timeout) { async_add_timeout(wsgi_req, timeout); } uwsgi.async_waiting_fd_table[fd] = wsgi_req; - event_queue_add_fd_read(uwsgi.async_queue, fd); + wsgi_req->async_force_again = 1; + return event_queue_add_fd_read(uwsgi.async_queue, fd); } static int async_wait_fd_read(int fd, int timeout) { struct wsgi_request *wsgi_req = current_wsgi_req(); - async_add_fd_read(wsgi_req, fd, timeout); + if (async_add_fd_read(wsgi_req, fd, timeout)) { + return -1; + } if (uwsgi.schedule_to_main) { uwsgi.schedule_to_main(wsgi_req); } @@ -189,12 +192,12 @@ void async_add_timeout(struct wsgi_request *wsgi_req, int timeout) { } -void async_add_fd_write(struct wsgi_request *wsgi_req, int fd, int timeout) { +int async_add_fd_write(struct wsgi_request *wsgi_req, int fd, int timeout) { struct uwsgi_async_fd *last_uad = NULL, *uad = wsgi_req->waiting_fds; if (fd < 0) - return; + return -1; // find first slot while (uad) { @@ -220,13 +223,15 @@ void async_add_fd_write(struct wsgi_request *wsgi_req, int fd, int timeout) { } uwsgi.async_waiting_fd_table[fd] = wsgi_req; - event_queue_add_fd_write(uwsgi.async_queue, fd); - + wsgi_req->async_force_again = 1; + return event_queue_add_fd_write(uwsgi.async_queue, fd); } static int async_wait_fd_write(int fd, int timeout) { struct wsgi_request *wsgi_req = current_wsgi_req(); - async_add_fd_write(wsgi_req, fd, timeout); + if (async_add_fd_write(wsgi_req, fd, timeout)) { + return -1; + } if (uwsgi.schedule_to_main) { uwsgi.schedule_to_main(wsgi_req); } diff --git a/plugins/fiber/fiber.c b/plugins/fiber/fiber.c index f1f84dd7..8eec8b9b 100644 --- a/plugins/fiber/fiber.c +++ b/plugins/fiber/fiber.c @@ -9,7 +9,7 @@ struct ufib { VALUE uwsgi_fiber_request() { - uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->request(uwsgi.wsgi_req); + uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->request(uwsgi.wsgi_req); uwsgi.wsgi_req->suspended = 0; return Qnil; diff --git a/plugins/greenlet/greenlet.c b/plugins/greenlet/greenlet.c index 877a5ab0..c09cfeed 100644 --- a/plugins/greenlet/greenlet.c +++ b/plugins/greenlet/greenlet.c @@ -17,7 +17,7 @@ struct uwsgi_option greenlet_options[] = { PyObject *py_uwsgi_greenlet_request(PyObject * self, PyObject *args) { - uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->request(uwsgi.wsgi_req); + uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->request(uwsgi.wsgi_req); uwsgi.wsgi_req->suspended = 0; Py_DECREF(ugl.gl[uwsgi.wsgi_req->async_id]); diff --git a/plugins/psgi/uwsgi_plmodule.c b/plugins/psgi/uwsgi_plmodule.c index 3e7969a7..bdc78644 100644 --- a/plugins/psgi/uwsgi_plmodule.c +++ b/plugins/psgi/uwsgi_plmodule.c @@ -40,11 +40,9 @@ XS(XS_wait_fd_read) { timeout = SvIV(ST(1)); } - if (fd >= 0) { - async_add_fd_read(wsgi_req, fd, timeout); - } - - wsgi_req->async_force_again = 1; + if (async_add_fd_read(wsgi_req, fd, timeout)) { + croak("unable to add fd %d to the event queue", fd); + } XSRETURN_UNDEF; } @@ -64,8 +62,8 @@ XS(XS_wait_fd_write) { timeout = SvIV(ST(1)); } - if (fd >= 0) { - async_add_fd_write(wsgi_req, fd, timeout); + if (async_add_fd_write(wsgi_req, fd, timeout)) { + croak("unable to add fd %d to the event queue", fd); } wsgi_req->async_force_again = 1; diff --git a/plugins/python/wsgi_handlers.c b/plugins/python/wsgi_handlers.c index 36c69446..cb63570a 100644 --- a/plugins/python/wsgi_handlers.c +++ b/plugins/python/wsgi_handlers.c @@ -217,8 +217,8 @@ PyObject *py_eventfd_read(PyObject * self, PyObject * args) { return NULL; } - if (fd >= 0) { - async_add_fd_read(wsgi_req, fd, timeout); + if (async_add_fd_read(wsgi_req, fd, timeout)) { + return PyErr_Format(PyExc_IOError, "unable to fd %d to the event queue", fd); } return PyString_FromString(""); @@ -234,8 +234,8 @@ PyObject *py_eventfd_write(PyObject * self, PyObject * args) { return NULL; } - if (fd >= 0) { - async_add_fd_write(wsgi_req, fd, timeout); + if (async_add_fd_write(wsgi_req, fd, timeout)) { + return PyErr_Format(PyExc_IOError, "unable to fd %d to the event queue", fd); } return PyString_FromString(""); diff --git a/plugins/rack/rack_api.c b/plugins/rack/rack_api.c index 15b2af26..38f852b3 100644 --- a/plugins/rack/rack_api.c +++ b/plugins/rack/rack_api.c @@ -506,8 +506,8 @@ VALUE uwsgi_ruby_wait_fd_read(VALUE *class, VALUE arg1, VALUE arg2) { int fd = NUM2INT(arg1); int timeout = NUM2INT(arg2); - if (fd >= 0) { - async_add_fd_read(wsgi_req, fd, timeout); + if (async_add_fd_read(wsgi_req, fd, timeout)) { + rb_raise(rb_eRuntimeError, "unable to add fd %d to the event queue", fd); } return Qtrue; @@ -523,8 +523,8 @@ VALUE uwsgi_ruby_wait_fd_write(VALUE *class, VALUE arg1, VALUE arg2) { int fd = NUM2INT(arg1); int timeout = NUM2INT(arg2); - if (fd >= 0) { - async_add_fd_write(wsgi_req, fd, timeout); + if (async_add_fd_write(wsgi_req, fd, timeout)) { + rb_raise(rb_eRuntimeError, "unable to add fd %d to the event queue", fd); } return Qtrue; diff --git a/uwsgi.h b/uwsgi.h index 587358c2..c1341310 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -2486,8 +2486,8 @@ struct wsgi_request *find_first_accepting_wsgi_req(void); struct wsgi_request *find_wsgi_req_by_fd(int); struct wsgi_request *find_wsgi_req_by_id(int); -void async_add_fd_write(struct wsgi_request *, int, int); -void async_add_fd_read(struct wsgi_request *, int, int); +int async_add_fd_write(struct wsgi_request *, int, int); +int async_add_fd_read(struct wsgi_request *, int, int); struct wsgi_request *next_wsgi_req(struct wsgi_request *);