diff --git a/async.c b/async.c index 0830ef86..a363b50e 100644 --- a/async.c +++ b/async.c @@ -265,6 +265,15 @@ struct wsgi_request *find_first_available_wsgi_req(struct uwsgi_server *uwsgi) { return NULL ; } +struct wsgi_request *find_wsgi_req_by_id(struct uwsgi_server *uwsgi, int async_id) { + + uint8_t *ptr = (uint8_t *) uwsgi->wsgi_requests ; + + ptr += (sizeof(struct wsgi_request)+(uwsgi->buffer_size-1)) * async_id ; + + return (struct wsgi_request *) ptr ; +} + struct wsgi_request *find_wsgi_req_by_fd(struct uwsgi_server *uwsgi, int fd, int etype) { struct wsgi_request* wsgi_req = uwsgi->wsgi_requests ; diff --git a/pyutils.c b/pyutils.c index e2b986e6..97afc993 100644 --- a/pyutils.c +++ b/pyutils.c @@ -8,12 +8,9 @@ int manage_python_response(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi ssize_t sf_len = 0 ; #endif - //fprintf(stderr,"managing response of tasklet %d on %p %s %d\n", wsgi_req->async_id, wsgi_req, ( (PyObject *) wsgi_req->async_result)->ob_type->tp_name, PyList_Size(wsgi_req->async_result)); - - fprintf(stderr,"managing request\n"); + //fprintf(stderr,"managing request for %d %p\n", wsgi_req->async_id, wsgi_req); // return or yield ? if (PyString_Check((PyObject *)wsgi_req->async_result)) { - //fprintf(stderr,"DOH !!!\n"); if ((wsize = write(wsgi_req->poll.fd, PyString_AsString(wsgi_req->async_result), PyString_Size(wsgi_req->async_result))) < 0) { perror("write()"); goto clear; @@ -52,45 +49,29 @@ int manage_python_response(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi // ok its a yield if (!wsgi_req->async_placeholder) { - //fprintf(stderr,"getting placeholder %d\n", wsgi_req->async_id); wsgi_req->async_placeholder = PyObject_GetIter(wsgi_req->async_result); if (!wsgi_req->async_placeholder) { goto clear2; } Py_DECREF((PyObject *)wsgi_req->async_result); #ifdef UWSGI_ASYNC - if (uwsgi->async > 1 && !uwsgi->stackless) { + if (uwsgi->async > 1) { return UWSGI_AGAIN; } #endif } - //fprintf(stderr,"running yield %d %p\n", wsgi_req->async_id, wsgi_req); - /* - boh = wsgi_req->async_placeholder; boh2 = wsgi_req->async_result ; - fprintf(stderr,"placeholder refcnt %d: %d\n", wsgi_req->async_switches, boh->ob_refcnt); - */ - - - fprintf(stderr,"placeholder: %p\n", wsgi_req->async_placeholder) ; pychunk = PyIter_Next(wsgi_req->async_placeholder) ; - /* - boh = wsgi_req->async_placeholder; boh2 = wsgi_req->async_result ; - fprintf(stderr,"AFTER NEXT %d/%d\n", boh->ob_refcnt, boh2->ob_refcnt); - */ - if (!pychunk) { if (PyErr_Occurred()) PyErr_Print(); goto clear; } - fprintf(stderr,"checking pychunk\n"); - //fprintf(stderr,"ob type %s\n", pychunk->ob_type->tp_name); if (PyString_Check(pychunk)) { if ((wsize = write(wsgi_req->poll.fd, PyString_AsString(pychunk), PyString_Size(pychunk))) < 0) { perror("write()"); @@ -112,22 +93,12 @@ int manage_python_response(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi #endif Py_DECREF(pychunk); - //Py_DECREF(wsgi_req->async_placeholder); - //Py_DECREF(wsgi_req->async_result); - - /* - boh = wsgi_req->async_placeholder; boh2 = wsgi_req->async_result ; - fprintf(stderr,"AFTER CHUNK %d/%d\n", boh->ob_refcnt, boh2->ob_refcnt); - */ - return UWSGI_AGAIN ; clear: - fprintf(stderr,"clearing request\n"); if (wsgi_req->sendfile_fd != -1) { - Py_DECREF(wsgi_req->async_sendfile); + Py_DECREF((PyObject *)wsgi_req->async_sendfile); } - //fprintf(stderr,"finito\n"); if (wsgi_req->async_environ) { PyDict_Clear(wsgi_req->async_environ); } @@ -138,7 +109,6 @@ clear: Py_XDECREF((PyObject *)wsgi_req->async_placeholder); clear2: Py_DECREF((PyObject *)wsgi_req->async_result); - //fprintf(stderr,"RESULT REFCNT: %d\n", ((PyObject *) wsgi_req->async_result)->ob_refcnt); PyErr_Clear(); return UWSGI_OK; } diff --git a/sendfile.c b/sendfile.c index 925bd067..b49fa078 100644 --- a/sendfile.c +++ b/sendfile.c @@ -6,16 +6,18 @@ extern struct uwsgi_server uwsgi; PyObject *py_uwsgi_sendfile(PyObject * self, PyObject * args) { - if (!PyArg_ParseTuple(args, "Oi:uwsgi_sendfile", &uwsgi.wsgi_req->async_sendfile, &uwsgi.wsgi_req->sendfile_fd_chunk)) { + struct wsgi_request *wsgi_req = current_wsgi_req(&uwsgi); + + if (!PyArg_ParseTuple(args, "Oi:uwsgi_sendfile", &wsgi_req->async_sendfile, &wsgi_req->sendfile_fd_chunk)) { return NULL; } #ifdef PYTHREE - uwsgi.wsgi_req->sendfile_fd = PyObject_AsFileDescriptor(uwsgi.wsgi_req->async_sendfile); + wsgi_req->sendfile_fd = PyObject_AsFileDescriptor(wsgi_req->async_sendfile); #else - if (PyFile_Check((PyObject *)uwsgi.wsgi_req->async_sendfile)) { - Py_INCREF(uwsgi.wsgi_req->async_sendfile); - uwsgi.wsgi_req->sendfile_fd = PyObject_AsFileDescriptor(uwsgi.wsgi_req->async_sendfile); + if (PyFile_Check((PyObject *)wsgi_req->async_sendfile)) { + Py_INCREF((PyObject *)wsgi_req->async_sendfile); + wsgi_req->sendfile_fd = PyObject_AsFileDescriptor(wsgi_req->async_sendfile); } #endif diff --git a/simple_app.py b/simple_app.py index 3b7d6c0d..b3764abf 100644 --- a/simple_app.py +++ b/simple_app.py @@ -1,6 +1,4 @@ -import stackless - def application(env, start_response): print env start_response('200 Ok', [('Content-type', 'text/plain')]) - return "hello world" + yield "hello world" diff --git a/stackless.c b/stackless.c index 0ed68569..1f73eccd 100644 --- a/stackless.c +++ b/stackless.c @@ -30,11 +30,8 @@ PyObject *py_uwsgi_stackless_worker(PyObject * self, PyObject * args) { for(;;) { // wait for request - fprintf(stderr,"tasklet %d is waiting on %p\n", async_id, wsgi_req); zero = PyChannel_Receive(uwsgi.workers_channel); - fprintf(stderr,"tasket %d start\n", async_id); - wsgi_req_setup(wsgi_req, async_id); if (wsgi_req_accept(uwsgi.serverfd, wsgi_req)) { @@ -47,7 +44,6 @@ PyObject *py_uwsgi_stackless_worker(PyObject * self, PyObject * args) { uwsgi_close_request(&uwsgi, wsgi_req); - fprintf(stderr,"tasket %d ended\n", async_id); } @@ -90,7 +86,7 @@ void stackless_init(struct uwsgi_server *uwsgi) { wsgi_req->async_id = i ; PyTasklet_Setup(wsgi_req->tasklet, PyTuple_New(0), NULL); - PyTasklet_Run(wsgi_req->tasklet); + //PyTasklet_Run(wsgi_req->tasklet); wsgi_req = next_wsgi_req(uwsgi, wsgi_req) ; } @@ -124,10 +120,14 @@ void stackless_loop(struct uwsgi_server *uwsgi) { } + /* if (PyStackless_GetRunCount() > 0) { PyStackless_Schedule(Py_None, 0); } - //PyStackless_RunWatchdogEx( 10, PY_WATCHDOG_TOTALTIMEOUT); + */ + + PyStackless_RunWatchdogEx( 10, PY_WATCHDOG_TOTALTIMEOUT); + //int_tasklet = (PyTaskletObject *) PyStackless_RunWatchdog( 1000 ); /* fprintf(stderr,"done watchdog %p\n", int_tasklet); diff --git a/tests/cpubound_green.py b/tests/cpubound_green.py new file mode 100644 index 00000000..078f9db1 --- /dev/null +++ b/tests/cpubound_green.py @@ -0,0 +1,15 @@ +import uwsgi +import time + +def application(env, start_response): + counter = 0 + start_response( '200 OK', [ ('Content-Type','text/html') ]) + start_time = time.time() + for i in range(1,100000): + uwsgi.green_schedule() + # print every 100 + if i % 100 == 0: + yield "

%d

\n" % i + counter = counter + i + + yield "

%d cycles after %d

\n" % (counter, time.time() - start_time) diff --git a/ugreen.c b/ugreen.c new file mode 100644 index 00000000..93bf651a --- /dev/null +++ b/ugreen.c @@ -0,0 +1,232 @@ +#ifdef UWSGI_UGREEN + +#include "uwsgi.h" + +#define GREEN_STACK_SIZE 128 * 1024 + +extern struct uwsgi_server uwsgi; + + +static int green_blocking(struct uwsgi_server *uwsgi) { + struct wsgi_request* wsgi_req = uwsgi->wsgi_requests ; + int i ; + + for(i=0;iasync;i++) { + if (wsgi_req->async_status != UWSGI_ACCEPTING) { + return 0 ; + } + wsgi_req = next_wsgi_req(uwsgi, wsgi_req) ; + } + + return -1 ; +} + +static void u_green_schedule_to_main(struct uwsgi_server *uwsgi, int async_id) { + + int py_current_recursion_depth; + struct _frame* py_current_frame; + + PyThreadState* tstate = PyThreadState_GET(); + py_current_recursion_depth = tstate->recursion_depth; + py_current_frame = tstate->frame; + + swapcontext(uwsgi->green_contexts[async_id], &uwsgi->greenmain); + + tstate = PyThreadState_GET(); + tstate->recursion_depth = py_current_recursion_depth; + tstate->frame = py_current_frame ; +} + +static void u_green_schedule_to_req(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) { + + int py_current_recursion_depth; + struct _frame* py_current_frame; + + PyThreadState* tstate = PyThreadState_GET(); + py_current_recursion_depth = tstate->recursion_depth; + py_current_frame = tstate->frame; + + uwsgi->wsgi_req = wsgi_req; + wsgi_req->async_switches++; + swapcontext(&uwsgi->greenmain, uwsgi->green_contexts[wsgi_req->async_id] ); + + tstate = PyThreadState_GET(); + tstate->recursion_depth = py_current_recursion_depth; + tstate->frame = py_current_frame ; +} + +PyObject *py_uwsgi_green_schedule(PyObject * self, PyObject * args) { + + struct wsgi_request *wsgi_req = current_wsgi_req(&uwsgi); + + /* + int py_current_recursion_depth; + struct _frame* py_current_frame; + + PyThreadState* tstate = PyThreadState_GET(); + py_current_recursion_depth = tstate->recursion_depth; + py_current_frame = tstate->frame; + */ + u_green_schedule_to_main(&uwsgi, wsgi_req->async_id); + + /* + tstate = PyThreadState_GET(); + tstate->recursion_depth = py_current_recursion_depth; + tstate->frame = py_current_frame ; + */ + + Py_INCREF(Py_True); + return Py_True; + +} + +PyMethodDef uwsgi_green_methods[] = { + {"green_schedule", py_uwsgi_green_schedule, METH_VARARGS, ""}, + { NULL, NULL } +}; + +static struct wsgi_request *find_first_accepting_wsgi_req(struct uwsgi_server *uwsgi) { + + struct wsgi_request* wsgi_req = uwsgi->wsgi_requests ; + int i ; + + for(i=0;iasync;i++) { + if (wsgi_req->async_status == UWSGI_ACCEPTING) { + return wsgi_req ; + } + wsgi_req = next_wsgi_req(uwsgi, wsgi_req) ; + } + + return NULL ; +} + + +static void u_green_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, int async_id) { + + + for(;;) { + wsgi_req_setup(wsgi_req, async_id); + + wsgi_req->async_status = UWSGI_ACCEPTING; + + u_green_schedule_to_main(uwsgi, async_id); + + if (wsgi_req_accept(uwsgi->serverfd, wsgi_req)) { + continue; + } + wsgi_req->async_status = UWSGI_OK; + + u_green_schedule_to_main(uwsgi, async_id); + + if (wsgi_req_recv(wsgi_req)) { + continue; + } + + while(wsgi_req->async_status == UWSGI_AGAIN) { + u_green_schedule_to_main(uwsgi, async_id); + wsgi_req->async_status = (*uwsgi->shared->hooks[wsgi_req->modifier]) (uwsgi, wsgi_req); + } + + u_green_schedule_to_main(uwsgi, async_id); + + uwsgi_close_request(uwsgi, wsgi_req); + + } + +} + +void u_green_loop(struct uwsgi_server *uwsgi) { + + struct wsgi_request *wsgi_req = uwsgi->wsgi_requests ; + + int i, current = 0 ; + + + PyMethodDef *uwsgi_function; + + fprintf(stderr,"initializing %d green threads with stack size of %lu (%lu KB)\n", uwsgi->async, (unsigned long) GREEN_STACK_SIZE, (unsigned long) GREEN_STACK_SIZE/1024); + + uwsgi->green_stacks = malloc( sizeof(char*) * uwsgi->async); + if (!uwsgi->green_stacks) { + perror("malloc()\n"); + exit(1); + } + + for(i=0;iasync;i++) { + //uwsgi->green_stacks[i] = malloc( 4096 * 256 ); + uwsgi->green_stacks[i] = mmap(NULL, GREEN_STACK_SIZE , PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN, -1, 0); + if (!uwsgi->green_stacks[i]) { + perror("mmap()"); + exit(1); + } + } + + + uwsgi->green_contexts = malloc( sizeof(ucontext_t*) * uwsgi->async); + if (!uwsgi->green_contexts) { + perror("malloc()\n"); + exit(1); + } + + + for(i=0;iasync;i++) { + uwsgi->green_contexts[i] = malloc( sizeof(ucontext_t) ); + if (!uwsgi->green_contexts[i]) { + perror("malloc()"); + exit(1); + } + getcontext(uwsgi->green_contexts[i]); + uwsgi->green_contexts[i]->uc_stack.ss_sp = uwsgi->green_stacks[i]; + uwsgi->green_contexts[i]->uc_stack.ss_size = GREEN_STACK_SIZE ; + uwsgi->green_contexts[i]->uc_link = NULL; + makecontext(uwsgi->green_contexts[i], (void (*) (void)) &u_green_request, 3, uwsgi, wsgi_req, i); + wsgi_req->async_status = UWSGI_ACCEPTING; + wsgi_req->async_id = i; + wsgi_req = next_wsgi_req(uwsgi, wsgi_req) ; + } + + for (uwsgi_function = uwsgi_green_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) { + PyObject *func = PyCFunction_New(uwsgi_function, NULL); + PyDict_SetItemString(uwsgi->embedded_dict, uwsgi_function->ml_name, func); + Py_DECREF(func); + } + + + for(;;) { + + uwsgi->async_running = green_blocking(uwsgi) ; + + uwsgi->async_nevents = async_wait(uwsgi->async_queue, uwsgi->async_events, uwsgi->async, uwsgi->async_running, 0); + + if (uwsgi->async_nevents < 0) { + continue; + } + + if (i > 0) { + wsgi_req = find_first_accepting_wsgi_req(uwsgi); + if (!wsgi_req) goto cycle; + } + + for(i=0; iasync_nevents;i++) { + + if (uwsgi->async_events[i].ASYNC_FD == uwsgi->serverfd) { + u_green_schedule_to_req(uwsgi, wsgi_req); + } + + } + +cycle: + wsgi_req = find_wsgi_req_by_id(uwsgi, current) ; + if (wsgi_req->async_status != UWSGI_ACCEPTING) { + u_green_schedule_to_req(uwsgi, wsgi_req); + } + current++; + if (current >= uwsgi->async) current = 0; + + } + + // never here + +} + +#endif diff --git a/utils.c b/utils.c index 515510fa..c6674bc9 100644 --- a/utils.c +++ b/utils.c @@ -281,7 +281,7 @@ int wsgi_req_accept(int fd, struct wsgi_request *wsgi_req) { wsgi_req->poll.fd = accept(fd, (struct sockaddr *) &wsgi_req->c_addr, (socklen_t *) &wsgi_req->c_len); - if (uwsgi.wsgi_req->poll.fd < 0) { + if (wsgi_req->poll.fd < 0) { perror("accept()"); return -1; } @@ -289,3 +289,17 @@ int wsgi_req_accept(int fd, struct wsgi_request *wsgi_req) { return 0; } +struct wsgi_request *current_wsgi_req(struct uwsgi_server *uwsgi) { + + struct wsgi_request *wsgi_req = uwsgi->wsgi_req; + +#ifdef UWSGI_STACKLESS + if (uwsgi->stackless && uwsgi->async >1) { + PyThreadState *ts = PyThreadState_GET(); + wsgi_req = find_request_by_tasklet(ts->st.current); + } +#endif + + return wsgi_req; + +} diff --git a/uwsgi.c b/uwsgi.c index 75224172..e97bf404 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -354,6 +354,9 @@ int main(int argc, char *argv[], char *envp[]) { #endif #ifdef UWSGI_STACKLESS {"stackless", no_argument, &uwsgi.stackless, 1}, +#endif +#ifdef UWSGI_UGREEN + {"ugreen", no_argument, &uwsgi.ugreen, 1}, #endif {"version", no_argument, 0, LONG_ARGS_VERSION}, {0, 0, 0, 0} @@ -1317,6 +1320,11 @@ int main(int argc, char *argv[], char *envp[]) { uwsgi.async_running = -1 ; #endif +#ifdef UWSGI_UGREEN + if (uwsgi.ugreen) { + u_green_loop(&uwsgi); + } +#endif #ifdef UWSGI_STACKLESS if (uwsgi.stackless) { diff --git a/uwsgi.h b/uwsgi.h index 0cc3f298..1c1cb0c2 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -16,6 +16,10 @@ #include #endif +#ifdef UWSGI_UGREEN +#include +#endif + #include #include #include @@ -124,6 +128,7 @@ PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t); #define UWSGI_OK 0 #define UWSGI_AGAIN 1 +#define UWSGI_ACCEPTING 2 #define UWSGI_CLEAR_STATUS uwsgi.workers[uwsgi.mywid].status = 0 @@ -402,6 +407,13 @@ struct uwsgi_server { int stackless; +#ifdef UWSGI_UGREEN + int ugreen; + ucontext_t greenmain; + ucontext_t **green_contexts; + char **green_stacks; +#endif + #ifdef __linux__ struct epoll_event *async_events; #elif defined(__sun__) @@ -681,6 +693,7 @@ struct http_status_codes { struct wsgi_request *async_loop(struct uwsgi_server *); struct wsgi_request *find_first_available_wsgi_req(struct uwsgi_server *); struct wsgi_request *find_wsgi_req_by_fd(struct uwsgi_server *, int, int); +struct wsgi_request *find_wsgi_req_by_id(struct uwsgi_server *, int); struct wsgi_request *next_wsgi_req(struct uwsgi_server *, struct wsgi_request *); @@ -757,3 +770,9 @@ void uwsgi_close_request(struct uwsgi_server *, struct wsgi_request *) ; void wsgi_req_setup(struct wsgi_request *, int); int wsgi_req_recv(struct wsgi_request *); int wsgi_req_accept(int, struct wsgi_request *); + +#ifdef UWSGI_UGREEN +void u_green_loop(struct uwsgi_server *); +#endif + +struct wsgi_request *current_wsgi_req(struct uwsgi_server *); diff --git a/uwsgiconfig.py b/uwsgiconfig.py index 40ed4151..fbbe3efe 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -8,13 +8,14 @@ SPOOLER=True EMBEDDED=True UDP=True MULTICAST=True -THREADING=True +THREADING=False SENDFILE=True PROFILER=False NAGIOS=True PROXY=True MINTERPRETERS=True ASYNC=True +UGREEN=True STACKLESS=False PLUGINS = [] UWSGI_BIN_NAME = 'uwsgi' @@ -153,6 +154,11 @@ def parse_vars(): cflags.append("-DUWSGI_PROXY") gcc_list.append('proxy') + if UGREEN: + depends_on("UGREEN", ['ASYNC']) + cflags.append("-DUWSGI_UGREEN") + gcc_list.append('ugreen') + if SNMP: depends_on("SNMP", ['UDP']) cflags.append("-DUWSGI_SNMP") diff --git a/wsgi_handlers.c b/wsgi_handlers.c index b6d919cc..0769f5cc 100644 --- a/wsgi_handlers.c +++ b/wsgi_handlers.c @@ -7,14 +7,7 @@ PyObject *py_uwsgi_write(PyObject * self, PyObject * args) { char *content; int len; - struct wsgi_request *wsgi_req = uwsgi.wsgi_req; - -#ifdef UWSGI_STACKLESS - if (uwsgi.stackless) { - PyThreadState *ts = PyThreadState_GET(); - wsgi_req = find_request_by_tasklet(ts->st.current); - } -#endif + struct wsgi_request *wsgi_req = current_wsgi_req(&uwsgi); data = PyTuple_GetItem(args, 0); if (PyString_Check(data)) { @@ -41,15 +34,7 @@ PyObject *py_uwsgi_write(PyObject * self, PyObject * args) { PyObject *py_eventfd_read(PyObject * self, PyObject * args) { int fd, timeout; - struct wsgi_request *wsgi_req = uwsgi.wsgi_req; - -#ifdef UWSGI_STACKLESS - if (uwsgi.stackless) { - PyThreadState *ts = PyThreadState_GET(); - wsgi_req = find_request_by_tasklet(ts->st.current); - } -#endif - + struct wsgi_request *wsgi_req = current_wsgi_req(&uwsgi); if (!PyArg_ParseTuple(args, "i|i", &fd, &timeout)) { return NULL; @@ -68,14 +53,7 @@ PyObject *py_eventfd_read(PyObject * self, PyObject * args) { PyObject *py_eventfd_write(PyObject * self, PyObject * args) { int fd, timeout; - struct wsgi_request *wsgi_req = uwsgi.wsgi_req; - -#ifdef UWSGI_STACKLESS - if (uwsgi.stackless) { - PyThreadState *ts = PyThreadState_GET(); - wsgi_req = find_request_by_tasklet(ts->st.current); - } -#endif + struct wsgi_request *wsgi_req = current_wsgi_req(&uwsgi); if (!PyArg_ParseTuple(args, "i|i", &fd, &timeout)) { return NULL; @@ -103,8 +81,6 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req struct uwsgi_app *wi ; - fprintf(stderr,"starting\n"); - #ifdef UWSGI_ASYNC if (wsgi_req->async_status == UWSGI_AGAIN) { // get rid of timeout @@ -204,6 +180,7 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req Py_INCREF((PyObject *)wsgi_req->async_environ); + for (i = 0; i < wsgi_req->var_cnt; i += 2) { //fprintf(stderr,"%.*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); pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len); @@ -303,6 +280,7 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req else { #endif + PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ); wsgi_req->async_result = python_call(wi->wsgi_callable, wsgi_req->async_args); @@ -313,7 +291,6 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req if (wsgi_req->async_result) { - fprintf(stderr,"looping\n"); while ( manage_python_response(uwsgi, wsgi_req) != UWSGI_OK) { #ifdef UWSGI_ASYNC diff --git a/wsgi_headers.c b/wsgi_headers.c index ad9a2c28..e72cfbc1 100644 --- a/wsgi_headers.c +++ b/wsgi_headers.c @@ -11,14 +11,7 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) { PyObject *h_key, *h_value; int i, j; -struct wsgi_request *wsgi_req = uwsgi.wsgi_req; - -#ifdef UWSGI_STACKLESS - if (uwsgi.stackless) { - PyThreadState *ts = PyThreadState_GET(); - wsgi_req = find_request_by_tasklet(ts->st.current); - } -#endif + struct wsgi_request *wsgi_req = current_wsgi_req(&uwsgi); #ifndef UNBIT int base = 0;