From f62f7f928238b6a191ec72f001be1cb647ca893f Mon Sep 17 00:00:00 2001 From: "roberto@quantal64" Date: Sat, 2 Jun 2012 09:43:24 +0200 Subject: [PATCH] thread-safe wsgi env behaviour --- plugins/python/python_plugin.c | 17 +++++++++++++++-- plugins/python/wsgi_handlers.c | 6 ------ plugins/python/wsgi_subhandler.c | 6 ------ 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index fca80f0c..66c10499 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -956,16 +956,18 @@ void uwsgi_python_spooler_init(void) { // and it is a bit faster than the "holy" allocator void *uwsgi_python_create_env_cheat(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) { #ifdef UWSGI_ASYNC + wsgi_req->async_args = wi->args[wsgi_req->async_id]; Py_INCREF((PyObject *)wi->environ[wsgi_req->async_id]); return wi->environ[wsgi_req->async_id]; #else + wsgi_req->async_args = wi->args; Py_INCREF((PyObject *)wi->environ); return wi->environ; #endif } void uwsgi_python_destroy_env_cheat(struct wsgi_request *wsgi_req) { - PyDict_Clear(wsgi_req->async_environ); + PyDict_Clear((PyObject *)wsgi_req->async_environ); } // this is the "holy" allocator for WSGI's env @@ -979,11 +981,22 @@ void uwsgi_python_destroy_env_cheat(struct wsgi_request *wsgi_req) { void *uwsgi_python_create_env_holy(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) { - return PyDict_New(); + wsgi_req->async_args = PyTuple_New(2); + // set start_response() + Py_INCREF(up.wsgi_spitout); + PyTuple_SetItem((PyObject *)wsgi_req->async_args, 1, up.wsgi_spitout); + PyObject *env = PyDict_New(); + Py_INCREF(env); + return env; } void uwsgi_python_destroy_env_holy(struct wsgi_request *wsgi_req) { Py_DECREF((PyObject *)wsgi_req->async_environ); + Py_DECREF((PyObject *) wsgi_req->async_args); + // in non-multithread modes, we set uwsgi.env incrementing the refcount of the environ + if (uwsgi.threads < 2) { + Py_DECREF((PyObject *)wsgi_req->async_environ); + } } diff --git a/plugins/python/wsgi_handlers.c b/plugins/python/wsgi_handlers.c index a0296f71..a9fabdbe 100644 --- a/plugins/python/wsgi_handlers.c +++ b/plugins/python/wsgi_handlers.c @@ -444,12 +444,6 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { // no fear of race conditions for this counter as it is already protected by the GIL wi->requests++; -#ifdef UWSGI_ASYNC - wsgi_req->async_args = wi->args[wsgi_req->async_id]; -#else - wsgi_req->async_args = wi->args; -#endif - // create WSGI environ wsgi_req->async_environ = up.wsgi_env_create(wsgi_req, wi); diff --git a/plugins/python/wsgi_subhandler.c b/plugins/python/wsgi_subhandler.c index fc829dfc..e339da9a 100644 --- a/plugins/python/wsgi_subhandler.c +++ b/plugins/python/wsgi_subhandler.c @@ -150,7 +150,6 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_ PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node); // call - PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ); return python_call(wsgi_req->async_app, wsgi_req->async_args, uwsgi.catch_exceptions, wsgi_req); } @@ -219,12 +218,8 @@ int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) { #endif } - - - pychunk = PyIter_Next(wsgi_req->async_placeholder); - if (!pychunk) { if (PyErr_Occurred()) { int do_exit = uwsgi_python_manage_exceptions(); @@ -309,7 +304,6 @@ clear2: Py_DECREF((PyObject *)wsgi_req->async_result); PyErr_Clear(); - return UWSGI_OK; }