From 296a8449c9dfbc720adbfd17fa813c4a327f9a8d Mon Sep 17 00:00:00 2001 From: Unbit Date: Thu, 25 Apr 2013 13:46:30 +0200 Subject: [PATCH] improved stackless plugin --- plugins/stackless/stackless.c | 67 +++++++++++++++++++++++------------ plugins/ugreen/ugreen.c | 4 +-- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/plugins/stackless/stackless.c b/plugins/stackless/stackless.c index 38e67565..eaf34456 100644 --- a/plugins/stackless/stackless.c +++ b/plugins/stackless/stackless.c @@ -2,6 +2,7 @@ #include extern struct uwsgi_server uwsgi; +extern struct uwsgi_python up; struct ustackless { int enabled; @@ -9,16 +10,22 @@ struct ustackless { PyTaskletObject **sl; } usl; -struct uwsgi_option stackless_options[] = { +static void gil_stackless_get() { + pthread_setspecific(up.upt_gil_key, (void *) PyGILState_Ensure()); +} + +static void gil_stackless_release() { + PyGILState_Release((PyGILState_STATE) pthread_getspecific(up.upt_gil_key)); +} + +static struct uwsgi_option stackless_options[] = { {"stackless", no_argument, 0, "use stackless as suspend engine", uwsgi_opt_true, &usl.enabled, 0}, - { 0, 0, 0, 0 } + { 0, 0, 0, 0, 0, 0, 0 } }; -PyObject *py_uwsgi_stackless_request(PyObject * self, PyObject *args) { - - uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->request(uwsgi.wsgi_req); - uwsgi.wsgi_req->suspended = 0; +static PyObject *py_uwsgi_stackless_request(PyObject * self, PyObject *args) { + async_schedule_to_req_green(); Py_DECREF(usl.sl[uwsgi.wsgi_req->async_id]); Py_INCREF(Py_None); @@ -27,9 +34,13 @@ PyObject *py_uwsgi_stackless_request(PyObject * self, PyObject *args) { PyMethodDef uwsgi_stackless_request_method[] = {{"uwsgi_stackless_request", py_uwsgi_stackless_request, METH_VARARGS, ""}}; -static inline static void stackless_schedule_to_req() { +static void stackless_schedule_to_req() { int id = uwsgi.wsgi_req->async_id; + uint8_t modifier1 = uwsgi.wsgi_req->uh->modifier1; + + // ensure gil + UWSGI_GET_GIL if (!uwsgi.wsgi_req->suspended) { usl.sl[id] = PyTasklet_New(NULL, usl.callable); @@ -39,46 +50,56 @@ static inline static void stackless_schedule_to_req() { uwsgi.wsgi_req->suspended = 1; } + // call it in the main core + if (uwsgi.p[modifier1]->suspend) { + uwsgi.p[modifier1]->suspend(NULL); + } + PyTasklet_Run(usl.sl[id]); - if (uwsgi.wsgi_req->suspended) { - uwsgi.wsgi_req->async_status = UWSGI_AGAIN; - } + // call it in the main core + if (uwsgi.p[modifier1]->resume) { + uwsgi.p[modifier1]->resume(NULL); + } } -static inline static void stackless_schedule_to_main(struct wsgi_request *wsgi_req) { +static void stackless_schedule_to_main(struct wsgi_request *wsgi_req) { + // ensure gil + UWSGI_GET_GIL + + if (uwsgi.p[wsgi_req->uh->modifier1]->suspend) { + uwsgi.p[wsgi_req->uh->modifier1]->suspend(wsgi_req); + } PyStackless_Schedule(Py_None, 1); + if (uwsgi.p[wsgi_req->uh->modifier1]->resume) { + uwsgi.p[wsgi_req->uh->modifier1]->resume(wsgi_req); + } uwsgi.wsgi_req = wsgi_req; } -int stackless_init() { - return 0; -} - -void stackless_init_apps(void) { - - if (!usl.enabled) { - return; - } +static void stackless_init_apps(void) { + if (!usl.enabled) return; usl.sl = uwsgi_malloc( sizeof(PyTaskletObject *) * uwsgi.async ); usl.callable = PyCFunction_New(uwsgi_stackless_request_method, NULL); + Py_INCREF(usl.callable); uwsgi_log("enabled stackless engine\n"); + if (uwsgi.has_threads) { + up.gil_get = gil_stackless_get; + up.gil_release = gil_stackless_release; + } uwsgi.schedule_to_main = stackless_schedule_to_main; uwsgi.schedule_to_req = stackless_schedule_to_req; - return; - } struct uwsgi_plugin stackless_plugin = { .name = "stackless", - .init = stackless_init, .init_apps = stackless_init_apps, .options = stackless_options, }; diff --git a/plugins/ugreen/ugreen.c b/plugins/ugreen/ugreen.c index 16fc3d34..76445ee8 100644 --- a/plugins/ugreen/ugreen.c +++ b/plugins/ugreen/ugreen.c @@ -21,8 +21,8 @@ struct uwsgi_ugreen { extern struct uwsgi_server uwsgi; -struct uwsgi_option ugreen_options[] = { - {"ugreen", no_argument, 0, "enable ugreen coroutine subsystem", uwsgi_opt_true, &ug.ugreen, 1}, +static struct uwsgi_option ugreen_options[] = { + {"ugreen", no_argument, 0, "enable ugreen coroutine subsystem", uwsgi_opt_true, &ug.ugreen, 0}, {"ugreen-stacksize", required_argument, 0, "set ugreen stack size in pages", uwsgi_opt_set_int, &ug.stackpages, 0}, { 0, 0, 0, 0, 0, 0, 0 } };