From 074d0b95d14b56261d211b9f7ca333f4faaa28bb Mon Sep 17 00:00:00 2001 From: "roberto@fiorenzo" Date: Mon, 4 Oct 2010 14:01:56 +0200 Subject: [PATCH] theading support improvements --- loop.c | 17 +++++++++++++++-- master.c | 2 ++ pyloader.c | 8 ++++---- pyutils.c | 1 + utils.c | 2 +- uwsgi.c | 28 +++++++++++++++------------- uwsgi.h | 9 +++++---- wsgi_handlers.c | 24 +++++++++++++----------- wsgi_headers.c | 2 ++ wsgi_subhandler.c | 3 ++- 10 files changed, 60 insertions(+), 36 deletions(-) diff --git a/loop.c b/loop.c index 24945246..9e59705a 100644 --- a/loop.c +++ b/loop.c @@ -4,11 +4,20 @@ extern struct uwsgi_server uwsgi; void *simple_loop(void *arg1) { - int *core_ptr = (int *) arg1; - int core_id = *core_ptr; + long core_id = (long) arg1; + PyThreadState *pts; struct wsgi_request *wsgi_req = uwsgi.wsgi_requests[core_id]; + pthread_setspecific(uwsgi.ut_key, (void *) wsgi_req); + + uwsgi_log("started core %d\n", core_id); + + if (core_id > 0) { + pts = PyThreadState_New(uwsgi.main_thread->interp); + pthread_setspecific(uwsgi.ut_save_key, (void *) pts); + } + while (uwsgi.workers[uwsgi.mywid].manage_next_request) { @@ -18,11 +27,15 @@ void *simple_loop(void *arg1) { continue; } + uwsgi_get_gil(); + if (wsgi_req_recv(wsgi_req)) { + uwsgi_release_gil(); continue; } uwsgi_close_request(wsgi_req); + uwsgi_release_gil(); } pthread_exit(NULL); diff --git a/master.c b/master.c index a6d54bc4..4a27f9d0 100644 --- a/master.c +++ b/master.c @@ -46,7 +46,9 @@ void master_loop(char **argv, char **environ) { #endif int i,j; +#ifdef UWSGI_UDP int rlen; +#endif struct timeval check_interval = {.tv_sec = 1,.tv_usec = 0 }; diff --git a/pyloader.c b/pyloader.c index 97e1a5e8..d37dfcad 100644 --- a/pyloader.c +++ b/pyloader.c @@ -105,13 +105,13 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, int ne } #ifdef UWSGI_ASYNC - wi->wsgi_environ = malloc(sizeof(PyObject*)*uwsgi.async); + wi->wsgi_environ = malloc(sizeof(PyObject*)*uwsgi.cores); if (!wi->wsgi_environ) { uwsgi_error("malloc()"); exit(1); } - for(i=0;iwsgi_environ[i] = PyDict_New(); if (!wi->wsgi_environ[i]) { uwsgi_log("unable to allocate new env dictionary for app\n"); @@ -171,13 +171,13 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, int ne } #ifdef UWSGI_ASYNC - wi->wsgi_args = malloc(sizeof(PyObject*)*uwsgi.async); + wi->wsgi_args = malloc(sizeof(PyObject*)*uwsgi.cores); if (!wi->wsgi_args) { uwsgi_error("malloc()"); exit(1); } - for(i=0;iwsgi_args[i] = PyTuple_New(wi->argc); if (!wi->wsgi_args[i]) { uwsgi_log("unable to allocate new tuple for app args\n"); diff --git a/pyutils.c b/pyutils.c index c76c4fdc..141afd32 100644 --- a/pyutils.c +++ b/pyutils.c @@ -12,6 +12,7 @@ PyObject *python_call(PyObject *callable, PyObject *args, int catch) { PyObject *pyret; pyret = PyEval_CallObject(callable, args); + if (PyErr_Occurred()) { if (!catch) { PyErr_Print(); diff --git a/utils.c b/utils.c index f0ee7eb7..89e189f4 100644 --- a/utils.c +++ b/utils.c @@ -380,7 +380,7 @@ void wsgi_req_setup(struct wsgi_request *wsgi_req, int async_id) { #ifdef UWSGI_ASYNC wsgi_req->async_waiting_fd = -1; #endif - wsgi_req->hvec = &uwsgi.async_hvec[wsgi_req->async_id]; + wsgi_req->hvec = uwsgi.async_hvec[wsgi_req->async_id]; wsgi_req->buffer = uwsgi.async_buf[wsgi_req->async_id]; #ifdef UWSGI_ROUTING diff --git a/uwsgi.c b/uwsgi.c index 4a778914..5b0a5209 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -968,6 +968,11 @@ int main(int argc, char *argv[], char *envp[]) { if (uwsgi.has_threads) { PyEval_InitThreads(); uwsgi_log("threads support enabled\n"); + if (pthread_key_create(&uwsgi.ut_save_key, NULL)) { + uwsgi_error("pthread_key_create()"); + exit(1); + } + pthread_setspecific(uwsgi.ut_save_key, (void *) PyThreadState_Get()); } #endif @@ -1437,12 +1442,16 @@ int main(int argc, char *argv[], char *envp[]) { - uwsgi.async_hvec = malloc((sizeof(struct iovec) * uwsgi.vec_size)*uwsgi.async); + uwsgi.async_hvec = malloc(sizeof(struct iovec*)*uwsgi.cores); if (uwsgi.async_hvec == NULL) { uwsgi_log( "unable to allocate memory for iovec.\n"); exit(1); } + for(i=0;ioptions[UWSGI_OPTION_HARAKIRI] > 0 && !uwsgi.master_process) { signal(SIGALRM, (void *) &harakiri); } @@ -1544,10 +1553,10 @@ int main(int argc, char *argv[], char *envp[]) { uwsgi_error("pthread_key_create()"); exit(1); } - for(i=0;iuh.pktsize) { uwsgi_log( "Invalid WSGI request. skip.\n"); @@ -117,6 +118,7 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { } } + if (!uwsgi.ignore_script_name) { if (!wsgi_req->script_name) @@ -147,9 +149,9 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { #endif ) { // a bit of magic: 1-1 = 0 / 0-1 = -1 - uwsgi_get_gil(); + //uwsgi_get_gil(); wsgi_req->app_id = init_uwsgi_app(LOADER_DYN, (void *) wsgi_req, wsgi_req, uwsgi.single_interpreter-1); - uwsgi_release_gil(); + //uwsgi_release_gil(); } } } @@ -181,9 +183,9 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { } // set the interpreter - uwsgi_get_gil(); + //uwsgi_get_gil(); PyThreadState_Swap(wi->interpreter); - uwsgi_release_gil(); + //uwsgi_release_gil(); if (wi->chdir) { #ifdef UWSGI_DEBUG uwsgi_debug("chdir to %s\n", wi->chdir); @@ -197,6 +199,7 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { wi->requests++; + if (wsgi_req->protocol_len < 5) { uwsgi_log( "INVALID PROTOCOL: %.*s\n", wsgi_req->protocol_len, wsgi_req->protocol); internal_server_error(wsgi_req->poll.fd, "invalid HTTP protocol !!!"); @@ -219,17 +222,16 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { wsgi_req->async_args = wi->wsgi_args; #endif - uwsgi_get_gil(); + //uwsgi_get_gil(); + Py_INCREF((PyObject *)wsgi_req->async_environ); 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, "ignore"); pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, "ignore"); @@ -242,7 +244,6 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { Py_DECREF(pydictvalue); } - if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) { pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME"); if (pydictkey) { @@ -263,9 +264,9 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { // set wsgi vars - uwsgi_release_gil(); if (uwsgi.post_buffering > 0 && wsgi_req->post_cl > (size_t) uwsgi.post_buffering) { + //uwsgi_release_gil(); wsgi_req->async_post = tmpfile(); if (!wsgi_req->async_post) { uwsgi_error("tmpfile()"); @@ -294,15 +295,16 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { post_remains -= post_chunk; } rewind(wsgi_req->async_post); + //uwsgi_get_gil(); } else { wsgi_req->async_post = fdopen(wsgi_req->poll.fd, "r"); } - uwsgi_get_gil(); wsgi_req->async_result = (*wi->request_subhandler)(wsgi_req, wi); + if (wsgi_req->async_result) { @@ -356,7 +358,7 @@ clear: PyThreadState_Swap(uwsgi.main_thread); } - uwsgi_release_gil(); + //uwsgi_release_gil(); clear2: diff --git a/wsgi_headers.c b/wsgi_headers.c index 5bc8c935..01678b8d 100644 --- a/wsgi_headers.c +++ b/wsgi_headers.c @@ -21,9 +21,11 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) { // use writev() // is a Web3 response ? + /* if (PyTuple_Size(args) == 3) { shift = 0; } + */ head = PyTuple_GetItem(args, 0+shift); if (!head) { diff --git a/wsgi_subhandler.c b/wsgi_subhandler.c index 2a6e46de..473d7a53 100644 --- a/wsgi_subhandler.c +++ b/wsgi_subhandler.c @@ -62,7 +62,7 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_ wsgi_req->async_app = wi->wsgi_callable ; - PyDict_SetItemString(uwsgi.embedded_dict, "env", wsgi_req->async_environ); + //PyDict_SetItemString(uwsgi.embedded_dict, "env", wsgi_req->async_environ); // TODO: fix here //PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.uwsgi.version", uwsgi_version); @@ -79,6 +79,7 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_ // 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); }