uGreen fd async waiting support

This commit is contained in:
roberto@sirius
2010-03-31 09:57:16 +02:00
parent 474860cd39
commit bdab4dcf84
4 changed files with 156 additions and 11 deletions
+16 -6
View File
@@ -279,12 +279,22 @@ struct wsgi_request *find_wsgi_req_by_fd(struct uwsgi_server *uwsgi, int fd, int
struct wsgi_request* wsgi_req = uwsgi->wsgi_requests ;
int i ;
for(i=0;i<uwsgi->async;i++) {
if (wsgi_req->async_waiting_fd == fd && wsgi_req->async_waiting_fd_type == etype) {
return wsgi_req ;
}
wsgi_req = next_wsgi_req(uwsgi, wsgi_req) ;
}
if (etype != -1) {
for(i=0;i<uwsgi->async;i++) {
if (wsgi_req->async_waiting_fd == fd && wsgi_req->async_waiting_fd_type == etype) {
return wsgi_req ;
}
wsgi_req = next_wsgi_req(uwsgi, wsgi_req) ;
}
}
else {
for(i=0;i<uwsgi->async;i++) {
if (wsgi_req->async_waiting_fd == fd) {
return wsgi_req ;
}
wsgi_req = next_wsgi_req(uwsgi, wsgi_req) ;
}
}
return NULL ;
+41
View File
@@ -0,0 +1,41 @@
import uwsgi
import socket
import errno
def send_request(env, client):
client.setblocking(1)
client.send(b"GET /intl/it_it/images/logo.gif HTTP/1.0\r\n")
client.send(b"Host: www.google.it\r\n\r\n")
uwsgi.green_schedule()
while 1:
uwsgi.green_wait_fdread(client.fileno(), 10)
buf = client.recv(4096)
if len(buf) == 0:
break
else:
yield buf
def application(env, start_response):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setblocking(0)
c = s.connect_ex(('74.125.77.104', 80))
if c == errno.EINPROGRESS:
uwsgi.green_wait_fdwrite(s.fileno(), 10)
for r in send_request(env, s):
yield r
elif c == errno.EISCONN:
for r in send_request(env, s):
yield r
else:
uwsgi.green_schedule()
start_response( '500 Internal Server Error', [ ('Content-Type', 'text/html')])
yield "Internal Server Error"
s.close()
+66 -5
View File
@@ -6,23 +6,22 @@
TODO
io and sleep management
io, timeout and sleep management
*/
#include "uwsgi.h"
#define UGREEN_DEFAULT_STACKSIZE 128*1024
#define UGREEN_DEFAULT_STACKSIZE 256*1024
extern struct uwsgi_server uwsgi;
static int u_green_blocking(struct uwsgi_server *uwsgi) {
struct wsgi_request* wsgi_req = uwsgi->wsgi_requests ;
int i ;
for(i=0;i<uwsgi->async;i++) {
if (wsgi_req->async_status != UWSGI_ACCEPTING) {
if (wsgi_req->async_status != UWSGI_ACCEPTING && wsgi_req->async_waiting_fd == -1) {
return 0 ;
}
wsgi_req = next_wsgi_req(uwsgi, wsgi_req) ;
@@ -65,6 +64,25 @@ inline static void u_green_schedule_to_req(struct uwsgi_server *uwsgi, struct ws
tstate->frame = py_current_frame ;
}
static void u_green_wait_for_fd(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, int fd, int etype, int timeout) {
if (fd < 0) return;
if (async_add(uwsgi->async_queue, fd, etype)) return ;
wsgi_req->async_waiting_fd = fd ;
wsgi_req->async_waiting_fd_type = etype;
wsgi_req->async_timeout = timeout ;
u_green_schedule_to_main(uwsgi, wsgi_req->async_id);
async_del(uwsgi->async_queue, wsgi_req->async_waiting_fd, wsgi_req->async_waiting_fd_type);
wsgi_req->async_waiting_fd = -1;
wsgi_req->async_timeout = 0 ;
}
PyObject *py_uwsgi_green_schedule(PyObject * self, PyObject * args) {
struct wsgi_request *wsgi_req = current_wsgi_req(&uwsgi);
@@ -76,8 +94,42 @@ PyObject *py_uwsgi_green_schedule(PyObject * self, PyObject * args) {
}
PyObject *py_uwsgi_green_wait_fdread(PyObject * self, PyObject * args) {
struct wsgi_request *wsgi_req = current_wsgi_req(&uwsgi);
int fd,timeout;
if (!PyArg_ParseTuple(args, "i|i", &fd, &timeout)) {
return NULL;
}
u_green_wait_for_fd(&uwsgi, wsgi_req, fd, ASYNC_IN, timeout);
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_green_wait_fdwrite(PyObject * self, PyObject * args) {
struct wsgi_request *wsgi_req = current_wsgi_req(&uwsgi);
int fd,timeout;
if (!PyArg_ParseTuple(args, "i|i", &fd, &timeout)) {
return NULL;
}
u_green_wait_for_fd(&uwsgi, wsgi_req, fd, ASYNC_OUT, timeout);
Py_INCREF(Py_True);
return Py_True;
}
PyMethodDef uwsgi_green_methods[] = {
{"green_schedule", py_uwsgi_green_schedule, METH_VARARGS, ""},
{"green_wait_fdread", py_uwsgi_green_wait_fdread, METH_VARARGS, ""},
{"green_wait_fdwrite", py_uwsgi_green_wait_fdwrite, METH_VARARGS, ""},
{ NULL, NULL }
};
@@ -218,12 +270,21 @@ void u_green_loop(struct uwsgi_server *uwsgi) {
if (uwsgi->async_events[i].ASYNC_FD == uwsgi->serverfd) {
u_green_schedule_to_req(uwsgi, wsgi_req);
}
else {
wsgi_req = find_wsgi_req_by_fd(uwsgi, uwsgi->async_events[i].ASYNC_FD, -1);
if (wsgi_req) {
u_green_schedule_to_req(uwsgi, wsgi_req);
}
else {
async_del(uwsgi->async_queue, uwsgi->async_events[i].ASYNC_FD, uwsgi->async_events[i].ASYNC_EV);
}
}
}
cycle:
wsgi_req = find_wsgi_req_by_id(uwsgi, current) ;
if (wsgi_req->async_status != UWSGI_ACCEPTING) {
if (wsgi_req->async_status != UWSGI_ACCEPTING && wsgi_req->async_waiting_fd == -1) {
u_green_schedule_to_req(uwsgi, wsgi_req);
}
current++;
+33
View File
@@ -18,6 +18,7 @@ ASYNC=True
UGREEN=True
STACKLESS=False
PLUGINS = []
UNBIT=False
UWSGI_BIN_NAME = 'uwsgi'
GCC='gcc'
@@ -101,6 +102,31 @@ def build_uwsgi(bin_name):
bin_name = './' + bin_name
print("*** uWSGI is ready, launch it with %s ***" % bin_name)
def unbit_setup():
global XML, SNMP, SCTP, ERLANG, SPOOLER
global EMBEDDED, UDP, MULTICAST, THREADING
global SENDFILE, PROFILER, NAGIOS, PROXY
global UWSGI_BIN_NAME
XML=False
SNMP=False
SCTP=False
ERLANG=False
UDP=False
MULTICAST=False
NAGIOS=False
PROXY=False
EMBEDDED=True
SPOOLER=True
THREADING=True
SENDFILE=True
PROFILER=True
UNBIT=True
UWSGI_BIN_NAME='/usr/share/unbit/uwsgi26'
def parse_vars():
@@ -211,6 +237,9 @@ def parse_vars():
cflags.append("-DUWSGI_SPOOLER")
gcc_list.append('spooler')
if UNBIT:
cflags.append("-DUWSGI_UNBIT")
def build_plugin(path):
path = path.rstrip('/')
@@ -255,6 +284,10 @@ if __name__ == "__main__":
elif cmd == '--build':
parse_vars()
build_uwsgi(UWSGI_BIN_NAME)
elif cmd == '--unbit':
unbit_setup()
parse_vars()
build_uwsgi(UWSGI_BIN_NAME)
elif cmd == '--plugin':
parse_vars()
build_plugin(sys.argv[2])