From e836272c07fa12e6b1e259b89de4689a98d4d076 Mon Sep 17 00:00:00 2001 From: Unbit Date: Fri, 3 Oct 2014 05:24:16 +0200 Subject: [PATCH] attempt to fix #732 --- core/offload.c | 7 ++++ plugins/python/python_plugin.c | 53 ++++++++++++++++------------- plugins/python/tracebacker.c | 61 ++++++++++++++++++++++++++++++++++ plugins/python/uwsgi_python.h | 2 ++ 4 files changed, 100 insertions(+), 23 deletions(-) diff --git a/core/offload.c b/core/offload.c index 5b8787f5..81816475 100644 --- a/core/offload.c +++ b/core/offload.c @@ -55,6 +55,9 @@ static int uwsgi_offload_enqueue(struct wsgi_request *wsgi_req, struct uwsgi_off } return -1; } +#ifdef UWSGI_DEBUG + uwsgi_log("[offload] created session %p\n", uor); +#endif return 0; } @@ -203,6 +206,10 @@ static void uwsgi_offload_close(struct uwsgi_thread *ut, struct uwsgi_offload_re } free(uor); + +#ifdef UWSGI_DEBUG + uwsgi_log("[offload] destroyed session %p\n", uor); +#endif } static void uwsgi_offload_append(struct uwsgi_thread *ut, struct uwsgi_offload_request *uor) { diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index 1a6f04e3..ebaa0f90 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -397,6 +397,7 @@ void uwsgi_python_post_fork() { PyErr_Clear(); if (uwsgi.mywid > 0) { + uwsgi_python_set_thread_name(0); if (up.auto_reload) { // spawn the reloader thread pthread_t par_tid; @@ -1270,11 +1271,39 @@ void uwsgi_python_enable_threads() { up.reset_ts = threaded_reset_ts; } + + uwsgi_log("python threads support enabled\n"); } +void uwsgi_python_set_thread_name(int core_id) { + // call threading.currentThread (taken from mod_wsgi, but removes DECREFs as thread in uWSGI are fixed) + PyObject *threading_module = PyImport_ImportModule("threading"); + if (threading_module) { + PyObject *threading_module_dict = PyModule_GetDict(threading_module); + if (threading_module_dict) { +#ifdef PYTHREE + PyObject *threading_current = PyDict_GetItemString(threading_module_dict, "current_thread"); +#else + PyObject *threading_current = PyDict_GetItemString(threading_module_dict, "currentThread"); +#endif + if (threading_current) { + PyObject *current_thread = PyEval_CallObject(threading_current, (PyObject *)NULL); + if (!current_thread) { + // ignore the error + PyErr_Clear(); + } + else { + PyObject_SetAttrString(current_thread, "name", PyString_FromFormat("uWSGIWorker%dCore%d", uwsgi.mywid, core_id)); + Py_INCREF(current_thread); + } + } + } + } +} + void uwsgi_python_init_thread(int core_id) { // set a new ThreadState for each thread @@ -1286,29 +1315,7 @@ void uwsgi_python_init_thread(int core_id) { uwsgi_log("python ThreadState %d = %p\n", core_id, pts); #endif UWSGI_GET_GIL; - // call threading.currentThread (taken from mod_wsgi, but removes DECREFs as thread in uWSGI are fixed) - PyObject *threading_module = PyImport_ImportModule("threading"); - if (threading_module) { - PyObject *threading_module_dict = PyModule_GetDict(threading_module); - if (threading_module_dict) { -#ifdef PYTHREE - PyObject *threading_current = PyDict_GetItemString(threading_module_dict, "current_thread"); -#else - PyObject *threading_current = PyDict_GetItemString(threading_module_dict, "currentThread"); -#endif - if (threading_current) { - PyObject *current_thread = PyEval_CallObject(threading_current, (PyObject *)NULL); - if (!current_thread) { - // ignore the error - PyErr_Clear(); - } - else { - PyObject_SetAttrString(current_thread, "name", PyString_FromFormat("uWSGIWorker%dCore%d", uwsgi.mywid, core_id)); - Py_INCREF(current_thread); - } - } - } - } + uwsgi_python_set_thread_name(core_id); UWSGI_RELEASE_GIL; diff --git a/plugins/python/tracebacker.c b/plugins/python/tracebacker.c index 542ef614..54308315 100644 --- a/plugins/python/tracebacker.c +++ b/plugins/python/tracebacker.c @@ -27,7 +27,18 @@ char *uwsgi_python_get_thread_name(PyObject *thread_id) { if (PyInt_AsLong(thread_ident) == PyInt_AsLong(thread_id)) { PyObject *thread_name = PyObject_GetAttrString(threads_list_next, "name"); if (!thread_name) goto clear2; +#ifdef PYTHREE + PyObject *thread_name_utf8 = PyUnicode_AsUTF8String(thread_name); + if (!thread_name_utf8) goto clear2; + char *name = NULL; + char *tmp_name = PyString_AsString(thread_name_utf8); + if (tmp_name) { + name = uwsgi_str(tmp_name); + Py_DECREF(thread_name_utf8); + } +#else char *name = PyString_AsString(thread_name); +#endif Py_DECREF(threads_list_next); Py_DECREF(threads_list_iter); Py_DECREF(threads_list); @@ -133,6 +144,9 @@ void *uwsgi_python_tracebacker_thread(void *foobar) { PyObject *st_items = PyIter_Next(stacktrace_iter); // we have the first traceback item while(st_items) { +#ifdef PYTHREE + int thread_name_need_free = 0; +#endif PyObject *st_filename = PyTuple_GetItem(st_items, 0); if (!st_filename) { Py_DECREF(st_items); goto next; } PyObject *st_lineno = PyTuple_GetItem(st_items, 1); @@ -149,12 +163,26 @@ void *uwsgi_python_tracebacker_thread(void *foobar) { if (!iov[1].iov_base) { iov[1].iov_base = ""; } +#ifdef PYTHREE + else { + thread_name_need_free = 1; + } +#endif iov[1].iov_len = strlen(iov[1].iov_base); iov[2].iov_base = " filename = "; iov[2].iov_len = 12; +#ifdef PYTHREE + PyObject *st_filename_utf8 = PyUnicode_AsUTF8String(st_filename); + if (!st_filename_utf8) { + if (thread_name_need_free) free(iov[1].iov_base); + goto next; + } + iov[3].iov_base = PyString_AsString(st_filename_utf8); +#else iov[3].iov_base = PyString_AsString(st_filename); +#endif iov[3].iov_len = strlen(iov[3].iov_base); iov[4].iov_base = " lineno = "; @@ -166,7 +194,17 @@ void *uwsgi_python_tracebacker_thread(void *foobar) { iov[6].iov_base = " function = "; iov[6].iov_len = 12 ; +#ifdef PYTHREE + PyObject *st_name_utf8 = PyUnicode_AsUTF8String(st_name); + if (!st_name_utf8) { + if (thread_name_need_free) free(iov[1].iov_base); + Py_DECREF(st_filename_utf8); + goto next; + } + iov[7].iov_base = PyString_AsString(st_name_utf8); +#else iov[7].iov_base = PyString_AsString(st_name); +#endif iov[7].iov_len = strlen(iov[7].iov_base); iov[8].iov_base = ""; @@ -178,10 +216,24 @@ void *uwsgi_python_tracebacker_thread(void *foobar) { iov[10].iov_base = "\n"; iov[10].iov_len = 1; +#ifdef PYTHREE + PyObject *st_line_utf8 = NULL; +#endif if (st_line) { iov[8].iov_base = " line = "; iov[8].iov_len = 8; +#ifdef PYTHREE + PyObject *st_line_utf8 = PyUnicode_AsUTF8String(st_line); + if (!st_line_utf8) { + if (thread_name_need_free) free(iov[1].iov_base); + Py_DECREF(st_filename_utf8); + Py_DECREF(st_name_utf8); + goto next; + } + iov[9].iov_base = PyString_AsString(st_line_utf8); +#else iov[9].iov_base = PyString_AsString(st_line); +#endif iov[9].iov_len = strlen(iov[9].iov_base); } @@ -192,6 +244,15 @@ void *uwsgi_python_tracebacker_thread(void *foobar) { // free the line_no free(iov[5].iov_base); Py_DECREF(st_items); +#ifdef PYTHREE + Py_DECREF(st_filename_utf8); + Py_DECREF(st_name_utf8); + if (st_line_utf8) { + Py_DECREF(st_line_utf8); + } + if (thread_name_need_free) + free(iov[1].iov_base); +#endif st_items = PyIter_Next(stacktrace_iter); } if (write(client_fd, "\n", 1) < 0) { diff --git a/plugins/python/uwsgi_python.h b/plugins/python/uwsgi_python.h index a2cc6e69..fb385658 100644 --- a/plugins/python/uwsgi_python.h +++ b/plugins/python/uwsgi_python.h @@ -299,6 +299,8 @@ int uwsgi_python_send_body(struct wsgi_request *, PyObject *); int uwsgi_request_python_raw(struct wsgi_request *); +void uwsgi_python_set_thread_name(int); + #define py_current_wsgi_req() current_wsgi_req();\ if (!wsgi_req) {\ return PyErr_Format(PyExc_SystemError, "you can call uwsgi api function only from the main callable");\