mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-05-01 04:13:36 +00:00
add new files to the tree
This commit is contained in:
614
plugins/python/python_plugin.c
Normal file
614
plugins/python/python_plugin.c
Normal file
@@ -0,0 +1,614 @@
|
||||
#include "uwsgi_python.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
struct uwsgi_python up;
|
||||
|
||||
struct option uwsgi_python_options[] = {
|
||||
|
||||
{"wsgi-file", required_argument, 0, LONG_ARGS_WSGI_FILE},
|
||||
{"file", required_argument, 0, LONG_ARGS_FILE_CONFIG},
|
||||
{"eval", required_argument, 0, LONG_ARGS_EVAL_CONFIG},
|
||||
{"module", required_argument, 0, 'w'},
|
||||
{"callable", required_argument, 0, LONG_ARGS_CALLABLE},
|
||||
{"test", required_argument, 0, 'j'},
|
||||
{"home", required_argument, 0, 'H'},
|
||||
{"pythonpath", required_argument, 0, LONG_ARGS_PYTHONPATH},
|
||||
{"python-path", required_argument, 0, LONG_ARGS_PYTHONPATH},
|
||||
{"pp", required_argument, 0, LONG_ARGS_PYTHONPATH},
|
||||
{"pyargv", required_argument, 0, LONG_ARGS_PYARGV},
|
||||
{"optimize", required_argument, 0, 'O'},
|
||||
#ifdef UWSGI_PASTE
|
||||
{"paste", required_argument, 0, LONG_ARGS_PASTE},
|
||||
#ifdef UWSGI_INI
|
||||
{"ini-paste", required_argument, 0, LONG_ARGS_INI_PASTE},
|
||||
#endif
|
||||
#endif
|
||||
{"catch-exceptions", no_argument, &up.catch_exceptions, 1},
|
||||
{"ignore-script-name", no_argument, &up.ignore_script_name, 1},
|
||||
{"no-site", no_argument, &Py_NoSiteFlag, 1},
|
||||
|
||||
{0, 0, 0, 0},
|
||||
|
||||
};
|
||||
|
||||
/* this routine will be called after each fork to reinitialize the various locks */
|
||||
void uwsgi_python_pthread_prepare(void) {
|
||||
pthread_mutex_lock(&up.lock_pyloaders);
|
||||
}
|
||||
|
||||
void uwsgi_python_pthread_parent(void) {
|
||||
pthread_mutex_unlock(&up.lock_pyloaders);
|
||||
}
|
||||
|
||||
void uwsgi_python_pthread_child(void) {
|
||||
pthread_mutex_init(&up.lock_pyloaders, NULL);
|
||||
}
|
||||
|
||||
|
||||
// fake method
|
||||
PyMethodDef null_methods[] = {
|
||||
{ NULL, NULL},
|
||||
};
|
||||
|
||||
PyMethodDef uwsgi_spit_method[] = { {"uwsgi_spit", py_uwsgi_spit, METH_VARARGS, ""} };
|
||||
PyMethodDef uwsgi_write_method[] = { {"uwsgi_write", py_uwsgi_write, METH_VARARGS, ""} };
|
||||
|
||||
|
||||
int uwsgi_python_init() {
|
||||
|
||||
uwsgi_log("Python version: %s\n", Py_GetVersion());
|
||||
|
||||
if (up.home != NULL) {
|
||||
uwsgi_log("Setting PythonHome to %s...\n", up.home);
|
||||
#ifdef PYTHREE
|
||||
wchar_t *wpyhome;
|
||||
wpyhome = malloc((sizeof(wchar_t) * strlen(up.home)) + 2);
|
||||
if (!wpyhome) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
}
|
||||
mbstowcs(wpyhome, up.home, strlen(up.home));
|
||||
Py_SetPythonHome(wpyhome);
|
||||
free(wpyhome);
|
||||
#else
|
||||
Py_SetPythonHome(up.home);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef PYTHREE
|
||||
wchar_t pname[6];
|
||||
mbstowcs(pname, "uWSGI", 6);
|
||||
Py_SetProgramName(pname);
|
||||
#else
|
||||
|
||||
Py_SetProgramName("uWSGI");
|
||||
#endif
|
||||
|
||||
|
||||
Py_Initialize();
|
||||
|
||||
Py_OptimizeFlag = up.optimize;
|
||||
|
||||
up.wsgi_spitout = PyCFunction_New(uwsgi_spit_method, NULL);
|
||||
up.wsgi_writeout = PyCFunction_New(uwsgi_write_method, NULL);
|
||||
|
||||
up.main_thread = PyThreadState_Get();
|
||||
|
||||
if (up.test_module != NULL) {
|
||||
if (PyImport_ImportModule(up.test_module)) {
|
||||
exit(0);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
init_uwsgi_vars();
|
||||
|
||||
// setup app loaders
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
up.loaders[LOADER_DYN] = uwsgi_dyn_loader;
|
||||
#endif
|
||||
up.loaders[LOADER_UWSGI] = uwsgi_uwsgi_loader;
|
||||
up.loaders[LOADER_FILE] = uwsgi_file_loader;
|
||||
#ifdef UWSGI_PASTE
|
||||
up.loaders[LOADER_PASTE] = uwsgi_paste_loader;
|
||||
#endif
|
||||
up.loaders[LOADER_EVAL] = uwsgi_eval_loader;
|
||||
up.loaders[LOADER_MOUNT] = uwsgi_mount_loader;
|
||||
up.loaders[LOADER_CALLABLE] = uwsgi_callable_loader;
|
||||
up.loaders[LOADER_STRING_CALLABLE] = uwsgi_string_callable_loader;
|
||||
|
||||
// by default set a fake GIL (little impact on performance)
|
||||
up.gil_get = gil_fake_get;
|
||||
up.gil_release = gil_fake_release;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_python_post_fork() {
|
||||
|
||||
PyObject *random_module, *random_dict, *random_seed;
|
||||
|
||||
// reinitialize the random seed (thanks Jonas Borgström)
|
||||
random_module = PyImport_ImportModule("random");
|
||||
if (random_module) {
|
||||
random_dict = PyModule_GetDict(random_module);
|
||||
if (random_dict) {
|
||||
random_seed = PyDict_GetItemString(random_dict, "seed");
|
||||
if (random_seed) {
|
||||
PyObject *random_args = PyTuple_New(1);
|
||||
// pass no args
|
||||
PyTuple_SetItem(random_args, 0, Py_None);
|
||||
PyEval_CallObject( random_seed, random_args );
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
// call the post_fork_hook
|
||||
PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
|
||||
if (uwsgi_dict) {
|
||||
PyObject *pfh = PyDict_GetItemString(uwsgi_dict, "post_fork_hook");
|
||||
if (pfh) {
|
||||
python_call(pfh, PyTuple_New(0), 0);
|
||||
}
|
||||
}
|
||||
PyErr_Clear();
|
||||
#endif
|
||||
|
||||
UWSGI_RELEASE_GIL
|
||||
|
||||
}
|
||||
|
||||
void init_uwsgi_vars() {
|
||||
|
||||
int i;
|
||||
PyObject *pysys, *pysys_dict, *pypath;
|
||||
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
char venv_version[15] ;
|
||||
PyObject *site_module;
|
||||
#endif
|
||||
|
||||
/* add cwd to pythonpath */
|
||||
pysys = PyImport_ImportModule("sys");
|
||||
if (!pysys) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
pysys_dict = PyModule_GetDict(pysys);
|
||||
pypath = PyDict_GetItemString(pysys_dict, "path");
|
||||
if (!pypath) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
// simulate a pythonhome directive
|
||||
if (uwsgi.wsgi_req->pyhome_len > 0) {
|
||||
|
||||
PyObject *venv_path = UWSGI_PYFROMSTRINGSIZE(uwsgi.wsgi_req->pyhome, uwsgi.wsgi_req->pyhome_len) ;
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_debug("setting dynamic virtualenv to %.*s\n", uwsgi.wsgi_req->pyhome_len, uwsgi.wsgi_req->pyhome);
|
||||
#endif
|
||||
|
||||
PyDict_SetItemString(pysys_dict, "prefix", venv_path);
|
||||
PyDict_SetItemString(pysys_dict, "exec_prefix", venv_path);
|
||||
|
||||
venv_version[14] = 0 ;
|
||||
if (snprintf(venv_version, 15, "/lib/python%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION) == -1) {
|
||||
return ;
|
||||
}
|
||||
|
||||
// check here
|
||||
PyString_Concat( &venv_path, PyString_FromString(venv_version) );
|
||||
|
||||
if ( PyList_Insert(pypath, 0, venv_path) ) {
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
site_module = PyImport_ImportModule("site");
|
||||
if (site_module) {
|
||||
PyImport_ReloadModule(site_module);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
if (PyList_Insert(pypath, 0, UWSGI_PYFROMSTRING(".") ) != 0) {
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
for (i = 0; i < up.python_path_cnt; i++) {
|
||||
if (PyList_Insert(pypath, 0, UWSGI_PYFROMSTRING(up.python_path[i]) ) != 0) {
|
||||
PyErr_Print();
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "added %s to pythonpath.\n", up.python_path[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_uwsgi_config(char *module) {
|
||||
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
PyObject *uwsgi_module, *uwsgi_dict;
|
||||
#endif
|
||||
PyObject *applications;
|
||||
PyObject *app_list;
|
||||
Py_ssize_t i;
|
||||
PyObject *app_mnt, *app_app = NULL;
|
||||
char *quick_callable ;
|
||||
|
||||
quick_callable = get_uwsgi_pymodule(module);
|
||||
if (quick_callable == NULL) {
|
||||
if (up.callable) {
|
||||
quick_callable = up.callable ;
|
||||
}
|
||||
else {
|
||||
quick_callable = "application";
|
||||
}
|
||||
}
|
||||
|
||||
up.loader_dict = get_uwsgi_pydict(module);
|
||||
if (!up.loader_dict) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_log( "...getting the applications list from the '%s' module...\n", module);
|
||||
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
uwsgi_module = PyImport_ImportModule("uwsgi");
|
||||
if (!uwsgi_module) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_dict = PyModule_GetDict(uwsgi_module);
|
||||
if (!uwsgi_dict) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
applications = PyDict_GetItemString(uwsgi_dict, "applications");
|
||||
if (!PyDict_Check(applications)) {
|
||||
uwsgi_log( "uwsgi.applications dictionary is not defined, trying with the \"applications\" one...\n");
|
||||
#endif
|
||||
applications = PyDict_GetItemString(up.loader_dict, "applications");
|
||||
if (!applications) {
|
||||
uwsgi_log( "applications dictionary is not defined, trying with the \"application\" callable.\n");
|
||||
quick_callable = uwsgi_concat3(module, ":", quick_callable);
|
||||
if (init_uwsgi_app(LOADER_UWSGI, (void *) quick_callable, uwsgi.wsgi_req, 0) < 0) {
|
||||
uwsgi_log( "...goodbye cruel world...\n");
|
||||
exit(1);
|
||||
}
|
||||
free(quick_callable);
|
||||
return;
|
||||
}
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!PyDict_Check(applications)) {
|
||||
uwsgi_log( "The 'applications' object must be a dictionary.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
app_list = PyDict_Keys(applications);
|
||||
if (!app_list) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
if (PyList_Size(app_list) < 1) {
|
||||
uwsgi_log( "You must define an app.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < PyList_Size(app_list); i++) {
|
||||
app_mnt = PyList_GetItem(app_list, i);
|
||||
|
||||
if (!PyString_Check(app_mnt)) {
|
||||
uwsgi_log( "the app mountpoint must be a bytestring.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
uwsgi.wsgi_req->script_name = PyString_AsString(app_mnt);
|
||||
uwsgi.wsgi_req->script_name_len = strlen(uwsgi.wsgi_req->script_name);
|
||||
|
||||
app_app = PyDict_GetItem(applications, app_mnt);
|
||||
|
||||
if (!PyString_Check(app_app) && !PyFunction_Check(app_app) && !PyCallable_Check(app_app)) {
|
||||
uwsgi_log( "the app callable must be a string, a function or a callable. (found %s)\n", app_app->ob_type->tp_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef PYTHREE
|
||||
if (PyUnicode_Check(app_app)) {
|
||||
#else
|
||||
if (PyString_Check(app_app)) {
|
||||
#endif
|
||||
if (init_uwsgi_app(LOADER_STRING_CALLABLE, (void *) PyString_AsString(app_app), uwsgi.wsgi_req, 0) < 0) {
|
||||
uwsgi_log( "...goodbye cruel world...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
if (init_uwsgi_app(LOADER_CALLABLE, (void *) app_app, uwsgi.wsgi_req, 0) < 0) {
|
||||
uwsgi_log( "...goodbye cruel world...\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(app_mnt);
|
||||
Py_DECREF(app_app);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef PYTHREE
|
||||
static PyModuleDef uwsgi_module3 = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"uwsgi",
|
||||
NULL,
|
||||
-1,
|
||||
null_methods,
|
||||
};
|
||||
PyObject *init_uwsgi3(void) {
|
||||
return PyModule_Create(&uwsgi_module3);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef UWSGI_EMBEDDED
|
||||
void init_uwsgi_embedded_module() {
|
||||
PyObject *new_uwsgi_module, *zero;
|
||||
int i;
|
||||
|
||||
/* initialize for stats */
|
||||
uwsgi.workers_tuple = PyTuple_New(uwsgi.numproc);
|
||||
for (i = 0; i < uwsgi.numproc; i++) {
|
||||
zero = PyDict_New();
|
||||
Py_INCREF(zero);
|
||||
PyTuple_SetItem(uwsgi.workers_tuple, i, zero);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef PYTHREE
|
||||
PyImport_AppendInittab("uwsgi", init_uwsgi3);
|
||||
new_uwsgi_module = PyImport_AddModule("uwsgi");
|
||||
#else
|
||||
new_uwsgi_module = Py_InitModule("uwsgi", null_methods);
|
||||
#endif
|
||||
if (new_uwsgi_module == NULL) {
|
||||
uwsgi_log( "could not initialize the uwsgi python module\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi.embedded_dict = PyModule_GetDict(new_uwsgi_module);
|
||||
if (!uwsgi.embedded_dict) {
|
||||
uwsgi_log( "could not get uwsgi module __dict__\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "version", PyString_FromString(UWSGI_VERSION))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (uwsgi.mode) {
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "mode", PyString_FromString(uwsgi.mode))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.pidfile) {
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "pidfile", PyString_FromString(uwsgi.pidfile))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "SPOOL_RETRY", PyInt_FromLong(17))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "numproc", PyInt_FromLong(uwsgi.numproc))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef UNBIT
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "unbit", Py_True)) {
|
||||
#else
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "unbit", Py_None)) {
|
||||
#endif
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "buffer_size", PyInt_FromLong(uwsgi.buffer_size))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "started_on", PyInt_FromLong(uwsgi.start_tv.tv_sec))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "start_response", up.wsgi_spitout)) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "fastfuncs", PyList_New(256))) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "applications", Py_None)) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (uwsgi.is_a_reload) {
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "is_a_reload", Py_True)) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "is_a_reload", Py_False)) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi.embedded_args = PyTuple_New(2);
|
||||
if (!uwsgi.embedded_args) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PyDict_SetItemString(uwsgi.embedded_dict, "message_manager_marshal", Py_None)) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi.fastfuncslist = PyDict_GetItemString(uwsgi.embedded_dict, "fastfuncs");
|
||||
if (!uwsgi.fastfuncslist) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
init_uwsgi_module_advanced(new_uwsgi_module);
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir != NULL) {
|
||||
init_uwsgi_module_spooler(new_uwsgi_module);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (uwsgi.sharedareasize > 0 && uwsgi.sharedarea) {
|
||||
init_uwsgi_module_sharedarea(new_uwsgi_module);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
int uwsgi_python_manage_options(int i, char *optarg) {
|
||||
|
||||
switch(i) {
|
||||
case 'w':
|
||||
up.wsgi_config = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_PYTHONPATH:
|
||||
uwsgi_log("found PYTHONPATH\n");
|
||||
if (up.python_path_cnt < MAX_PYTHONPATH) {
|
||||
up.python_path[up.python_path_cnt] = optarg;
|
||||
up.python_path_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "you can specify at most %d --pythonpath options\n", MAX_PYTHONPATH);
|
||||
}
|
||||
return 1;
|
||||
case LONG_ARGS_PYARGV:
|
||||
up.argv = optarg;
|
||||
return 1;
|
||||
case 'j':
|
||||
up.test_module = optarg;
|
||||
return 1;
|
||||
case 'H':
|
||||
up.home = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_CALLABLE:
|
||||
up.callable = optarg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uwsgi_python_init_app() {
|
||||
|
||||
if (up.wsgi_config != NULL) {
|
||||
init_uwsgi_app(LOADER_UWSGI, up.wsgi_config, uwsgi.wsgi_req, 0);
|
||||
}
|
||||
|
||||
if (up.file_config != NULL) {
|
||||
init_uwsgi_app(LOADER_FILE, up.file_config, uwsgi.wsgi_req, 0);
|
||||
}
|
||||
#ifdef UWSGI_PASTE
|
||||
if (up.paste != NULL) {
|
||||
init_uwsgi_app(LOADER_PASTE, up.paste, uwsgi.wsgi_req, 0);
|
||||
}
|
||||
#endif
|
||||
if (up.eval != NULL) {
|
||||
init_uwsgi_app(LOADER_EVAL, up.eval, uwsgi.wsgi_req, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_python_enable_threads() {
|
||||
|
||||
PyEval_InitThreads();
|
||||
if (pthread_key_create(&up.upt_save_key, NULL)) {
|
||||
uwsgi_error("pthread_key_create()");
|
||||
exit(1);
|
||||
}
|
||||
pthread_setspecific(up.upt_save_key, (void *) PyThreadState_Get());
|
||||
pthread_mutex_init(&up.lock_pyloaders, NULL);
|
||||
pthread_atfork(uwsgi_python_pthread_prepare, uwsgi_python_pthread_parent, uwsgi_python_pthread_child);
|
||||
up.gil_get = gil_real_get;
|
||||
up.gil_release = gil_real_release;
|
||||
|
||||
uwsgi_log("threads support enabled\n");
|
||||
}
|
||||
|
||||
void uwsgi_python_init_thread() {
|
||||
|
||||
// set a new ThreadState for each thread
|
||||
PyThreadState *pts;
|
||||
pts = PyThreadState_New(up.main_thread->interp);
|
||||
pthread_setspecific(up.upt_save_key, (void *) pts);
|
||||
|
||||
}
|
||||
|
||||
struct uwsgi_plugin python_plugin = {
|
||||
|
||||
.name = "python",
|
||||
.modifier1 = 0,
|
||||
.init = uwsgi_python_init,
|
||||
.post_fork = uwsgi_python_post_fork,
|
||||
.options = uwsgi_python_options,
|
||||
.manage_opt = uwsgi_python_manage_options,
|
||||
.request = uwsgi_request_wsgi,
|
||||
.after_request = uwsgi_after_request_wsgi,
|
||||
.init_apps = uwsgi_python_init_app,
|
||||
.enable_threads = uwsgi_python_enable_threads,
|
||||
.init_thread = uwsgi_python_init_thread,
|
||||
/*
|
||||
.magic = uwsgi_python_magic,
|
||||
.help = uwsgi_python_help,
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user