theading support improvements

This commit is contained in:
roberto@fiorenzo
2010-10-04 14:01:56 +02:00
parent 36c8a8c675
commit 074d0b95d1
10 changed files with 60 additions and 36 deletions
+15 -2
View File
@@ -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);
+2
View File
@@ -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 };
+4 -4
View File
@@ -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;i<uwsgi.async;i++) {
for(i=0;i<uwsgi.cores;i++) {
wi->wsgi_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;i<uwsgi.async;i++) {
for(i=0;i<uwsgi.cores;i++) {
wi->wsgi_args[i] = PyTuple_New(wi->argc);
if (!wi->wsgi_args[i]) {
uwsgi_log("unable to allocate new tuple for app args\n");
+1
View File
@@ -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();
+1 -1
View File
@@ -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
+15 -13
View File
@@ -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;i<uwsgi.cores;i++) {
uwsgi.async_hvec[i] = malloc(sizeof(struct iovec) * uwsgi.vec_size);
}
if (uwsgi.shared->options[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;i<uwsgi.threads-1;i++) {
for(i=1;i<uwsgi.threads;i++) {
int j = i;
a_thread = malloc(sizeof(pthread_t));
pthread_create(a_thread, &pa, simple_loop, (void *) &i);
uwsgi_log("started thread %d\n", i);
pthread_create(a_thread, &pa, simple_loop, (void *) j);
}
}
@@ -1626,15 +1635,8 @@ cycle:
}
else {
#endif
wsgi_req_setup(uwsgi.wsgi_req, 0);
if (wsgi_req_accept(uwsgi.wsgi_req)) {
continue;
}
if (wsgi_req_recv(uwsgi.wsgi_req)) {
continue;
}
int y = 0;
simple_loop((void *) y);
#ifdef UWSGI_ASYNC
}
+5 -4
View File
@@ -14,8 +14,8 @@
#define MAX_PYTHONPATH 64
#ifdef UWSGI_THREADING
#define uwsgi_get_gil() if (uwsgi.has_threads) PyEval_AcquireLock()
#define uwsgi_release_gil() if (uwsgi.has_threads) PyEval_ReleaseLock()
#define uwsgi_get_gil() if (uwsgi.has_threads) { PyEval_AcquireLock(); PyThreadState_Swap((PyThreadState *) pthread_getspecific(uwsgi.ut_save_key)); }
#define uwsgi_release_gil() if (uwsgi.has_threads) { pthread_setspecific(uwsgi.ut_save_key, (void *) PyThreadState_Swap(NULL)); PyEval_ReleaseLock();}
#else
#define uwsgi_get_gil()
#define uwsgi_release_gil()
@@ -554,7 +554,7 @@ struct uwsgi_server {
int vhost;
struct iovec *async_hvec;
struct iovec **async_hvec;
char **async_buf;
char **async_post_buf;
@@ -795,6 +795,7 @@ struct uwsgi_server {
int cores;
int threads;
pthread_key_t ut_key;
pthread_key_t ut_save_key;
};
struct uwsgi_cluster_node {
@@ -1115,7 +1116,7 @@ struct wsgi_request *current_wsgi_req(void);
inline struct wsgi_request *current_wsgi_req(void);
#endif
#else
#define current_wsgi_req() uwsgi.wsgi_req
#define current_wsgi_req() pthread_getspecific(uwsgi.ut_key)
#endif
void sanitize_args(void);
+13 -11
View File
@@ -99,6 +99,7 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
}
#endif
/* Standard WSGI request */
if (!wsgi_req->uh.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:
+2
View File
@@ -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) {
+2 -1
View File
@@ -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);
}