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.
This commit is contained in:
@@ -151,6 +151,7 @@ static wchar_t *nxt_py_home;
|
|||||||
static char *nxt_py_home;
|
static char *nxt_py_home;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static PyThreadState *nxt_python_thread_state;
|
||||||
static nxt_python_run_ctx_t *nxt_python_run_ctx;
|
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;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nxt_python_thread_state = PyEval_SaveThread();
|
||||||
|
|
||||||
rc = nxt_unit_run(unit_ctx);
|
rc = nxt_unit_run(unit_ctx);
|
||||||
|
|
||||||
nxt_unit_done(unit_ctx);
|
nxt_unit_done(unit_ctx);
|
||||||
|
|
||||||
|
PyEval_RestoreThread(nxt_python_thread_state);
|
||||||
|
|
||||||
nxt_python_atexit();
|
nxt_python_atexit();
|
||||||
|
|
||||||
exit(rc);
|
exit(rc);
|
||||||
@@ -368,19 +373,20 @@ nxt_python_request_handler(nxt_unit_request_info_t *req)
|
|||||||
PyObject *result, *iterator, *item, *args, *environ;
|
PyObject *result, *iterator, *item, *args, *environ;
|
||||||
nxt_python_run_ctx_t run_ctx = {-1, 0, NULL, req};
|
nxt_python_run_ctx_t run_ctx = {-1, 0, NULL, req};
|
||||||
|
|
||||||
|
PyEval_RestoreThread(nxt_python_thread_state);
|
||||||
|
|
||||||
environ = nxt_python_get_environ(&run_ctx);
|
environ = nxt_python_get_environ(&run_ctx);
|
||||||
if (nxt_slow_path(environ == NULL)) {
|
if (nxt_slow_path(environ == NULL)) {
|
||||||
nxt_unit_request_done(req, NXT_UNIT_ERROR);
|
rc = NXT_UNIT_ERROR;
|
||||||
|
goto done;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
args = PyTuple_New(2);
|
args = PyTuple_New(2);
|
||||||
if (nxt_slow_path(args == NULL)) {
|
if (nxt_slow_path(args == NULL)) {
|
||||||
nxt_unit_req_error(req, "Python failed to create arguments tuple");
|
nxt_unit_req_error(req, "Python failed to create arguments tuple");
|
||||||
|
|
||||||
nxt_unit_request_done(req, NXT_UNIT_ERROR);
|
rc = NXT_UNIT_ERROR;
|
||||||
return;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyTuple_SET_ITEM(args, 0, environ);
|
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");
|
nxt_unit_req_error(req, "Python failed to call the application");
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
|
|
||||||
nxt_unit_request_done(req, NXT_UNIT_ERROR);
|
rc = NXT_UNIT_ERROR;
|
||||||
nxt_python_run_ctx = NULL;
|
goto done;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
item = NULL;
|
item = NULL;
|
||||||
@@ -455,13 +459,11 @@ nxt_python_request_handler(nxt_unit_request_info_t *req)
|
|||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_unit_request_done(req, NXT_UNIT_OK);
|
|
||||||
|
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
|
|
||||||
nxt_python_run_ctx = NULL;
|
rc = NXT_UNIT_OK;
|
||||||
|
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
@@ -478,9 +480,15 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Py_DECREF(result);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user