mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-08-27 08:55:48 +00:00
async sleep implementation, kqueue re-broken, profiler leaks memory
This commit is contained in:
@@ -31,6 +31,25 @@ int async_queue_init(int serverfd) {
|
||||
return epfd;
|
||||
}
|
||||
|
||||
int async_wait(int queuefd, void *events, int nevents, int block, int timeout) {
|
||||
|
||||
int ret ;
|
||||
|
||||
if (timeout <= 0) {
|
||||
timeout = block;
|
||||
}
|
||||
else {
|
||||
timeout = timeout*1000;
|
||||
}
|
||||
|
||||
//fprintf(stderr,"waiting with timeout %d nevents %d\n", timeout, nevents);
|
||||
ret = epoll_wait(queuefd, (struct epoll_event *) events, nevents, timeout);
|
||||
if (ret < 0) {
|
||||
perror("epoll_wait()");
|
||||
}
|
||||
return ret ;
|
||||
}
|
||||
|
||||
int async_add(int queuefd, int fd, int etype) {
|
||||
struct epoll_event ee;
|
||||
|
||||
@@ -83,6 +102,10 @@ int async_queue_init(int serverfd) {
|
||||
return kfd;
|
||||
}
|
||||
|
||||
int async_wait() {
|
||||
uwsgi.async_nevents = kevent(uwsgi.async_queue, NULL, 0, uwsgi.async_events, uwsgi.async, &uwsgi.async_timeout);
|
||||
}
|
||||
|
||||
int async_add(int queuefd, int fd, int etype) {
|
||||
struct kevent kev;
|
||||
|
||||
@@ -117,14 +140,66 @@ struct wsgi_request *next_wsgi_req(struct uwsgi_server *uwsgi, struct wsgi_reque
|
||||
|
||||
return (struct wsgi_request *) ptr ;
|
||||
}
|
||||
|
||||
int async_get_timeout(struct uwsgi_server *uwsgi) {
|
||||
|
||||
|
||||
struct wsgi_request* wsgi_req = uwsgi->wsgi_requests ;
|
||||
int i ;
|
||||
time_t curtime, tdelta = 0 ;
|
||||
int ret = 0 ;
|
||||
|
||||
if (!uwsgi->async_running) return 0;
|
||||
|
||||
for(i=0;i<uwsgi->async;i++) {
|
||||
if (wsgi_req->async_status == UWSGI_AGAIN) {
|
||||
if (wsgi_req->async_timeout_expired) {
|
||||
return 0;
|
||||
}
|
||||
if (wsgi_req->async_timeout > 0) {
|
||||
if (tdelta <= 0 || tdelta > wsgi_req->async_timeout) {
|
||||
tdelta = wsgi_req->async_timeout ;
|
||||
}
|
||||
}
|
||||
}
|
||||
wsgi_req = next_wsgi_req(uwsgi, wsgi_req) ;
|
||||
}
|
||||
|
||||
curtime = time(NULL);
|
||||
|
||||
ret = tdelta - curtime ;
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void async_expire_timeouts(struct uwsgi_server *uwsgi) {
|
||||
|
||||
struct wsgi_request* wsgi_req = uwsgi->wsgi_requests ;
|
||||
int i ;
|
||||
time_t deadline = time(NULL);
|
||||
|
||||
|
||||
for(i=0;i<uwsgi->async;i++) {
|
||||
if (wsgi_req->async_status == UWSGI_AGAIN && wsgi_req->async_timeout > 0) {
|
||||
if (wsgi_req->async_timeout <= deadline) {
|
||||
wsgi_req->async_timeout = 0 ;
|
||||
wsgi_req->async_timeout_expired = 1 ;
|
||||
}
|
||||
}
|
||||
wsgi_req = next_wsgi_req(uwsgi, wsgi_req) ;
|
||||
}
|
||||
}
|
||||
|
||||
struct wsgi_request *find_first_available_wsgi_req(struct uwsgi_server *uwsgi) {
|
||||
|
||||
struct wsgi_request* wsgi_req = uwsgi->wsgi_requests ;
|
||||
int i ;
|
||||
|
||||
for(i=0;i<uwsgi->async;i++) {
|
||||
//fprintf(stderr,"request %d fd %d switches %d\n", i, wsgi_req->poll.fd, wsgi_req->async_switches);
|
||||
if (wsgi_req->async_status == 0) {
|
||||
if (wsgi_req->async_status == UWSGI_OK) {
|
||||
return wsgi_req ;
|
||||
}
|
||||
wsgi_req = next_wsgi_req(uwsgi, wsgi_req) ;
|
||||
@@ -149,6 +224,13 @@ struct wsgi_request *find_wsgi_req_by_fd(struct uwsgi_server *uwsgi, int fd, int
|
||||
|
||||
}
|
||||
|
||||
void async_set_timeout(struct wsgi_request *wsgi_req, time_t timeout) {
|
||||
|
||||
wsgi_req->async_timeout = time(NULL);
|
||||
wsgi_req->async_timeout += timeout;
|
||||
wsgi_req->async_timeout_expired = 0 ;
|
||||
|
||||
}
|
||||
|
||||
struct wsgi_request * async_loop(struct uwsgi_server *uwsgi) {
|
||||
|
||||
@@ -173,12 +255,14 @@ struct wsgi_request * async_loop(struct uwsgi_server *uwsgi) {
|
||||
wsgi_req->async_waiting_fd_monitored = 1;
|
||||
wsgi_req->async_status = UWSGI_AGAIN;
|
||||
}
|
||||
else if (wsgi_req->async_waiting_fd == -1) {
|
||||
else if (wsgi_req->async_waiting_fd == -1 && wsgi_req->async_timeout <= 0) {
|
||||
uwsgi->async_running = 0 ;
|
||||
// st global wsgi_req for python functions
|
||||
uwsgi->wsgi_req = wsgi_req ;
|
||||
wsgi_req->async_status = (*uwsgi->shared->hooks[wsgi_req->modifier]) (uwsgi, wsgi_req);
|
||||
|
||||
wsgi_req->async_switches++;
|
||||
|
||||
if (wsgi_req->async_status < UWSGI_AGAIN) {
|
||||
return wsgi_req;
|
||||
}
|
||||
|
||||
+17
-17
@@ -319,8 +319,8 @@ int uwsgi_parse_vars(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req)
|
||||
ptrbuf += 2;
|
||||
if (ptrbuf + strsize < bufferend) {
|
||||
// var key
|
||||
uwsgi->hvec[wsgi_req->var_cnt].iov_base = ptrbuf;
|
||||
uwsgi->hvec[wsgi_req->var_cnt].iov_len = strsize;
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_base = ptrbuf;
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = strsize;
|
||||
ptrbuf += strsize;
|
||||
if (ptrbuf + 2 < bufferend) {
|
||||
memcpy(&strsize, ptrbuf, 2);
|
||||
@@ -329,56 +329,56 @@ int uwsgi_parse_vars(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req)
|
||||
#endif
|
||||
ptrbuf += 2;
|
||||
if (ptrbuf + strsize <= bufferend) {
|
||||
if (!strncmp("SCRIPT_NAME", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
if (!strncmp("SCRIPT_NAME", wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->script_name = ptrbuf;
|
||||
wsgi_req->script_name_len = strsize;
|
||||
}
|
||||
else if (!strncmp("SERVER_PROTOCOL", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
else if (!strncmp("SERVER_PROTOCOL", wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->protocol = ptrbuf;
|
||||
wsgi_req->protocol_len = strsize;
|
||||
}
|
||||
else if (!strncmp("REQUEST_URI", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
else if (!strncmp("REQUEST_URI", wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->uri = ptrbuf;
|
||||
wsgi_req->uri_len = strsize;
|
||||
}
|
||||
else if (!strncmp("QUERY_STRING", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
else if (!strncmp("QUERY_STRING", wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->query_string = ptrbuf;
|
||||
wsgi_req->query_string_len = strsize;
|
||||
}
|
||||
else if (!strncmp("REQUEST_METHOD", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
else if (!strncmp("REQUEST_METHOD", wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->method = ptrbuf;
|
||||
wsgi_req->method_len = strsize;
|
||||
}
|
||||
else if (!strncmp("REMOTE_ADDR", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
else if (!strncmp("REMOTE_ADDR", wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->remote_addr = ptrbuf;
|
||||
wsgi_req->remote_addr_len = strsize;
|
||||
}
|
||||
else if (!strncmp("REMOTE_USER", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
else if (!strncmp("REMOTE_USER", wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->remote_user = ptrbuf;
|
||||
wsgi_req->remote_user_len = strsize;
|
||||
}
|
||||
else if (!strncmp("UWSGI_SCHEME", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
else if (!strncmp("UWSGI_SCHEME", wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->scheme = ptrbuf;
|
||||
wsgi_req->scheme_len = strsize;
|
||||
}
|
||||
else if (!strncmp("UWSGI_SCRIPT",uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len )) {
|
||||
else if (!strncmp("UWSGI_SCRIPT",wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len )) {
|
||||
wsgi_req->wsgi_script = ptrbuf;
|
||||
wsgi_req->wsgi_script_len = strsize;
|
||||
}
|
||||
else if (!strncmp("UWSGI_MODULE", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
else if (!strncmp("UWSGI_MODULE", wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->wsgi_module = ptrbuf;
|
||||
wsgi_req->wsgi_module_len = strsize;
|
||||
}
|
||||
else if (!strncmp("UWSGI_CALLABLE", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
else if (!strncmp("UWSGI_CALLABLE", wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->wsgi_callable = ptrbuf;
|
||||
wsgi_req->wsgi_callable_len = strsize;
|
||||
}
|
||||
else if (!strncmp("HTTPS", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
else if (!strncmp("HTTPS", wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->https = ptrbuf;
|
||||
wsgi_req->https_len = strsize;
|
||||
}
|
||||
#ifdef UNBIT
|
||||
else if (!strncmp("UNBIT_FLAGS", uwsgi->hvec[wsgi_req->var_cnt].iov_base, uwsgi->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
else if (!strncmp("UNBIT_FLAGS", wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->unbit_flags = *(unsigned long long *) ptrbuf;
|
||||
}
|
||||
#endif
|
||||
@@ -390,8 +390,8 @@ int uwsgi_parse_vars(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req)
|
||||
return -1;
|
||||
}
|
||||
// var value
|
||||
uwsgi->hvec[wsgi_req->var_cnt].iov_base = ptrbuf;
|
||||
uwsgi->hvec[wsgi_req->var_cnt].iov_len = strsize;
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_base = ptrbuf;
|
||||
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = strsize;
|
||||
if (wsgi_req->var_cnt < uwsgi->vec_size - (4 + 1)) {
|
||||
wsgi_req->var_cnt++;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
#include "uwsgi.h"
|
||||
|
||||
int manage_python_response(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyObject *pychunk ;
|
||||
ssize_t wsize ;
|
||||
|
||||
// return or yield ?
|
||||
if (PyString_Check(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;
|
||||
}
|
||||
wsgi_req->response_size += wsize;
|
||||
goto clear;
|
||||
}
|
||||
|
||||
// ok its a yield
|
||||
if (!wsgi_req->async_placeholder) {
|
||||
wsgi_req->async_placeholder = PyObject_GetIter(wsgi_req->async_result);
|
||||
if (!wsgi_req->async_placeholder) {
|
||||
goto clear2;
|
||||
}
|
||||
Py_DECREF(wsgi_req->async_result);
|
||||
#ifdef UWSGI_ASYNC
|
||||
if (uwsgi->async > 1) {
|
||||
return UWSGI_AGAIN;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
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,"NEXT CHUNK\n");
|
||||
|
||||
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) {
|
||||
//fprintf(stderr,"AIA\n");
|
||||
if (PyErr_Occurred()) PyErr_Print();
|
||||
goto clear;
|
||||
}
|
||||
|
||||
//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()");
|
||||
Py_DECREF(pychunk);
|
||||
goto clear;
|
||||
}
|
||||
wsgi_req->response_size += wsize;
|
||||
}
|
||||
|
||||
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,"finito\n");
|
||||
if (wsgi_req->async_environ) {
|
||||
PyDict_Clear(wsgi_req->async_environ);
|
||||
}
|
||||
if (wsgi_req->async_post) {
|
||||
fclose(wsgi_req->async_post);
|
||||
}
|
||||
Py_XDECREF(wsgi_req->async_placeholder);
|
||||
clear2:
|
||||
Py_DECREF(wsgi_req->async_result);
|
||||
//fprintf(stderr,"RESULT REFCNT: %d\n", ((PyObject *) wsgi_req->async_result)->ob_refcnt);
|
||||
PyErr_Clear();
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
|
||||
PyObject *python_call(PyObject *callable, PyObject *args) {
|
||||
|
||||
PyObject *pyret;
|
||||
|
||||
pyret = PyEval_CallObject(callable, args);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
return pyret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int uwsgi_python_call(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, PyObject *callable, PyObject *args) {
|
||||
|
||||
wsgi_req->async_result = python_call(callable, args);
|
||||
|
||||
if (wsgi_req->async_result) {
|
||||
while ( manage_python_response(uwsgi, wsgi_req) != UWSGI_OK) {
|
||||
#ifdef UWSGI_ASYNC
|
||||
if (uwsgi->async > 1) {
|
||||
return UWSGI_AGAIN;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return UWSGI_OK;
|
||||
}
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
def application(env, start_response):
|
||||
start_response('200 Ok', [('Content-type', 'text/plain; charset=UTF-32')])
|
||||
start_response('200 Ok', [('Content-type', 'text/plain')])
|
||||
return "hello world"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import time
|
||||
|
||||
def application(env, start_response):
|
||||
start_response( '200 OK', [ ('Content-Type','text/html') ])
|
||||
for i in range(1,10000):
|
||||
yield "<h1>%s</h1>" % i
|
||||
for i in range(1,100000):
|
||||
yield "<h1>%s at %s</h1>" % (i, str(time.time()))
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import uwsgi
|
||||
|
||||
sleepvalue = 5 ;
|
||||
|
||||
def application(env, start_response):
|
||||
start_response('200 Ok', [('Content-type', 'text/html')])
|
||||
yield uwsgi.async_sleep(sleepvalue)
|
||||
#print "TIMEOUT: ", env['x-wsgiorg.fdevent.timeout']
|
||||
yield "<h1>Hello World after %d seconds</h1>" % sleepvalue
|
||||
@@ -1,4 +1,5 @@
|
||||
def application(environ, start_response):
|
||||
|
||||
start_response('200 OK', [('Content-Type', 'image/png')])
|
||||
fd = open('logo_uWSGI.png','r')
|
||||
return environ['wsgi.file_wrapper'](fd, 4096)
|
||||
yield environ['wsgi.file_wrapper'](fd, 4096)
|
||||
@@ -301,43 +301,43 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
|
||||
|
||||
if (uwsgi.wsgi_req->protocol_len == 0) {
|
||||
uwsgi.hvec[0].iov_base = (char *) http_protocol;
|
||||
uwsgi.wsgi_req->hvec[0].iov_base = (char *) http_protocol;
|
||||
uwsgi.wsgi_req->protocol_len = 8;
|
||||
}
|
||||
else {
|
||||
uwsgi.hvec[0].iov_base = uwsgi.wsgi_req->protocol;
|
||||
uwsgi.wsgi_req->hvec[0].iov_base = uwsgi.wsgi_req->protocol;
|
||||
}
|
||||
|
||||
uwsgi.hvec[0].iov_len = uwsgi.wsgi_req->protocol_len;
|
||||
uwsgi.hvec[1].iov_base = " ";
|
||||
uwsgi.hvec[1].iov_len = 1;
|
||||
uwsgi.wsgi_req->hvec[0].iov_len = uwsgi.wsgi_req->protocol_len;
|
||||
uwsgi.wsgi_req->hvec[1].iov_base = " ";
|
||||
uwsgi.wsgi_req->hvec[1].iov_len = 1;
|
||||
#ifdef PYTHREE
|
||||
uwsgi.hvec[2].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(head));
|
||||
uwsgi.hvec[2].iov_len = strlen(uwsgi.hvec[2].iov_base);
|
||||
uwsgi.wsgi_req->hvec[2].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(head));
|
||||
uwsgi.wsgi_req->hvec[2].iov_len = strlen(uwsgi.wsgi_req->hvec[2].iov_base);
|
||||
#else
|
||||
uwsgi.hvec[2].iov_base = PyString_AsString(head);
|
||||
uwsgi.hvec[2].iov_len = PyString_Size(head);
|
||||
uwsgi.wsgi_req->hvec[2].iov_base = PyString_AsString(head);
|
||||
uwsgi.wsgi_req->hvec[2].iov_len = PyString_Size(head);
|
||||
#endif
|
||||
uwsgi.wsgi_req->status = atoi(uwsgi.hvec[2].iov_base);
|
||||
uwsgi.hvec[3].iov_base = nl;
|
||||
uwsgi.hvec[3].iov_len = NL_SIZE;
|
||||
uwsgi.wsgi_req->status = atoi(uwsgi.wsgi_req->hvec[2].iov_base);
|
||||
uwsgi.wsgi_req->hvec[3].iov_base = nl;
|
||||
uwsgi.wsgi_req->hvec[3].iov_len = NL_SIZE;
|
||||
#ifndef UNBIT
|
||||
}
|
||||
else {
|
||||
// drop http status on cgi mode
|
||||
base = 3;
|
||||
uwsgi.hvec[0].iov_base = "Status: ";
|
||||
uwsgi.hvec[0].iov_len = 8;
|
||||
uwsgi.wsgi_req->hvec[0].iov_base = "Status: ";
|
||||
uwsgi.wsgi_req->hvec[0].iov_len = 8;
|
||||
#ifdef PYTHREE
|
||||
uwsgi.hvec[1].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(head));
|
||||
uwsgi.hvec[1].iov_len = strlen(uwsgi.hvec[1].iov_base);
|
||||
uwsgi.wsgi_req->hvec[1].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(head));
|
||||
uwsgi.wsgi_req->hvec[1].iov_len = strlen(uwsgi.wsgi_req->hvec[1].iov_base);
|
||||
#else
|
||||
uwsgi.hvec[1].iov_base = PyString_AsString(head);
|
||||
uwsgi.hvec[1].iov_len = PyString_Size(head);
|
||||
uwsgi.wsgi_req->hvec[1].iov_base = PyString_AsString(head);
|
||||
uwsgi.wsgi_req->hvec[1].iov_len = PyString_Size(head);
|
||||
#endif
|
||||
uwsgi.wsgi_req->status = atoi(uwsgi.hvec[1].iov_base);
|
||||
uwsgi.hvec[2].iov_base = nl;
|
||||
uwsgi.hvec[2].iov_len = NL_SIZE;
|
||||
uwsgi.wsgi_req->status = atoi(uwsgi.wsgi_req->hvec[1].iov_base);
|
||||
uwsgi.wsgi_req->hvec[2].iov_base = nl;
|
||||
uwsgi.wsgi_req->hvec[2].iov_len = NL_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -385,31 +385,31 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
goto clear;
|
||||
}
|
||||
#ifdef PYTHREE
|
||||
uwsgi.hvec[j].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(h_key));
|
||||
uwsgi.hvec[j].iov_len = strlen(uwsgi.hvec[j].iov_base);
|
||||
uwsgi.wsgi_req->hvec[j].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(h_key));
|
||||
uwsgi.wsgi_req->hvec[j].iov_len = strlen(uwsgi.wsgi_req->hvec[j].iov_base);
|
||||
#else
|
||||
uwsgi.hvec[j].iov_base = PyString_AsString(h_key);
|
||||
uwsgi.hvec[j].iov_len = PyString_Size(h_key);
|
||||
uwsgi.wsgi_req->hvec[j].iov_base = PyString_AsString(h_key);
|
||||
uwsgi.wsgi_req->hvec[j].iov_len = PyString_Size(h_key);
|
||||
#endif
|
||||
uwsgi.hvec[j + 1].iov_base = h_sep;
|
||||
uwsgi.hvec[j + 1].iov_len = H_SEP_SIZE;
|
||||
uwsgi.wsgi_req->hvec[j + 1].iov_base = h_sep;
|
||||
uwsgi.wsgi_req->hvec[j + 1].iov_len = H_SEP_SIZE;
|
||||
#ifdef PYTHREE
|
||||
uwsgi.hvec[j + 2].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(h_value));
|
||||
uwsgi.hvec[j + 2].iov_len = strlen(uwsgi.hvec[j + 2].iov_base);
|
||||
uwsgi.wsgi_req->hvec[j + 2].iov_base = PyBytes_AsString(PyUnicode_AsASCIIString(h_value));
|
||||
uwsgi.wsgi_req->hvec[j + 2].iov_len = strlen(uwsgi.wsgi_req->hvec[j + 2].iov_base);
|
||||
#else
|
||||
uwsgi.hvec[j + 2].iov_base = PyString_AsString(h_value);
|
||||
uwsgi.hvec[j + 2].iov_len = PyString_Size(h_value);
|
||||
uwsgi.wsgi_req->hvec[j + 2].iov_base = PyString_AsString(h_value);
|
||||
uwsgi.wsgi_req->hvec[j + 2].iov_len = PyString_Size(h_value);
|
||||
#endif
|
||||
uwsgi.hvec[j + 3].iov_base = nl;
|
||||
uwsgi.hvec[j + 3].iov_len = NL_SIZE;
|
||||
//fprintf(stderr, "%.*s: %.*s\n", uwsgi.hvec[j].iov_len, (char *)uwsgi.hvec[j].iov_base, uwsgi.hvec[j+2].iov_len, (char *) uwsgi.hvec[j+2].iov_base);
|
||||
uwsgi.wsgi_req->hvec[j + 3].iov_base = nl;
|
||||
uwsgi.wsgi_req->hvec[j + 3].iov_len = NL_SIZE;
|
||||
//fprintf(stderr, "%.*s: %.*s\n", uwsgi.wsgi_req->hvec[j].iov_len, (char *)uwsgi.wsgi_req->hvec[j].iov_base, uwsgi.wsgi_req->hvec[j+2].iov_len, (char *) uwsgi.wsgi_req->hvec[j+2].iov_base);
|
||||
}
|
||||
|
||||
|
||||
#ifdef UNBIT
|
||||
if (save_to_disk >= 0) {
|
||||
for (j = 0; j < i; j += 4) {
|
||||
if (!strncasecmp(uwsgi.hvec[j].iov_base, "Set-Cookie", uwsgi.hvec[j].iov_len)) {
|
||||
if (!strncasecmp(uwsgi.wsgi_req->hvec[j].iov_base, "Set-Cookie", uwsgi.wsgi_req->hvec[j].iov_len)) {
|
||||
close(save_to_disk);
|
||||
save_to_disk = -1;
|
||||
break;
|
||||
@@ -420,10 +420,10 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
|
||||
// \r\n
|
||||
j = (i * 4) + base;
|
||||
uwsgi.hvec[j].iov_base = nl;
|
||||
uwsgi.hvec[j].iov_len = NL_SIZE;
|
||||
uwsgi.wsgi_req->hvec[j].iov_base = nl;
|
||||
uwsgi.wsgi_req->hvec[j].iov_len = NL_SIZE;
|
||||
|
||||
uwsgi.wsgi_req->headers_size = writev(uwsgi.wsgi_req->poll.fd, uwsgi.hvec, j + 1);
|
||||
uwsgi.wsgi_req->headers_size = writev(uwsgi.wsgi_req->poll.fd, uwsgi.wsgi_req->hvec, j + 1);
|
||||
if (uwsgi.wsgi_req->headers_size < 0) {
|
||||
perror("writev()");
|
||||
}
|
||||
@@ -515,6 +515,10 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
|
||||
int rlen;
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
int current_async_timeout = 0;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_NAGIOS
|
||||
int nagios = 0;
|
||||
#endif
|
||||
@@ -844,7 +848,6 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
|
||||
fprintf(stderr, "allocated %d bytes for %d request's buffer.\n", uwsgi.buffer_size, uwsgi.async);
|
||||
|
||||
|
||||
if (uwsgi.synclog) {
|
||||
fprintf(stderr, "allocating a memory page for synced logging.\n");
|
||||
uwsgi.sync_page = malloc(uwsgi.page_size);
|
||||
@@ -1600,8 +1603,8 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
|
||||
|
||||
|
||||
uwsgi.hvec = malloc(sizeof(struct iovec) * uwsgi.vec_size);
|
||||
if (uwsgi.hvec == NULL) {
|
||||
uwsgi.async_hvec = malloc((sizeof(struct iovec) * uwsgi.vec_size)*uwsgi.async);
|
||||
if (uwsgi.async_hvec == NULL) {
|
||||
fprintf(stderr, "unable to allocate memory for iovec.\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -1665,21 +1668,16 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
#ifdef UWSGI_ASYNC
|
||||
|
||||
if (uwsgi.async > 1) {
|
||||
#ifdef __linux__
|
||||
uwsgi.async_nevents = epoll_wait(uwsgi.async_queue, uwsgi.async_events, uwsgi.async, uwsgi.async_running);
|
||||
#elif defined(__sun__)
|
||||
#else
|
||||
if (uwsgi.async_running == 0) {
|
||||
uwsgi.async_nevents = kevent(uwsgi.async_queue, NULL, 0, uwsgi.async_events, uwsgi.async, &uwsgi.async_timeout);
|
||||
}
|
||||
else {
|
||||
uwsgi.async_nevents = kevent(uwsgi.async_queue, NULL, 0, uwsgi.async_events, uwsgi.async, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
current_async_timeout = async_get_timeout(&uwsgi) ;
|
||||
fprintf(stderr,"sleeping for %d secs\n", current_async_timeout);
|
||||
uwsgi.async_nevents = async_wait(uwsgi.async_queue, uwsgi.async_events, uwsgi.async, uwsgi.async_running, current_async_timeout);
|
||||
async_expire_timeouts(&uwsgi);
|
||||
|
||||
if (uwsgi.async_nevents < 0) {
|
||||
perror("epoll_wait()");
|
||||
continue;
|
||||
}
|
||||
|
||||
for(i=0; i<uwsgi.async_nevents;i++) {
|
||||
|
||||
if (uwsgi.async_events[i].ASYNC_FD == uwsgi.serverfd) {
|
||||
@@ -1697,8 +1695,10 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
uwsgi.wsgi_req->sendfile_fd = -1;
|
||||
#endif
|
||||
|
||||
uwsgi.wsgi_req->async_id = ( (uint8_t *) uwsgi.wsgi_req - (uint8_t *) uwsgi.wsgi_requests)/(sizeof(struct wsgi_request)+(uwsgi.buffer_size-1)) ;
|
||||
|
||||
uwsgi.wsgi_req->hvec = &uwsgi.async_hvec[uwsgi.wsgi_req->async_id];
|
||||
uwsgi.wsgi_req->poll.fd = accept(uwsgi.serverfd, (struct sockaddr *) &c_addr, (socklen_t *) & c_len);
|
||||
fprintf(stderr,"accepted request\n");
|
||||
|
||||
if (uwsgi.wsgi_req->poll.fd < 0) {
|
||||
perror("accept()");
|
||||
@@ -1720,6 +1720,9 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
}
|
||||
|
||||
uwsgi.wsgi_req->async_status = (*uwsgi.shared->hooks[uwsgi.wsgi_req->modifier]) (&uwsgi, uwsgi.wsgi_req);
|
||||
if (uwsgi.wsgi_req->async_status == UWSGI_OK) {
|
||||
goto reqclear;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
@@ -1748,9 +1751,11 @@ cycle:
|
||||
|
||||
uwsgi.wsgi_req->poll.events = POLLIN;
|
||||
uwsgi.wsgi_req->app_id = uwsgi.default_app;
|
||||
uwsgi.wsgi_req->async_id = 0;
|
||||
#ifdef UWSGI_SENDFILE
|
||||
uwsgi.wsgi_req->sendfile_fd = -1;
|
||||
#endif
|
||||
uwsgi.wsgi_req->hvec = &uwsgi.async_hvec[uwsgi.wsgi_req->async_id];
|
||||
|
||||
|
||||
uwsgi.wsgi_req->poll.fd = accept(uwsgi.serverfd, (struct sockaddr *) &c_addr, (socklen_t *) & c_len);
|
||||
@@ -1780,6 +1785,9 @@ cycle:
|
||||
}
|
||||
#endif
|
||||
|
||||
reqclear:
|
||||
|
||||
|
||||
gettimeofday(&uwsgi.wsgi_req->end_of_request, NULL);
|
||||
uwsgi.workers[uwsgi.mywid].running_time += (double) (((double) (uwsgi.wsgi_req->end_of_request.tv_sec * 1000000 + uwsgi.wsgi_req->end_of_request.tv_usec) - (double) (uwsgi.wsgi_req->start_of_request.tv_sec * 1000000 + uwsgi.wsgi_req->start_of_request.tv_usec)) / (double) 1000.0);
|
||||
|
||||
@@ -1884,6 +1892,9 @@ int init_uwsgi_app(PyObject * force_wsgi_dict, PyObject * my_callable) {
|
||||
PyObject *pycprof, *pycprof_dict;
|
||||
char tmpstring[256];
|
||||
int id;
|
||||
#ifdef UWSGI_ASYNC
|
||||
int i;
|
||||
#endif
|
||||
|
||||
struct uwsgi_app *wi;
|
||||
|
||||
@@ -2030,6 +2041,40 @@ int init_uwsgi_app(PyObject * force_wsgi_dict, PyObject * my_callable) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
wi->wsgi_environ = malloc(sizeof(PyObject*)*uwsgi.async);
|
||||
if (!wi->wsgi_environ) {
|
||||
perror("malloc()");
|
||||
if (uwsgi.single_interpreter == 0) {
|
||||
Py_EndInterpreter(wi->interpreter);
|
||||
PyThreadState_Swap(uwsgi.main_thread) ;
|
||||
}
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
for(i=0;i<uwsgi.async;i++) {
|
||||
wi->wsgi_environ[i] = PyDict_New();
|
||||
// this will leak all the already allocated dictionary !!!
|
||||
if (!wi->wsgi_environ[i]) {
|
||||
if (uwsgi.single_interpreter == 0) {
|
||||
Py_EndInterpreter(wi->interpreter);
|
||||
PyThreadState_Swap(uwsgi.main_thread) ;
|
||||
}
|
||||
return -1 ;
|
||||
}
|
||||
}
|
||||
#else
|
||||
wi->wsgi_environ = PyDict_New();
|
||||
if (!wi->wsgi_environ) {
|
||||
PyErr_Print();
|
||||
if (uwsgi.single_interpreter == 0) {
|
||||
Py_EndInterpreter(wi->interpreter);
|
||||
PyThreadState_Swap(uwsgi.main_thread) ;
|
||||
}
|
||||
return -1 ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (wsgi_dict) {
|
||||
wi->wsgi_harakiri = PyDict_GetItemString(wsgi_dict, "harakiri");
|
||||
@@ -2056,12 +2101,7 @@ int init_uwsgi_app(PyObject * force_wsgi_dict, PyObject * my_callable) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
if (PyDict_SetItem(wi->pymain_dict, PyString_FromFormat("uwsgi_environ__%d", id), wi->wsgi_environ)) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
*/
|
||||
|
||||
if (PyDict_SetItem(wi->pymain_dict, PyString_FromFormat("uwsgi_spit__%d", id), wsgi_spitout)) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
|
||||
@@ -207,6 +207,12 @@ struct uwsgi_app {
|
||||
|
||||
PyObject *wsgi_callable;
|
||||
PyObject *wsgi_args;
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
PyObject **wsgi_environ;
|
||||
#else
|
||||
PyObject *wsgi_environ;
|
||||
#endif
|
||||
PyObject *wsgi_harakiri;
|
||||
|
||||
PyObject *wsgi_sendfile;
|
||||
@@ -231,6 +237,8 @@ struct __attribute__ ((packed)) wsgi_request {
|
||||
|
||||
struct pollfd poll;
|
||||
|
||||
// iovec
|
||||
struct iovec *hvec;
|
||||
|
||||
struct timeval start_of_request;
|
||||
struct timeval end_of_request;
|
||||
@@ -274,12 +282,16 @@ struct __attribute__ ((packed)) wsgi_request {
|
||||
int response_size;
|
||||
int headers_size;
|
||||
|
||||
int async_id;
|
||||
int async_status ;
|
||||
int async_waiting_fd;
|
||||
int async_waiting_fd_type;
|
||||
int async_waiting_fd_monitored;
|
||||
int async_switches;
|
||||
|
||||
time_t async_timeout ;
|
||||
int async_timeout_expired ;
|
||||
|
||||
void *async_app;
|
||||
void *async_result;
|
||||
void *async_placeholder;
|
||||
@@ -317,6 +329,8 @@ struct uwsgi_server {
|
||||
char *proxy_socket_name;
|
||||
#endif
|
||||
|
||||
struct iovec *async_hvec;
|
||||
|
||||
struct rlimit rl;
|
||||
|
||||
char *binary_path;
|
||||
@@ -335,8 +349,6 @@ struct uwsgi_server {
|
||||
char *snmp_community;
|
||||
#endif
|
||||
|
||||
// iovec
|
||||
struct iovec *hvec;
|
||||
|
||||
int to_heaven;
|
||||
int to_hell;
|
||||
@@ -367,7 +379,6 @@ struct uwsgi_server {
|
||||
#elif defined(__sun__)
|
||||
#else
|
||||
struct kevent *async_events;
|
||||
struct timespec async_timeout;
|
||||
#endif
|
||||
|
||||
int max_vars;
|
||||
@@ -637,9 +648,14 @@ struct wsgi_request *find_first_available_wsgi_req(struct uwsgi_server *);
|
||||
struct wsgi_request *find_wsgi_req_by_fd(struct uwsgi_server *, int, int);
|
||||
|
||||
int async_add(int, int , int) ;
|
||||
int async_wait(int, void *, int, int, int);
|
||||
int async_del(int, int , int) ;
|
||||
int async_queue_init(int);
|
||||
|
||||
int async_get_timeout(struct uwsgi_server *);
|
||||
void async_set_timeout(struct wsgi_request *, time_t);
|
||||
void async_expire_timeouts(struct uwsgi_server *);
|
||||
|
||||
#ifdef __linux__
|
||||
#define ASYNC_FD data.fd
|
||||
#define ASYNC_EV events
|
||||
@@ -649,3 +665,7 @@ int async_queue_init(int);
|
||||
#define ASYNC_EV filter
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int manage_python_response(struct uwsgi_server *, struct wsgi_request *);
|
||||
int uwsgi_python_call(struct uwsgi_server *, struct wsgi_request *, PyObject *, PyObject *);
|
||||
PyObject *python_call(PyObject *, PyObject *);
|
||||
|
||||
+12
-23
@@ -46,38 +46,27 @@ int uwsgi_request_admin(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_re
|
||||
perror("write()");
|
||||
}
|
||||
|
||||
return 0;
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
/* uwsgi FASTFUNC|26 */
|
||||
int uwsgi_request_fastfunc(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyObject *zero, *func_result, *fchunk, *func_chunks;
|
||||
PyObject *ffunc;
|
||||
|
||||
zero = PyList_GetItem(uwsgi->fastfuncslist, wsgi_req->modifier_arg);
|
||||
if (zero) {
|
||||
#ifdef UWSGI_ASYNC
|
||||
if (wsgi_req->async_status == UWSGI_AGAIN) {
|
||||
return manage_python_response(uwsgi, wsgi_req);
|
||||
}
|
||||
#endif
|
||||
|
||||
ffunc = PyList_GetItem(uwsgi->fastfuncslist, wsgi_req->modifier_arg);
|
||||
if (ffunc) {
|
||||
fprintf(stderr, "managing fastfunc %d\n", wsgi_req->modifier_arg);
|
||||
func_result = PyEval_CallObject(zero, NULL);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
}
|
||||
if (func_result) {
|
||||
func_chunks = PyObject_GetIter(func_result);
|
||||
if (func_chunks) {
|
||||
while ((fchunk = PyIter_Next(func_chunks))) {
|
||||
if (PyString_Check(fchunk)) {
|
||||
wsgi_req->response_size += write(wsgi_req->poll.fd, PyString_AsString(fchunk), PyString_Size(fchunk));
|
||||
}
|
||||
Py_DECREF(fchunk);
|
||||
}
|
||||
Py_DECREF(func_chunks);
|
||||
}
|
||||
Py_DECREF(func_result);
|
||||
}
|
||||
return uwsgi_python_call(uwsgi, wsgi_req, ffunc, NULL);
|
||||
}
|
||||
PyErr_Clear();
|
||||
|
||||
return 0;
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
/* uwsgi MARSHAL|33 */
|
||||
|
||||
@@ -19,6 +19,27 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
#define UWSGI_LOGBASE "[- uWSGI -"
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
PyObject *py_uwsgi_async_sleep(PyObject * self, PyObject * args) {
|
||||
|
||||
float timeout ;
|
||||
time_t sec_timeout ;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "f:async_sleep", &timeout)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sec_timeout = (time_t) timeout ;
|
||||
|
||||
fprintf(stderr,"timeout sleep: %d\n", (int) sec_timeout);
|
||||
if (sec_timeout > 0) {
|
||||
async_set_timeout(uwsgi.wsgi_req, sec_timeout);
|
||||
}
|
||||
|
||||
return PyString_FromString("") ;
|
||||
}
|
||||
#endif
|
||||
|
||||
PyObject *py_uwsgi_warning(PyObject * self, PyObject * args) {
|
||||
char *message;
|
||||
int len;
|
||||
@@ -831,6 +852,9 @@ static PyMethodDef uwsgi_advanced_methods[] = {
|
||||
{"set_warning_message", py_uwsgi_warning, METH_VARARGS, ""},
|
||||
#ifdef UWSGI_MULTICAST
|
||||
{"send_multicast_message", py_uwsgi_multicast, METH_VARARGS, ""},
|
||||
#endif
|
||||
#ifdef UWSGI_ASYNC
|
||||
{"async_sleep", py_uwsgi_async_sleep, METH_VARARGS, ""},
|
||||
#endif
|
||||
//{"call_hook", py_uwsgi_call_hook, METH_VARARGS, ""},
|
||||
{NULL, NULL},
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ uwsgi_os = os.uname()[0]
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
gcc_list = ['utils', 'protocol', 'socket', 'logging', 'wsgi_handlers', 'uwsgi_handlers', 'uwsgi']
|
||||
gcc_list = ['utils', 'pyutils', 'protocol', 'socket', 'logging', 'wsgi_handlers', 'uwsgi_handlers', 'uwsgi']
|
||||
|
||||
# large file support
|
||||
cflags = ['-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64']
|
||||
|
||||
+43
-117
@@ -2,86 +2,29 @@
|
||||
|
||||
static int uwsgi_sendfile(struct uwsgi_server *, int, int);
|
||||
|
||||
static PyObject *wsgi_response(PyObject *chunks, struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyObject *wchunk ;
|
||||
ssize_t wsize ;
|
||||
|
||||
wchunk = PyIter_Next(chunks) ;
|
||||
|
||||
|
||||
if (!wchunk) {
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Print();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyString_Check(wchunk)) {
|
||||
if ((wsize = write(wsgi_req->poll.fd, PyString_AsString(wchunk), PyString_Size(wchunk))) < 0) {
|
||||
perror("write()");
|
||||
return NULL;
|
||||
}
|
||||
wsgi_req->response_size += wsize;
|
||||
|
||||
#ifdef UNBIT
|
||||
if (save_to_disk >= 0) {
|
||||
if (write(save_to_disk, PyString_AsString(wchunk), PyString_Size(wchunk)) < 0) {
|
||||
perror("write()");
|
||||
close(save_to_disk);
|
||||
save_to_disk = -1;
|
||||
unlinkat(tmp_dir_fd, tmp_filename, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
return wchunk;
|
||||
|
||||
}
|
||||
|
||||
static void wsgi_end(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyErr_Clear();
|
||||
|
||||
Py_XDECREF(wsgi_req->async_placeholder);
|
||||
Py_XDECREF(wsgi_req->async_environ);
|
||||
fclose(wsgi_req->async_post);
|
||||
|
||||
#ifdef UWSGI_THREADING
|
||||
if (uwsgi->has_threads && uwsgi->shared->options[UWSGI_OPTION_THREADS] == 1) {
|
||||
uwsgi->_save = PyEval_SaveThread();
|
||||
uwsgi->workers[uwsgi->mywid].i_have_gil = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
|
||||
|
||||
int i;
|
||||
struct uwsgi_app *wi;
|
||||
|
||||
PyObject *zero, *wsgi_socket;
|
||||
|
||||
PyObject *pydictkey, *pydictvalue;
|
||||
|
||||
char *path_info;
|
||||
|
||||
PyObject *wchunk;
|
||||
struct uwsgi_app *wi ;
|
||||
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
if (wsgi_req->async_status == UWSGI_AGAIN) {
|
||||
wchunk = wsgi_response(wsgi_req->async_placeholder, wsgi_req);
|
||||
if (!wchunk) {
|
||||
wsgi_end(uwsgi, wsgi_req);
|
||||
return UWSGI_OK ;
|
||||
// get rid of timeout
|
||||
if (wsgi_req->async_timeout_expired) {
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.timeout", Py_True);
|
||||
wsgi_req->async_timeout_expired = 0 ;
|
||||
}
|
||||
Py_DECREF(wchunk);
|
||||
wsgi_req->async_switches++;
|
||||
return UWSGI_AGAIN ;
|
||||
else {
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.timeout", Py_None);
|
||||
}
|
||||
return manage_python_response(uwsgi, wsgi_req);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -116,7 +59,8 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req
|
||||
if (wsgi_req->wsgi_script_len > 0 || (wsgi_req->wsgi_callable_len > 0 && wsgi_req->wsgi_module_len > 0)) {
|
||||
if ((wsgi_req->app_id = init_uwsgi_app(NULL, NULL)) == -1) {
|
||||
internal_server_error(wsgi_req->poll.fd, "wsgi application not found");
|
||||
wsgi_end(uwsgi, wsgi_req);
|
||||
Py_DECREF(zero);
|
||||
goto clear2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,7 +70,7 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req
|
||||
|
||||
if (wsgi_req->app_id == -1) {
|
||||
internal_server_error(wsgi_req->poll.fd, "wsgi application not found");
|
||||
wsgi_end(uwsgi, wsgi_req);
|
||||
goto clear2;
|
||||
|
||||
}
|
||||
|
||||
@@ -136,35 +80,40 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req
|
||||
if (uwsgi->single_interpreter == 0) {
|
||||
if (!wi->interpreter) {
|
||||
internal_server_error(wsgi_req->poll.fd, "wsgi application's %d interpreter not found");
|
||||
wsgi_end(uwsgi, wsgi_req);
|
||||
goto clear2;
|
||||
}
|
||||
|
||||
// set the interpreter
|
||||
PyThreadState_Swap(wi->interpreter);
|
||||
}
|
||||
|
||||
wi->requests++;
|
||||
|
||||
|
||||
if (wsgi_req->protocol_len < 5) {
|
||||
fprintf(stderr, "INVALID PROTOCOL: %.*s", wsgi_req->protocol_len, wsgi_req->protocol);
|
||||
internal_server_error(wsgi_req->poll.fd, "invalid HTTP protocol !!!");
|
||||
wsgi_end(uwsgi, wsgi_req);
|
||||
goto clear;
|
||||
|
||||
}
|
||||
if (strncmp(wsgi_req->protocol, "HTTP/", 5)) {
|
||||
fprintf(stderr, "INVALID PROTOCOL: %.*s", wsgi_req->protocol_len, wsgi_req->protocol);
|
||||
internal_server_error(wsgi_req->poll.fd, "invalid HTTP protocol !!!");
|
||||
wsgi_end(uwsgi, wsgi_req);
|
||||
goto clear;
|
||||
}
|
||||
|
||||
|
||||
wsgi_req->async_environ = PyDict_New();
|
||||
#ifdef UWSGI_ASYNC
|
||||
wsgi_req->async_environ = wi->wsgi_environ[wsgi_req->async_id];
|
||||
#else
|
||||
wsgi_req->async_environ = wi->wsgi_environ;
|
||||
#endif
|
||||
Py_INCREF(wsgi_req->async_environ);
|
||||
|
||||
for (i = 0; i < wsgi_req->var_cnt; i += 2) {
|
||||
/*fprintf(stderr,"%.*s: %.*s\n", uwsgi->hvec[i].iov_len, uwsgi->hvec[i].iov_base, uwsgi->hvec[i+1].iov_len, uwsgi->hvec[i+1].iov_base); */
|
||||
pydictkey = PyString_FromStringAndSize(uwsgi->hvec[i].iov_base, uwsgi->hvec[i].iov_len);
|
||||
pydictvalue = PyString_FromStringAndSize(uwsgi->hvec[i + 1].iov_base, uwsgi->hvec[i + 1].iov_len);
|
||||
/*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);
|
||||
pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
|
||||
PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue);
|
||||
Py_DECREF(pydictkey);
|
||||
Py_DECREF(pydictvalue);
|
||||
@@ -203,6 +152,7 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req
|
||||
if (uwsgi->async > 1) {
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.readable", wi->wsgi_eventfd_read);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.writable", wi->wsgi_eventfd_write);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.timeout", Py_None);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -243,38 +193,25 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.url_scheme", zero);
|
||||
Py_DECREF(zero);
|
||||
|
||||
#ifdef UNBIT
|
||||
if (wsgi_req->unbit_flags & (unsigned long long) 1) {
|
||||
if (uri_to_hex() <= 0) {
|
||||
tmp_filename[0] = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
PyTuple_SetItem(wi->wsgi_args, 0, wsgi_req->async_environ);
|
||||
|
||||
// call
|
||||
#ifdef UWSGI_PROFILER
|
||||
if (uwsgi->enable_profiler == 1) {
|
||||
wsgi_req->async_result = PyEval_CallObject(wi->wsgi_cprofile_run, wi->wsgi_args);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
}
|
||||
PyDict_SetItem(wi->pymain_dict, PyString_FromFormat("uwsgi_environ__%d", wsgi_req->app_id), wsgi_req->async_environ);
|
||||
wsgi_req->async_result = python_call(wi->wsgi_cprofile_run, wi->wsgi_args);
|
||||
if (wsgi_req->async_result) {
|
||||
Py_DECREF(wsgi_req->async_result);
|
||||
wsgi_req->async_result = PyDict_GetItemString(wi->pymain_dict, "uwsgi_out");
|
||||
Py_INCREF(wsgi_req->async_result);
|
||||
Py_INCREF(wsgi_req->async_result);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
|
||||
wsgi_req->async_result = PyEval_CallObject(wi->wsgi_callable, wi->wsgi_args);
|
||||
PyTuple_SetItem(wi->wsgi_args, 0, wsgi_req->async_environ);
|
||||
wsgi_req->async_result = python_call(wi->wsgi_callable, wi->wsgi_args);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
}
|
||||
#ifdef UWSGI_PROFILER
|
||||
}
|
||||
#endif
|
||||
@@ -286,33 +223,24 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req
|
||||
#ifdef UWSGI_SENDFILE
|
||||
if (wsgi_req->sendfile_fd > -1) {
|
||||
wsgi_req->response_size = uwsgi_sendfile(uwsgi, wsgi_req->sendfile_fd, wsgi_req->poll.fd);
|
||||
if (wsgi_req->async_environ) {
|
||||
PyDict_Clear(wsgi_req->async_environ);
|
||||
}
|
||||
if (wsgi_req->async_post) {
|
||||
fclose(wsgi_req->async_post);
|
||||
}
|
||||
Py_DECREF(wsgi_req->async_result);
|
||||
}
|
||||
else {
|
||||
|
||||
#endif
|
||||
|
||||
wsgi_req->async_placeholder = PyObject_GetIter(wsgi_req->async_result);
|
||||
if (wsgi_req->async_placeholder) {
|
||||
while ( manage_python_response(uwsgi, wsgi_req) != UWSGI_OK) {
|
||||
//fprintf(stderr,"WSGI CYCLE\n");
|
||||
#ifdef UWSGI_ASYNC
|
||||
if (uwsgi->async > 1) {
|
||||
return UWSGI_AGAIN;
|
||||
}
|
||||
|
||||
while ( (wchunk = wsgi_response(wsgi_req->async_placeholder, wsgi_req)) ) {
|
||||
wsgi_req->async_switches++;
|
||||
Py_DECREF(wchunk);
|
||||
}
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
|
||||
#ifdef UNBIT
|
||||
else if (save_to_disk >= 0) {
|
||||
close(save_to_disk);
|
||||
save_to_disk = -1;
|
||||
fprintf(stderr, "[uWSGI cacher] output of request %llu (%.*s) on pid %d written to cache file %s\n", uwsgi->workers[0].requests + 1, wsgi_req->uri_len, wsgi_req->uri, uwsgi->mypid, tmp_filename);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -323,14 +251,12 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req
|
||||
}
|
||||
|
||||
|
||||
wsgi_end(uwsgi, wsgi_req);
|
||||
|
||||
wi->requests++;
|
||||
|
||||
clear:
|
||||
if (uwsgi->single_interpreter == 0) {
|
||||
// restoring main interpreter
|
||||
PyThreadState_Swap(uwsgi->main_thread);
|
||||
}
|
||||
clear2:
|
||||
|
||||
|
||||
return UWSGI_OK;
|
||||
|
||||
Reference in New Issue
Block a user