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:
Valentin Bartenev
2019-11-13 16:45:37 +03:00
parent defb14f165
commit 69ff7ce731

View File

@@ -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);
}