int uwsgi_python_signal_handler(uint8_t sig, void *handler) { UWSGI_GET_GIL; PyObject *args = PyTuple_New(1); PyObject *ret; if (!args) goto clear; if (!handler) goto clear; PyTuple_SetItem(args, 0, PyInt_FromLong(sig)); ret = python_call(handler, args, 0, NULL); Py_DECREF(args); if (ret) { Py_DECREF(ret); UWSGI_RELEASE_GIL; return 0; } clear: UWSGI_RELEASE_GIL; return -1; }
int uwsgi_python_mule_msg(char *message, size_t len) { UWSGI_GET_GIL; PyObject *mule_msg_hook = PyDict_GetItemString(up.embedded_dict, "mule_msg_hook"); if (!mule_msg_hook) { // ignore UWSGI_RELEASE_GIL; return 0; } PyObject *pyargs = PyTuple_New(1); PyTuple_SetItem(pyargs, 0, PyString_FromStringAndSize(message, len)); PyObject *ret = python_call(mule_msg_hook, pyargs, 0, NULL); Py_DECREF(pyargs); if (ret) { Py_DECREF(ret); } if (PyErr_Occurred()) PyErr_Print(); UWSGI_RELEASE_GIL; return 1; }
PyObject *py_uwsgi_gevent_main(PyObject * self, PyObject * args) { // hack to retrieve the socket address PyObject *py_uwsgi_sock = PyTuple_GetItem(args, 0); struct uwsgi_socket *uwsgi_sock = (struct uwsgi_socket *) PyLong_AsLong(py_uwsgi_sock); struct wsgi_request *wsgi_req = NULL; edge: wsgi_req = find_first_available_wsgi_req(); if (wsgi_req == NULL) { uwsgi_log("async queue is full !!!\n"); goto clear; } // fill wsgi_request structure wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi_sock ); // mark core as used uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 1; wsgi_req->start_of_request = uwsgi_micros(); wsgi_req->start_of_request_in_sec = wsgi_req->start_of_request/1000000; // enter harakiri mode if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) { set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]); } // accept the connection if (wsgi_req_simple_accept(wsgi_req, uwsgi_sock->fd)) { free_req_queue; if (uwsgi_sock->retry && uwsgi_sock->retry[wsgi_req->async_id]) { goto edge; } goto clear; } // on linux we need to set the socket in non-blocking as it is not inherited #ifdef __linux__ uwsgi_socket_nb(wsgi_req->poll.fd); #endif // hack to easily pass wsgi_req pointer to the greenlet PyTuple_SetItem(ugevent.greenlet_args, 1, PyLong_FromLong((long)wsgi_req)); // spawn the request greenlet PyObject *new_gl = python_call(ugevent.spawn, ugevent.greenlet_args, 0, NULL); Py_DECREF(new_gl); if (uwsgi_sock->edge_trigger) { #ifdef UWSGI_DEBUG uwsgi_log("i am an edge triggered socket !!!\n"); #endif goto edge; } clear: Py_INCREF(Py_None); return Py_None; }
void uwsgi_python_post_fork() { #ifdef UWSGI_SPOOLER if (uwsgi.i_am_a_spooler) { UWSGI_GET_GIL } #endif uwsgi_python_reset_random_seed(); #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, NULL); } } PyErr_Clear(); #endif if (uwsgi.mywid > 0) { #ifdef UWSGI_THREADING if (up.auto_reload) { // spawn the reloader thread pthread_t par_tid; pthread_create(&par_tid, NULL, uwsgi_python_autoreloader_thread, NULL); } #endif } UWSGI_RELEASE_GIL }
PyObject *py_uwsgi_gevent_main(PyObject * self, PyObject * args) { // hack to retrieve the socket address PyObject *py_uwsgi_sock = PyTuple_GetItem(args, 0); struct uwsgi_socket *uwsgi_sock = (struct uwsgi_socket *) PyLong_AsLong(py_uwsgi_sock); long watcher_index = PyInt_AsLong(PyTuple_GetItem(args, 1)); struct wsgi_request *wsgi_req = NULL; edge: wsgi_req = find_first_available_wsgi_req(); if (wsgi_req == NULL) { uwsgi_async_queue_is_full(uwsgi_now()); PyObject_CallMethod(ugevent.watchers[watcher_index], "stop", NULL); goto clear; } // fill wsgi_request structure wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi_sock ); // mark core as used uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 1; // accept the connection (since uWSGI 1.5 all of the sockets are non-blocking) if (wsgi_req_simple_accept(wsgi_req, uwsgi_sock->fd)) { free_req_queue; if (uwsgi_sock->retry && uwsgi_sock->retry[wsgi_req->async_id]) { goto edge; } // in case of errors (or thundering herd, just rest it) uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 0; goto clear; } wsgi_req->start_of_request = uwsgi_micros(); wsgi_req->start_of_request_in_sec = wsgi_req->start_of_request/1000000; // enter harakiri mode if (uwsgi.harakiri_options.workers > 0) { set_harakiri(wsgi_req, uwsgi.harakiri_options.workers); } // hack to easily pass wsgi_req pointer to the greenlet PyTuple_SetItem(ugevent.greenlet_args, 1, PyLong_FromLong((long)wsgi_req)); // spawn the request greenlet PyObject *new_gl = python_call(ugevent.spawn, ugevent.greenlet_args, 0, NULL); Py_DECREF(new_gl); if (uwsgi_sock->edge_trigger) { #ifdef UWSGI_DEBUG uwsgi_log("i am an edge triggered socket !!!\n"); #endif goto edge; } clear: Py_INCREF(Py_None); return Py_None; }
static void monkey_patch() { PyObject *gevent_monkey_dict = get_uwsgi_pydict("gevent.monkey"); if (!gevent_monkey_dict) uwsgi_pyexit; PyObject *gevent_monkey_patch_all = PyDict_GetItemString(gevent_monkey_dict, "patch_all"); if (!gevent_monkey_patch_all) uwsgi_pyexit; PyObject *ret = python_call(gevent_monkey_patch_all, PyTuple_New(0), 0, NULL); if (!ret) uwsgi_pyexit; }
// yes copy&paste no-DRY for me :P PyObject *py_uwsgi_gevent_my_signal(PyObject * self, PyObject * args) { PyTuple_SetItem(ugevent.signal_args, 1, PyInt_FromLong(uwsgi.my_signal_socket)); // spawn the signal_handler greenlet PyObject *new_gl = python_call(ugevent.spawn, ugevent.signal_args, 0, NULL); Py_DECREF(new_gl); Py_INCREF(Py_None); return Py_None; }
void uwsgi_python_atexit() { if (uwsgi.mywid == -1) goto realstuff; // if hijacked do not run atexit hooks if (uwsgi.workers[uwsgi.mywid].hijacked) return; // if busy do not run atexit hooks if (uwsgi.workers[uwsgi.mywid].busy) return; #ifdef UWSGI_ASYNC // managing atexit in async mode is a real pain...skip it for now if (uwsgi.async > 1) return; #endif realstuff: // this time we use this higher level function // as this code can be executed in a signal handler if (!Py_IsInitialized()) { return; } if (uwsgi.has_threads) PyGILState_Ensure(); // no need to worry about freeing memory #ifdef UWSGI_EMBEDDED PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi"); if (uwsgi_dict) { PyObject *ae = PyDict_GetItemString(uwsgi_dict, "atexit"); if (ae) { python_call(ae, PyTuple_New(0), 0, NULL); } } #endif // this part is a 1:1 copy of mod_wsgi 3.x // it is required to fix some atexit bug with python 3 // and to shutdown useless threads complaints PyObject *module = PyImport_ImportModule("atexit"); Py_XDECREF(module); if (uwsgi.has_threads) { if (!PyImport_AddModule("dummy_threading")) PyErr_Clear(); } Py_Finalize(); }
PyObject *uwsgi_uwsgi_loader(void *arg1) { PyObject *wsgi_dict; char *quick_callable; PyObject *tmp_callable; PyObject *applications; PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi"); char *module = (char *) arg1; quick_callable = get_uwsgi_pymodule(module); if (quick_callable == NULL) { if (up.callable) { quick_callable = up.callable; } else { quick_callable = "application"; } wsgi_dict = get_uwsgi_pydict(module); } else { wsgi_dict = get_uwsgi_pydict(module); module[strlen(module)] = ':'; } if (!wsgi_dict) { return NULL; } applications = PyDict_GetItemString(uwsgi_dict, "applications"); if (applications && PyDict_Check(applications)) return applications; applications = PyDict_GetItemString(wsgi_dict, "applications"); if (applications && PyDict_Check(applications)) return applications; // quick callable -> thanks gunicorn for the idea // we have extended the concept a bit... if (quick_callable[strlen(quick_callable) -2 ] == '(' && quick_callable[strlen(quick_callable) -1] ==')') { quick_callable[strlen(quick_callable) -2 ] = 0; tmp_callable = PyDict_GetItemString(wsgi_dict, quick_callable); quick_callable[strlen(quick_callable)] = '('; if (tmp_callable) { return python_call(tmp_callable, PyTuple_New(0), 0, NULL); } } return PyDict_GetItemString(wsgi_dict, quick_callable); }
PyObject *py_uwsgi_gevent_graceful(PyObject *self, PyObject *args) { int running_cores = 0; int rounds = 0; uwsgi_log("Gracefully killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid); uwsgi.workers[uwsgi.mywid].manage_next_request = 0; uwsgi_log_verbose("stopping gevent signals watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid); PyObject_CallMethod(ugevent.my_signal_watcher, "stop", NULL); PyObject_CallMethod(ugevent.signal_watcher, "stop", NULL); uwsgi_log_verbose("stopping gevent sockets watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid); int i,count = uwsgi_count_sockets(uwsgi.sockets); for(i=0;i<count;i++) { PyObject_CallMethod(ugevent.watchers[i], "stop", NULL); } uwsgi_log_verbose("main gevent watchers stopped for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid); retry: running_cores = 0; for(i=0;i<uwsgi.async;i++) { if (uwsgi.workers[uwsgi.mywid].cores[i].in_request) { struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[i].req; if (!rounds) { uwsgi_log_verbose("worker %d (pid: %d) core %d is managing \"%.*s %.*s\" for %.*s\n", uwsgi.mywid, uwsgi.mypid, i, wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri, wsgi_req->remote_addr_len, wsgi_req->remote_addr); } running_cores++; } } if (running_cores > 0) { uwsgi_log_verbose("waiting for %d running requests on worker %d (pid: %d)...\n", running_cores, uwsgi.mywid, uwsgi.mypid); PyObject *gevent_sleep_args = PyTuple_New(1); PyTuple_SetItem(gevent_sleep_args, 0, PyInt_FromLong(1)); PyObject *gswitch = python_call(ugevent.greenlet_switch, gevent_sleep_args, 0, NULL); Py_DECREF(gswitch); Py_DECREF(gevent_sleep_args); rounds++; goto retry; } if (!ugevent.wait_for_hub) { PyObject_CallMethod(ugevent.ctrl_gl, "kill", NULL); } Py_INCREF(Py_None); return Py_None; }
char *uwsgi_python_code_string(char *id, char *code, char *function, char *key, uint16_t keylen) { PyObject *cs_module = NULL; PyObject *cs_dict = NULL; UWSGI_GET_GIL; cs_module = PyImport_ImportModule(id); if (!cs_module) { PyErr_Clear(); cs_module = uwsgi_pyimport_by_filename(id, code); } if (!cs_module) { UWSGI_RELEASE_GIL; return NULL; } cs_dict = PyModule_GetDict(cs_module); if (!cs_dict) { PyErr_Print(); UWSGI_RELEASE_GIL; return NULL; } PyObject *func = PyDict_GetItemString(cs_dict, function); if (!func) { uwsgi_log("function %s not available in %s\n", function, code); PyErr_Print(); UWSGI_RELEASE_GIL; return NULL; } PyObject *args = PyTuple_New(1); PyTuple_SetItem(args, 0, PyString_FromStringAndSize(key, keylen)); PyObject *ret = python_call(func, args, 0, NULL); Py_DECREF(args); if (ret && PyString_Check(ret)) { char *val = PyString_AsString(ret); UWSGI_RELEASE_GIL; return val; } UWSGI_RELEASE_GIL; return NULL; }
PyObject *py_uwsgi_gevent_graceful(PyObject *self, PyObject *args) { uwsgi_log("Gracefully killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid); uwsgi.workers[uwsgi.mywid].manage_next_request = 0; uwsgi_log_verbose("stopping gevent signals watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid); PyObject_CallMethod(ugevent.my_signal_watcher, "stop", NULL); PyObject_CallMethod(ugevent.signal_watcher, "stop", NULL); uwsgi_log_verbose("stopping gevent sockets watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid); int i,count = uwsgi_count_sockets(uwsgi.sockets); for(i=0;i<count;i++) { PyObject_CallMethod(ugevent.watchers[i], "stop", NULL); } uwsgi_log_verbose("main gevent watchers stopped for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid); int running_cores = 0; for(i=0;i<uwsgi.async;i++) { if (uwsgi.workers[uwsgi.mywid].cores[i].in_request) { struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[i].req; uwsgi_log_verbose("worker %d (pid: %d) core %d is managing \"%.*s %.*s\" for %.*s\n", uwsgi.mywid, uwsgi.mypid, i, wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri, wsgi_req->remote_addr_len, wsgi_req->remote_addr); running_cores++; } } if (running_cores > 0) { uwsgi_log_verbose("waiting for %d running requests on worker %d (pid: %d)...\n", running_cores, uwsgi.mywid, uwsgi.mypid); } else { // no need to worry about freeing memory PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi"); if (uwsgi_dict) { PyObject *ae = PyDict_GetItemString(uwsgi_dict, "atexit"); if (ae) { python_call(ae, PyTuple_New(0), 0, NULL); } } } Py_INCREF(Py_None); return Py_None; }
uint16_t uwsgi_python_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) { UWSGI_GET_GIL; uint8_t i; char *rv; size_t rl; PyObject *pyargs = PyTuple_New(argc); PyObject *ret; if (!pyargs) return 0; for (i = 0; i < argc; i++) { PyTuple_SetItem(pyargs, i, PyString_FromStringAndSize(argv[i], argvs[i])); } ret = python_call((PyObject *) func, pyargs, 0, NULL); Py_DECREF(pyargs); if (ret) { if (PyString_Check(ret)) { rv = PyString_AsString(ret); rl = PyString_Size(ret); if (rl <= 65536) { memcpy(buffer, rv, rl); Py_DECREF(ret); UWSGI_RELEASE_GIL; return rl; } } Py_DECREF(ret); } if (PyErr_Occurred()) PyErr_Print(); UWSGI_RELEASE_GIL; return 0; }
PyObject *py_uwsgi_gevent_main(PyObject * self, PyObject * args) { struct wsgi_request *wsgi_req = find_first_available_wsgi_req(); if (wsgi_req == NULL) { uwsgi_log("async queue is full !!!\n"); goto clear; } uwsgi.wsgi_req = wsgi_req; // fill wsgi_request structure wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi.sockets ); // mark core as used uwsgi.core[wsgi_req->async_id]->in_request = 1; gettimeofday(&wsgi_req->start_of_request, NULL); // enter harakiri mode if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) { set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]); } // accept the connection if (wsgi_req_simple_accept(wsgi_req, uwsgi.sockets->fd)) { uwsgi_close_request(wsgi_req); free_req_queue; goto clear; } // hack to easily pass wsgi_req pointer to the greenlet PyTuple_SetItem(ugevent.greenlet_args, 1, PyLong_FromLong((long)wsgi_req)); // spawn the request greenlet PyObject *new_gl = python_call(ugevent.spawn, ugevent.greenlet_args, 0, NULL); Py_DECREF(new_gl); clear: Py_INCREF(Py_None); return Py_None; }
void *uwsgi_request_subhandler_web3(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) { PyObject *zero; int i; PyObject *pydictkey, *pydictvalue; char *path_info; for (i = 0; i < wsgi_req->var_cnt; i += 2) { #ifdef UWSGI_DEBUG uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base); #endif #ifdef PYTHREE pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, NULL); pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL); #else pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len); pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len); #endif PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue); Py_DECREF(pydictkey); Py_DECREF(pydictvalue); } if (wsgi_req->uh->modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) { wsgi_req->uh->modifier1 = python_plugin.modifier1; pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME"); if (pydictkey) { if (PyString_Check(pydictkey)) { pydictvalue = PyDict_GetItemString(wsgi_req->async_environ, "PATH_INFO"); if (pydictvalue) { if (PyString_Check(pydictvalue)) { path_info = PyString_AsString(pydictvalue); PyDict_SetItemString(wsgi_req->async_environ, "PATH_INFO", PyString_FromString(path_info + PyString_Size(pydictkey))); } } } } } // create wsgi.input custom object wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType); ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req; PyDict_SetItemString(wsgi_req->async_environ, "web3.input", wsgi_req->async_input); PyDict_SetItemString(wsgi_req->async_environ, "web3.version", wi->gateway_version); zero = PyFile_FromFile(stderr, "web3_input", "w", NULL); PyDict_SetItemString(wsgi_req->async_environ, "web3.errors", zero); Py_DECREF(zero); PyDict_SetItemString(wsgi_req->async_environ, "web3.run_once", Py_False); PyDict_SetItemString(wsgi_req->async_environ, "web3.multithread", Py_False); if (uwsgi.numproc == 1) { PyDict_SetItemString(wsgi_req->async_environ, "web3.multiprocess", Py_False); } else { PyDict_SetItemString(wsgi_req->async_environ, "web3.multiprocess", Py_True); } if (wsgi_req->scheme_len > 0) { zero = UWSGI_PYFROMSTRINGSIZE(wsgi_req->scheme, wsgi_req->scheme_len); } else if (wsgi_req->https_len > 0) { if (!strncasecmp(wsgi_req->https, "on", 2) || wsgi_req->https[0] == '1') { zero = UWSGI_PYFROMSTRING("https"); } else { zero = UWSGI_PYFROMSTRING("http"); } } else { zero = UWSGI_PYFROMSTRING("http"); } PyDict_SetItemString(wsgi_req->async_environ, "web3.url_scheme", zero); Py_DECREF(zero); wsgi_req->async_app = wi->callable; // export .env only in non-threaded mode if (uwsgi.threads < 2) { PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ); } PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version); if (uwsgi.cores > 1) { PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", PyInt_FromLong(wsgi_req->async_id)); } PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node); // call if (PyTuple_GetItem(wsgi_req->async_args, 0) != wsgi_req->async_environ) { if (PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ)) { uwsgi_log_verbose("unable to set environ to the python application callable, consider using the holy env allocator\n"); return NULL; } } return python_call(wsgi_req->async_app, wsgi_req->async_args, uwsgi.catch_exceptions, wsgi_req); }
int uwsgi_python_spooler(char *filename, char *buf, uint16_t len, char *body, size_t body_len) { static int random_seed_reset = 0; UWSGI_GET_GIL; PyObject *spool_dict = PyDict_New(); PyObject *spool_func, *pyargs, *ret; if (!random_seed_reset) { uwsgi_python_reset_random_seed(); random_seed_reset = 1; } if (!up.embedded_dict) { // ignore UWSGI_RELEASE_GIL; return 0; } spool_func = PyDict_GetItemString(up.embedded_dict, "spooler"); if (!spool_func) { // ignore UWSGI_RELEASE_GIL; return 0; } if (uwsgi_hooked_parse(buf, len, uwsgi_python_add_item, spool_dict)) { // malformed packet, destroy it UWSGI_RELEASE_GIL; return -2; } pyargs = PyTuple_New(1); PyDict_SetItemString(spool_dict, "spooler_task_name", PyString_FromString(filename)); if (body && body_len > 0) { PyDict_SetItemString(spool_dict, "body", PyString_FromStringAndSize(body, body_len)); } PyTuple_SetItem(pyargs, 0, spool_dict); ret = python_call(spool_func, pyargs, 0, NULL); if (ret) { if (!PyInt_Check(ret)) { // error, retry UWSGI_RELEASE_GIL; return -1; } int retval = (int) PyInt_AsLong(ret); UWSGI_RELEASE_GIL; return retval; } if (PyErr_Occurred()) PyErr_Print(); // error, retry UWSGI_RELEASE_GIL; return -1; }
void *uwsgi_request_subhandler_pump(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) { PyObject *zero; int i; PyObject *pydictkey, *pydictvalue; char *port = memchr(wsgi_req->host, ':', wsgi_req->host_len); if (port) { zero = PyString_FromStringAndSize(wsgi_req->host, (port-wsgi_req->host)); PyDict_SetItemString(wsgi_req->async_environ, "server_name", zero); Py_DECREF(zero); zero = PyString_FromStringAndSize(port, wsgi_req->host_len-((port+1)-wsgi_req->host)); PyDict_SetItemString(wsgi_req->async_environ, "server_port", zero); Py_DECREF(zero); } else { zero = PyString_FromStringAndSize(wsgi_req->host, wsgi_req->host_len); PyDict_SetItemString(wsgi_req->async_environ, "server_name", zero); Py_DECREF(zero); zero = PyString_FromStringAndSize("80", 2); PyDict_SetItemString(wsgi_req->async_environ, "server_port", zero); Py_DECREF(zero); } zero = PyString_FromStringAndSize(wsgi_req->remote_addr, wsgi_req->remote_addr_len); PyDict_SetItemString(wsgi_req->async_environ, "remote_addr", zero); Py_DECREF(zero); zero = PyString_FromStringAndSize(wsgi_req->path_info, wsgi_req->path_info_len); PyDict_SetItemString(wsgi_req->async_environ, "uri", zero); Py_DECREF(zero); if (wsgi_req->query_string_len > 0) { zero = PyString_FromStringAndSize(wsgi_req->query_string, wsgi_req->query_string_len); PyDict_SetItemString(wsgi_req->async_environ, "query_string", zero); Py_DECREF(zero); } zero = PyString_FromStringAndSize(uwsgi_lower(wsgi_req->method, wsgi_req->method_len), wsgi_req->method_len); PyDict_SetItemString(wsgi_req->async_environ, "method", zero); Py_DECREF(zero); if (wsgi_req->post_cl > 0) { PyDict_SetItemString(wsgi_req->async_environ, "content_length", PyInt_FromLong(wsgi_req->post_cl)); if (wsgi_req->content_type_len > 0) { zero = PyString_FromStringAndSize(wsgi_req->content_type, wsgi_req->content_type_len); PyDict_SetItemString(wsgi_req->async_environ, "content_type", zero); Py_DECREF(zero); } } PyObject *headers = PyDict_New(); for (i = 0; i < wsgi_req->var_cnt; i += 2) { #ifdef UWSGI_DEBUG uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base); #endif if (wsgi_req->hvec[i].iov_len < 6) continue; if (!uwsgi_startswith(wsgi_req->hvec[i].iov_base, "HTTP_", 5)) { (void) uwsgi_lower(wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5); #ifdef PYTHREE pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5, NULL); pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL); #else pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5); pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len); #endif PyObject *old_value = PyDict_GetItem(headers, pydictkey); if (old_value) { if (PyString_Check(old_value)) { PyObject *new_value = PyList_New(0); PyList_Append(new_value, old_value); old_value = new_value; PyDict_SetItem(headers, pydictkey, old_value); Py_DECREF(old_value); } PyList_Append(old_value, pydictvalue); } else { PyDict_SetItem(headers, pydictkey, pydictvalue); } Py_DECREF(pydictkey); Py_DECREF(pydictvalue); } } PyDict_SetItemString(wsgi_req->async_environ, "headers", headers); Py_DECREF(headers); // create wsgi.input custom object wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType); ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req; PyDict_SetItemString(wsgi_req->async_environ, "body", wsgi_req->async_input); if (wsgi_req->scheme_len > 0) { zero = PyString_FromStringAndSize(wsgi_req->scheme, wsgi_req->scheme_len); } else if (wsgi_req->https_len > 0) { if (!strncasecmp(wsgi_req->https, "on", 2) || wsgi_req->https[0] == '1') { zero = PyString_FromString("https"); } else { zero = PyString_FromString("http"); } } else { zero = PyString_FromString("http"); } PyDict_SetItemString(wsgi_req->async_environ, "scheme", zero); Py_DECREF(zero); wsgi_req->async_app = wi->callable; // export .env only in non-threaded mode if (uwsgi.threads < 2) { PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ); } PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version); if (uwsgi.cores > 1) { PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", PyInt_FromLong(wsgi_req->async_id)); } 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); }
void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) { PyObject *zero; int i; PyObject *pydictkey, *pydictvalue; char *path_info; for (i = 0; i < wsgi_req->var_cnt; i += 2) { #ifdef UWSGI_DEBUG uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base); #endif #ifdef PYTHREE pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, NULL); pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL); #else pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len); pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len); #endif #ifdef UWSGI_DEBUG uwsgi_log("%p %d %p %d\n", pydictkey, wsgi_req->hvec[i].iov_len, pydictvalue, wsgi_req->hvec[i + 1].iov_len); #endif PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue); Py_DECREF(pydictkey); Py_DECREF(pydictvalue); } if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) { wsgi_req->uh.modifier1 = 0; pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME"); if (pydictkey) { if (PyString_Check(pydictkey)) { pydictvalue = PyDict_GetItemString(wsgi_req->async_environ, "PATH_INFO"); if (pydictvalue) { if (PyString_Check(pydictvalue)) { path_info = PyString_AsString(pydictvalue); PyDict_SetItemString(wsgi_req->async_environ, "PATH_INFO", PyString_FromString(path_info + PyString_Size(pydictkey))); } } } } } // if async_post is mapped as a file, directly use it as wsgi.input if (wsgi_req->async_post) { #ifdef PYTHREE wsgi_req->async_input = PyFile_FromFd(fileno((FILE *)wsgi_req->async_post), "wsgi_input", "rb", 0, NULL, NULL, NULL, 0); #else wsgi_req->async_input = PyFile_FromFile(wsgi_req->async_post, "wsgi_input", "r", NULL); #endif } else { // create wsgi.input custom object wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType); ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req; ((uwsgi_Input*)wsgi_req->async_input)->pos = 0; ((uwsgi_Input*)wsgi_req->async_input)->readline_pos = 0; ((uwsgi_Input*)wsgi_req->async_input)->readline_max_size = 0; } PyDict_SetItemString(wsgi_req->async_environ, "wsgi.input", wsgi_req->async_input); #ifdef UWSGI_SENDFILE PyDict_SetItemString(wsgi_req->async_environ, "wsgi.file_wrapper", wi->sendfile); #endif #ifdef UWSGI_ASYNC if (uwsgi.async > 1) { PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.readable", wi->eventfd_read); PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.writable", wi->eventfd_write); PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.timeout", Py_None); } #endif PyDict_SetItemString(wsgi_req->async_environ, "wsgi.version", wi->gateway_version); zero = PyFile_FromFile(stderr, "wsgi_errors", "w", NULL); PyDict_SetItemString(wsgi_req->async_environ, "wsgi.errors", zero); Py_DECREF(zero); PyDict_SetItemString(wsgi_req->async_environ, "wsgi.run_once", Py_False); if (uwsgi.threads > 1) { PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multithread", Py_True); } else { PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multithread", Py_False); } if (uwsgi.numproc == 1) { PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multiprocess", Py_False); } else { PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multiprocess", Py_True); } if (wsgi_req->scheme_len > 0) { zero = UWSGI_PYFROMSTRINGSIZE(wsgi_req->scheme, wsgi_req->scheme_len); } else if (wsgi_req->https_len > 0) { if (!strncasecmp(wsgi_req->https, "on", 2) || wsgi_req->https[0] == '1') { zero = UWSGI_PYFROMSTRING("https"); } else { zero = UWSGI_PYFROMSTRING("http"); } } else { zero = UWSGI_PYFROMSTRING("http"); } PyDict_SetItemString(wsgi_req->async_environ, "wsgi.url_scheme", zero); Py_DECREF(zero); wsgi_req->async_app = wi->callable; // export .env only in non-threaded mode if (uwsgi.threads < 2) { PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ); } PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version); if (uwsgi.cores > 1) { zero = PyInt_FromLong(wsgi_req->async_id); PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", zero); Py_DECREF(zero); } // cache this ? if (uwsgi.cluster_fd >= 0) { zero = PyString_FromString(uwsgi.cluster); PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster", zero); Py_DECREF(zero); zero = PyString_FromString(uwsgi.hostname); PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster_node", zero); Py_DECREF(zero); } 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); }
PyObject *uwsgi_paste_loader(void *arg1) { char *paste = (char *) arg1; PyObject *paste_module, *paste_dict, *paste_loadapp; PyObject *paste_arg, *paste_app; uwsgi_log( "Loading paste environment: %s\n", paste); if (up.paste_logger) { PyObject *paste_logger_dict = get_uwsgi_pydict("paste.script.util.logging_config"); if (paste_logger_dict) { PyObject *paste_logger_fileConfig = PyDict_GetItemString(paste_logger_dict, "fileConfig"); if (paste_logger_fileConfig) { PyObject *paste_logger_arg = PyTuple_New(1); if (!paste_logger_arg) { PyErr_Print(); exit(UWSGI_FAILED_APP_CODE); } PyTuple_SetItem(paste_logger_arg, 0, UWSGI_PYFROMSTRING(paste+7)); if (python_call(paste_logger_fileConfig, paste_logger_arg, 0, NULL)) { PyErr_Print(); } } } } paste_module = PyImport_ImportModule("paste.deploy"); if (!paste_module) { PyErr_Print(); exit(UWSGI_FAILED_APP_CODE); } paste_dict = PyModule_GetDict(paste_module); if (!paste_dict) { PyErr_Print(); exit(UWSGI_FAILED_APP_CODE); } paste_loadapp = PyDict_GetItemString(paste_dict, "loadapp"); if (!paste_loadapp) { PyErr_Print(); exit(UWSGI_FAILED_APP_CODE); } paste_arg = PyTuple_New(1); if (!paste_arg) { PyErr_Print(); exit(UWSGI_FAILED_APP_CODE); } if (PyTuple_SetItem(paste_arg, 0, UWSGI_PYFROMSTRING(paste))) { PyErr_Print(); exit(UWSGI_FAILED_APP_CODE); } paste_app = PyEval_CallObject(paste_loadapp, paste_arg); if (!paste_app) { PyErr_Print(); exit(UWSGI_FAILED_APP_CODE); } return paste_app; }
static void gevent_loop() { if (!uwsgi.has_threads && uwsgi.mywid == 1) { uwsgi_log("!!! Running gevent without threads IS NOT recommended, enable them with --enable-threads !!!\n"); } if (uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] < 30) { uwsgi_log("!!! Running gevent with a socket-timeout lower than 30 seconds is not recommended, tune it with --socket-timeout !!!\n"); } // get the GIL UWSGI_GET_GIL up.gil_get = gil_gevent_get; up.gil_release = gil_gevent_release; uwsgi.wait_write_hook = uwsgi_gevent_wait_write_hook; uwsgi.wait_read_hook = uwsgi_gevent_wait_read_hook; struct uwsgi_socket *uwsgi_sock = uwsgi.sockets; if (uwsgi.async < 2) { uwsgi_log("the gevent loop engine requires async mode (--async <n>)\n"); exit(1); } uwsgi.current_wsgi_req = uwsgi_gevent_current_wsgi_req; PyObject *gevent_dict = get_uwsgi_pydict("gevent"); if (!gevent_dict) uwsgi_pyexit; PyObject *gevent_version = PyDict_GetItemString(gevent_dict, "version_info"); if (!gevent_version) uwsgi_pyexit; if (PyInt_AsLong(PyTuple_GetItem(gevent_version, 0)) < 1) { uwsgi_log("uWSGI requires at least gevent 1.x version\n"); exit(1); } ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn"); if (!ugevent.spawn) uwsgi_pyexit; ugevent.signal = PyDict_GetItemString(gevent_dict, "signal"); if (!ugevent.signal) uwsgi_pyexit; ugevent.greenlet_switch = PyDict_GetItemString(gevent_dict, "sleep"); if (!ugevent.greenlet_switch) uwsgi_pyexit; ugevent.greenlet_switch_args = PyTuple_New(0); Py_INCREF(ugevent.greenlet_switch_args); PyObject *gevent_get_hub = PyDict_GetItemString(gevent_dict, "get_hub"); ugevent.hub = python_call(gevent_get_hub, PyTuple_New(0), 0, NULL); if (!ugevent.hub) uwsgi_pyexit; ugevent.get_current = PyDict_GetItemString(gevent_dict, "getcurrent"); if (!ugevent.get_current) uwsgi_pyexit; ugevent.get_current_args = PyTuple_New(0); Py_INCREF(ugevent.get_current_args); ugevent.hub_loop = PyObject_GetAttrString(ugevent.hub, "loop"); if (!ugevent.hub_loop) uwsgi_pyexit; // main greenlet waiting for connection (one greenlet per-socket) PyObject *uwsgi_gevent_main = PyCFunction_New(uwsgi_gevent_main_def, NULL); Py_INCREF(uwsgi_gevent_main); // greenlet to run at each request PyObject *uwsgi_request_greenlet = PyCFunction_New(uwsgi_gevent_request_def, NULL); Py_INCREF(uwsgi_request_greenlet); // pre-fill the greenlet args ugevent.greenlet_args = PyTuple_New(2); PyTuple_SetItem(ugevent.greenlet_args, 0, uwsgi_request_greenlet); if (uwsgi.signal_socket > -1) { // and these are the watcher for signal sockets ugevent.signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.signal_socket, 1); if (!ugevent.signal_watcher) uwsgi_pyexit; ugevent.my_signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.my_signal_socket, 1); if (!ugevent.my_signal_watcher) uwsgi_pyexit; PyObject *uwsgi_greenlet_signal = PyCFunction_New(uwsgi_gevent_signal_def, NULL); Py_INCREF(uwsgi_greenlet_signal); PyObject *uwsgi_greenlet_my_signal = PyCFunction_New(uwsgi_gevent_my_signal_def, NULL); Py_INCREF(uwsgi_greenlet_my_signal); PyObject *uwsgi_greenlet_signal_handler = PyCFunction_New(uwsgi_gevent_signal_handler_def, NULL); Py_INCREF(uwsgi_greenlet_signal_handler); ugevent.signal_args = PyTuple_New(2); PyTuple_SetItem(ugevent.signal_args, 0, uwsgi_greenlet_signal_handler); // start the two signal watchers if (!PyObject_CallMethod(ugevent.signal_watcher, "start", "O", uwsgi_greenlet_signal)) uwsgi_pyexit; if (!PyObject_CallMethod(ugevent.my_signal_watcher, "start", "O", uwsgi_greenlet_my_signal)) uwsgi_pyexit; } // start a greenlet for each socket ugevent.watchers = uwsgi_malloc(sizeof(PyObject *) * uwsgi_count_sockets(uwsgi.sockets)); int i = 0; while(uwsgi_sock) { // this is the watcher for server socket ugevent.watchers[i] = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi_sock->fd, 1); if (!ugevent.watchers[i]) uwsgi_pyexit; // start the main greenlet PyObject_CallMethod(ugevent.watchers[i], "start", "Ol", uwsgi_gevent_main,(long)uwsgi_sock); uwsgi_sock = uwsgi_sock->next; i++; } // patch goodbye_cruel_world uwsgi.gbcw_hook = uwsgi_gevent_gbcw; // map SIGHUP with gevent.signal PyObject *ge_signal_tuple = PyTuple_New(2); PyTuple_SetItem(ge_signal_tuple, 0, PyInt_FromLong(SIGHUP)); PyObject *uwsgi_gevent_unix_signal_handler = PyCFunction_New(uwsgi_gevent_unix_signal_handler_def, NULL); Py_INCREF(uwsgi_gevent_unix_signal_handler); PyTuple_SetItem(ge_signal_tuple, 1, uwsgi_gevent_unix_signal_handler); python_call(ugevent.signal, ge_signal_tuple, 0, NULL); for(;;) { if (!PyObject_CallMethod(ugevent.hub, "join", NULL)) { PyErr_Print(); } else { break; } } if (uwsgi.workers[uwsgi.mywid].manage_next_request == 0) { uwsgi_log("goodbye to the gevent Hub on worker %d (pid: %d)\n", uwsgi.mywid, uwsgi.mypid); if (ugevent.destroy) { exit(0); } exit(UWSGI_RELOAD_CODE); } uwsgi_log("the gevent Hub is no more :(\n"); }
void gevent_loop() { if (!uwsgi.has_threads && uwsgi.mywid == 1) { uwsgi_log("!!! Running gevent without threads IS NOT recommended, enable them with --enable-threads !!!\n"); } // get the GIL UWSGI_GET_GIL // ..then reset GIL subsystem as noop (gevent IO will take care of it...) up.gil_get = gil_fake_get; up.gil_release = gil_fake_release; struct uwsgi_socket *uwsgi_sock = uwsgi.sockets; if (uwsgi.async < 2) { uwsgi_log("the gevent loop engine requires async mode (--async <n>)\n"); exit(1); } uwsgi.current_wsgi_req = uwsgi_gevent_current_wsgi_req; PyObject *gevent_dict = get_uwsgi_pydict("gevent"); if (!gevent_dict) uwsgi_pyexit; PyObject *gevent_version = PyDict_GetItemString(gevent_dict, "version_info"); if (!gevent_version) uwsgi_pyexit; if (PyInt_AsLong(PyTuple_GetItem(gevent_version, 0)) < 1) { uwsgi_log("uWSGI requires at least gevent 1.x version\n"); exit(1); } ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn"); if (!ugevent.spawn) uwsgi_pyexit; ugevent.greenlet_switch = PyDict_GetItemString(gevent_dict, "sleep"); if (!ugevent.greenlet_switch) uwsgi_pyexit; ugevent.greenlet_switch_args = PyTuple_New(0); Py_INCREF(ugevent.greenlet_switch_args); PyObject *gevent_get_hub = PyDict_GetItemString(gevent_dict, "get_hub"); ugevent.hub = python_call(gevent_get_hub, PyTuple_New(0), 0, NULL); if (!ugevent.hub) uwsgi_pyexit; ugevent.get_current = PyDict_GetItemString(gevent_dict, "getcurrent"); if (!ugevent.get_current) uwsgi_pyexit; ugevent.get_current_args = PyTuple_New(0); Py_INCREF(ugevent.get_current_args); ugevent.hub_loop = PyObject_GetAttrString(ugevent.hub, "loop"); if (!ugevent.hub_loop) uwsgi_pyexit; // this is the watcher for server socket PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi_sock->fd, 1); if (!watcher) uwsgi_pyexit; // main greenlet waiting for connection PyObject *uwsgi_gevent_main = PyCFunction_New(uwsgi_gevent_main_def, NULL); Py_INCREF(uwsgi_gevent_main); // greenlet to run at each request PyObject *uwsgi_request_greenlet = PyCFunction_New(uwsgi_gevent_request_def, NULL); Py_INCREF(uwsgi_request_greenlet); // pre-fill the greenlet args ugevent.greenlet_args = PyTuple_New(2); PyTuple_SetItem(ugevent.greenlet_args, 0, uwsgi_request_greenlet); if (uwsgi.signal_socket > -1) { // and these are the watcher for signal sockets PyObject *signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.signal_socket, 1); if (!signal_watcher) uwsgi_pyexit; PyObject *my_signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.my_signal_socket, 1); if (!my_signal_watcher) uwsgi_pyexit; PyObject *uwsgi_greenlet_signal = PyCFunction_New(uwsgi_gevent_signal_def, NULL); Py_INCREF(uwsgi_greenlet_signal); PyObject *uwsgi_greenlet_my_signal = PyCFunction_New(uwsgi_gevent_my_signal_def, NULL); Py_INCREF(uwsgi_greenlet_my_signal); PyObject *uwsgi_greenlet_signal_handler = PyCFunction_New(uwsgi_gevent_signal_handler_def, NULL); Py_INCREF(uwsgi_greenlet_signal_handler); ugevent.signal_args = PyTuple_New(2); PyTuple_SetItem(ugevent.signal_args, 0, uwsgi_greenlet_signal_handler); // start the two signal watchers if (!PyObject_CallMethod(signal_watcher, "start", "O", uwsgi_greenlet_signal)) uwsgi_pyexit; if (!PyObject_CallMethod(my_signal_watcher, "start", "O", uwsgi_greenlet_my_signal)) uwsgi_pyexit; } // start the main greenlet PyObject_CallMethod(watcher, "start", "O", uwsgi_gevent_main); if (!PyObject_CallMethod(ugevent.hub, "join", NULL)) { PyErr_Print(); } uwsgi_log("the gevent Hub is no more :(\n"); }
PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) { PyObject *py_wsgi_req = PyTuple_GetItem(args, 0); struct wsgi_request *wsgi_req = (struct wsgi_request *) PyLong_AsLong(py_wsgi_req); PyObject *greenlet_switch = NULL; PyObject *current_greenlet = GET_CURRENT_GREENLET; // another hack to retrieve the current wsgi_req; PyObject_SetAttrString(current_greenlet, "uwsgi_wsgi_req", py_wsgi_req); // if in edge-triggered mode read from socket now !!! if (wsgi_req->socket->edge_trigger) { int status = wsgi_req->socket->proto(wsgi_req); if (status < 0) { goto end2; } goto request; } greenlet_switch = PyObject_GetAttrString(current_greenlet, "switch"); for(;;) { int ret = uwsgi.wait_read_hook(wsgi_req->fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); wsgi_req->switches++; if (ret <= 0) { goto end; } int status = wsgi_req->socket->proto(wsgi_req); if (status < 0) { goto end; } else if (status == 0) { break; } } request: #ifdef UWSGI_ROUTING if (uwsgi_apply_routes(wsgi_req) == UWSGI_ROUTE_BREAK) { goto end; } #endif for(;;) { if (uwsgi.p[wsgi_req->uh->modifier1]->request(wsgi_req) <= UWSGI_OK) { goto end; } wsgi_req->switches++; // switch after each yield GEVENT_SWITCH; } end: Py_DECREF(greenlet_switch); end2: Py_DECREF(current_greenlet); uwsgi_close_request(wsgi_req); free_req_queue; if (uwsgi.workers[uwsgi.mywid].manage_next_request == 0) { int running_cores = 0; int i; for(i=0;i<uwsgi.async;i++) { if (uwsgi.workers[uwsgi.mywid].cores[i].in_request) { running_cores++; } } if (running_cores == 0) { // no need to worry about freeing memory PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi"); if (uwsgi_dict) { PyObject *ae = PyDict_GetItemString(uwsgi_dict, "atexit"); if (ae) { python_call(ae, PyTuple_New(0), 0, NULL); } } } } Py_INCREF(Py_None); return Py_None; }
void gevent_loop() { struct uwsgi_socket *uwsgi_sock = uwsgi.sockets; if (uwsgi.async < 2) { uwsgi_log("the gevent loop engine requires async mode (--async <n>)\n"); exit(1); } PyObject *gevent_dict = get_uwsgi_pydict("gevent"); if (!gevent_dict) uwsgi_pyexit; PyObject *gevent_version = PyDict_GetItemString(gevent_dict, "version_info"); if (!gevent_version) uwsgi_pyexit; if (PyInt_AsLong(PyTuple_GetItem(gevent_version, 0)) < 1) { uwsgi_log("uWSGI requires at least gevent 1.x version\n"); exit(1); } ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn"); if (!ugevent.spawn) uwsgi_pyexit; ugevent.greenlet_switch = PyDict_GetItemString(gevent_dict, "sleep"); if (!ugevent.greenlet_switch) uwsgi_pyexit; ugevent.greenlet_switch_args = PyTuple_New(0); Py_INCREF(ugevent.greenlet_switch_args); PyObject *gevent_get_hub = PyDict_GetItemString(gevent_dict, "get_hub"); ugevent.hub = python_call(gevent_get_hub, PyTuple_New(0), 0, NULL); if (!ugevent.hub) uwsgi_pyexit; ugevent.get_current = PyDict_GetItemString(gevent_dict, "getcurrent"); if (!ugevent.get_current) uwsgi_pyexit; ugevent.get_current_args = PyTuple_New(0); Py_INCREF(ugevent.get_current_args); ugevent.hub_loop = PyObject_GetAttrString(ugevent.hub, "loop"); if (!ugevent.hub_loop) uwsgi_pyexit; // this is the watcher for server socket PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi_sock->fd, 1); if (!watcher) uwsgi_pyexit; // main greenlet waiting for connection PyObject *uwsgi_gevent_main = PyCFunction_New(uwsgi_gevent_main_def, NULL); Py_INCREF(uwsgi_gevent_main); // greenlet to run at each request PyObject *uwsgi_request_greenlet = PyCFunction_New(uwsgi_gevent_request_def, NULL); Py_INCREF(uwsgi_request_greenlet); // pre-fill the greenlet args ugevent.greenlet_args = PyTuple_New(2); PyTuple_SetItem(ugevent.greenlet_args, 0, uwsgi_request_greenlet); if (uwsgi.signal_socket > -1) { // and these are the watcher for signal sockets PyObject *signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.signal_socket, 1); if (!signal_watcher) uwsgi_pyexit; PyObject *my_signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.my_signal_socket, 1); if (!my_signal_watcher) uwsgi_pyexit; PyObject *uwsgi_greenlet_signal = PyCFunction_New(uwsgi_gevent_signal_def, NULL); Py_INCREF(uwsgi_greenlet_signal); PyObject *uwsgi_greenlet_my_signal = PyCFunction_New(uwsgi_gevent_my_signal_def, NULL); Py_INCREF(uwsgi_greenlet_my_signal); PyObject *uwsgi_greenlet_signal_handler = PyCFunction_New(uwsgi_gevent_signal_handler_def, NULL); Py_INCREF(uwsgi_greenlet_signal_handler); ugevent.signal_args = PyTuple_New(2); PyTuple_SetItem(ugevent.signal_args, 0, uwsgi_greenlet_signal_handler); // start the two signal watchers if (!PyObject_CallMethod(signal_watcher, "start", "O", uwsgi_greenlet_signal)) uwsgi_pyexit; if (!PyObject_CallMethod(my_signal_watcher, "start", "O", uwsgi_greenlet_my_signal)) uwsgi_pyexit; } // start the main greenlet PyObject_CallMethod(watcher, "start", "O", uwsgi_gevent_main); if (!PyObject_CallMethod(ugevent.hub, "join", NULL)) { PyErr_Print(); } uwsgi_log("the gevent Hub is no more :(\n"); }
PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) { PyObject *py_wsgi_req = PyTuple_GetItem(args, 0); struct wsgi_request *wsgi_req = (struct wsgi_request *) PyLong_AsLong(py_wsgi_req); PyObject *greenlet_switch = NULL; PyObject *current_greenlet = GET_CURRENT_GREENLET; // another hack to retrieve the current wsgi_req; PyObject_SetAttrString(current_greenlet, "uwsgi_wsgi_req", py_wsgi_req); // if in edge-triggered mode read from socket now !!! if (wsgi_req->socket->edge_trigger) { int status = wsgi_req->socket->proto(wsgi_req); if (status < 0) { goto end; } goto request; } greenlet_switch = PyObject_GetAttrString(current_greenlet, "switch"); for(;;) { int ret = uwsgi.wait_read_hook(wsgi_req->fd, uwsgi.socket_timeout); wsgi_req->switches++; if (ret <= 0) { goto end; } int status = wsgi_req->socket->proto(wsgi_req); if (status < 0) { goto end; } else if (status == 0) { break; } } request: #ifdef UWSGI_ROUTING if (uwsgi_apply_routes(wsgi_req) == UWSGI_ROUTE_BREAK) { goto end; } #endif for(;;) { if (uwsgi.p[wsgi_req->uh->modifier1]->request(wsgi_req) <= UWSGI_OK) { goto end; } wsgi_req->switches++; // switch after each yield GEVENT_SWITCH; } end: if (greenlet_switch) { Py_DECREF(greenlet_switch); } Py_DECREF(current_greenlet); uwsgi_close_request(wsgi_req); free_req_queue; if (uwsgi.workers[uwsgi.mywid].manage_next_request == 0) { int running_cores = 0; int i; for(i=0;i<uwsgi.async;i++) { if (uwsgi.workers[uwsgi.mywid].cores[i].in_request) { running_cores++; } } if (running_cores == 0) { // no need to worry about freeing memory PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi"); if (uwsgi_dict) { PyObject *ae = PyDict_GetItemString(uwsgi_dict, "atexit"); if (ae) { python_call(ae, PyTuple_New(0), 0, NULL); } } } } else { // If we stopped any watcher due to being out of async workers, restart it. int i = 0; struct uwsgi_socket *uwsgi_sock = uwsgi.sockets; for (; uwsgi_sock; uwsgi_sock = uwsgi_sock->next, ++i) { PyObject *py_watcher_active = PyObject_GetAttrString(ugevent.watchers[i], "active"); if (py_watcher_active && PyBool_Check(py_watcher_active) && !PyInt_AsLong(py_watcher_active)) { start_watcher(i, uwsgi_sock); } Py_XDECREF(py_watcher_active); } } Py_INCREF(Py_None); return Py_None; }