mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-07 14:11:46 +00:00
uGreen fd async waiting support
This commit is contained in:
@@ -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 ;
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -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++;
|
||||
|
||||
@@ -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])
|
||||
|
||||
Reference in New Issue
Block a user