summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorValentin Bartenev <vbart@nginx.com>2019-11-13 16:45:37 +0300
committerValentin Bartenev <vbart@nginx.com>2019-11-13 16:45:37 +0300
commit69ff7ce7315cc22db3196fef184e0dfad4de7218 (patch)
tree5b853ecabe242c6584529aaf412a602c18e41423
parentdefb14f165509648f1bf1527fb4b5dd96ee9e7cc (diff)
downloadunit-69ff7ce7315cc22db3196fef184e0dfad4de7218.tar.gz
unit-69ff7ce7315cc22db3196fef184e0dfad4de7218.tar.bz2
Python: releasing GIL while waiting for a request.
It unblocks other threads that can be forked by the application to work in background. This closes #336 issue on GitHub.
-rw-r--r--src/nxt_python_wsgi.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/src/nxt_python_wsgi.c b/src/nxt_python_wsgi.c
index 0d647e40..6c726a20 100644
--- a/src/nxt_python_wsgi.c
+++ b/src/nxt_python_wsgi.c
@@ -151,6 +151,7 @@ static wchar_t *nxt_py_home;
static char *nxt_py_home;
#endif
+static PyThreadState *nxt_python_thread_state;
static nxt_python_run_ctx_t *nxt_python_run_ctx;
@@ -340,10 +341,14 @@ nxt_python_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
goto fail;
}
+ nxt_python_thread_state = PyEval_SaveThread();
+
rc = nxt_unit_run(unit_ctx);
nxt_unit_done(unit_ctx);
+ PyEval_RestoreThread(nxt_python_thread_state);
+
nxt_python_atexit();
exit(rc);
@@ -368,19 +373,20 @@ nxt_python_request_handler(nxt_unit_request_info_t *req)
PyObject *result, *iterator, *item, *args, *environ;
nxt_python_run_ctx_t run_ctx = {-1, 0, NULL, req};
+ PyEval_RestoreThread(nxt_python_thread_state);
+
environ = nxt_python_get_environ(&run_ctx);
if (nxt_slow_path(environ == NULL)) {
- nxt_unit_request_done(req, NXT_UNIT_ERROR);
-
- return;
+ rc = NXT_UNIT_ERROR;
+ goto done;
}
args = PyTuple_New(2);
if (nxt_slow_path(args == NULL)) {
nxt_unit_req_error(req, "Python failed to create arguments tuple");
- nxt_unit_request_done(req, NXT_UNIT_ERROR);
- return;
+ rc = NXT_UNIT_ERROR;
+ goto done;
}
PyTuple_SET_ITEM(args, 0, environ);
@@ -398,10 +404,8 @@ nxt_python_request_handler(nxt_unit_request_info_t *req)
nxt_unit_req_error(req, "Python failed to call the application");
PyErr_Print();
- nxt_unit_request_done(req, NXT_UNIT_ERROR);
- nxt_python_run_ctx = NULL;
-
- return;
+ rc = NXT_UNIT_ERROR;
+ goto done;
}
item = NULL;
@@ -455,13 +459,11 @@ nxt_python_request_handler(nxt_unit_request_info_t *req)
PyErr_Print();
}
- nxt_unit_request_done(req, NXT_UNIT_OK);
-
Py_DECREF(result);
- nxt_python_run_ctx = NULL;
+ rc = NXT_UNIT_OK;
- return;
+ goto done;
fail:
@@ -478,9 +480,15 @@ fail:
}
Py_DECREF(result);
- nxt_python_run_ctx = NULL;
- nxt_unit_request_done(req, NXT_UNIT_ERROR);
+ rc = NXT_UNIT_ERROR;
+
+done:
+
+ nxt_python_thread_state = PyEval_SaveThread();
+
+ nxt_python_run_ctx = NULL;
+ nxt_unit_request_done(req, rc);
}