async support for BSD systems (kqueue based)

This commit is contained in:
roberto@fierobecco
2010-03-18 13:35:11 +01:00
parent 6805e5ee9f
commit 1caea3dbeb
6 changed files with 115 additions and 12 deletions
+62
View File
@@ -45,6 +45,68 @@ int async_add(int queuefd, int fd, int etype) {
return 0;
}
int async_del(int queuefd, int fd, int etype) {
struct epoll_event ee;
memset(&ee, 0, sizeof(struct epoll_event));
ee.events = etype;
ee.data.fd = fd;
if (epoll_ctl(queuefd, EPOLL_CTL_DEL, fd, &ee)) {
perror("epoll_ctl()");
return -1;
}
return 0;
}
#elif defined(__sun__)
#else
int async_queue_init(int serverfd) {
int kfd ;
struct kevent kev;
kfd = kqueue();
if (kfd < 0) {
perror("kqueue()");
return -1 ;
}
EV_SET(&kev, serverfd, EVFILT_READ, EV_ADD, 0, 0, NULL);
if (kevent(kfd, &kev, 1, NULL, 0, NULL) < 0) {
perror("kevent()");
return -1;
}
return kfd;
}
int async_add(int queuefd, int fd, int etype) {
struct kevent kev;
EV_SET(&kev, fd, etype, EV_ADD, 0, 0, NULL);
if (kevent(queuefd, &kev, 1, NULL, 0, NULL) < 0) {
perror("kevent()");
return -1;
}
return 0;
}
int async_del(int queuefd, int fd, int etype) {
struct kevent kev;
EV_SET(&kev, fd, etype, EV_DELETE, 0, 0, NULL);
if (kevent(queuefd, &kev, 1, NULL, 0, NULL) < 0) {
perror("kevent()");
return -1;
}
return 0;
}
#endif
struct wsgi_request *next_wsgi_req(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
+1 -1
View File
@@ -315,7 +315,7 @@ static ssize_t build_snmp_response(uint8_t oid1, uint8_t oid2, uint8_t * buffer,
buffer[size - 2] = oid_type;
oid_sz = snmp_int_to_snmp(snmp_val, oid_type, buffer + (size - 1));
if (oid_sz < 0)
if (oid_sz < 1)
return -1;
oid_sz--;
+1 -1
View File
@@ -1,5 +1,5 @@
def application(env, start_response):
start_response( '200 OK', [ ('Content-Type','text/html') ])
for i in range(1,100000):
for i in range(1,10000):
yield "<h1>%s</h1>" % i
+29 -9
View File
@@ -35,10 +35,6 @@ in particular)
#define Py_ssize_t ssize_t
#endif
#ifdef __linux__
#include <sys/epoll.h>
#endif
struct uwsgi_server uwsgi;
static char *nl = "\r\n";
@@ -236,7 +232,12 @@ PyObject *py_eventfd_read(PyObject * self, PyObject * args) {
if (fd >= 0) {
uwsgi.wsgi_req->async_waiting_fd = fd ;
#ifdef __linux__
uwsgi.wsgi_req->async_waiting_fd_type = EPOLLIN ;
#elif defined(__sun__)
#else
uwsgi.wsgi_req->async_waiting_fd_type = EVFILT_READ ;
#endif
uwsgi.wsgi_req->async_waiting_fd_monitored = 0 ;
}
@@ -253,7 +254,12 @@ PyObject *py_eventfd_write(PyObject * self, PyObject * args) {
if (fd >= 0) {
uwsgi.wsgi_req->async_waiting_fd = fd ;
#ifdef __linux__
uwsgi.wsgi_req->async_waiting_fd_type = EPOLLOUT ;
#elif defined(__sun__)
#else
uwsgi.wsgi_req->async_waiting_fd_type = EVFILT_WRITE ;
#endif
uwsgi.wsgi_req->async_waiting_fd_monitored = 0 ;
}
@@ -1072,7 +1078,12 @@ int main(int argc, char *argv[], char *envp[]) {
if (uwsgi.async_queue < 0) {
exit(1);
}
#ifdef __linux__
uwsgi.async_events = malloc( sizeof(struct epoll_event) * uwsgi.async ) ;
#elif defined(__sun__)
#else
uwsgi.async_events = malloc( sizeof(struct kevent) * uwsgi.async ) ;
#endif
if (!uwsgi.async_events) {
perror("malloc()");
exit(1);
@@ -1654,14 +1665,24 @@ 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
if (uwsgi.async_nevents < 0) {
perror("epoll_wait()");
continue;
}
for(i=0; i<uwsgi.async_nevents;i++) {
if (uwsgi.async_events[i].data.fd == uwsgi.serverfd) {
if (uwsgi.async_events[i].ASYNC_FD == uwsgi.serverfd) {
uwsgi.wsgi_req = find_first_available_wsgi_req(&uwsgi);
if (uwsgi.wsgi_req == NULL) {
@@ -1677,6 +1698,7 @@ int main(int argc, char *argv[], char *envp[]) {
#endif
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()");
@@ -1701,16 +1723,14 @@ int main(int argc, char *argv[], char *envp[]) {
}
else {
uwsgi.wsgi_req = find_wsgi_req_by_fd(&uwsgi, uwsgi.async_events[i].data.fd, uwsgi.async_events[i].events);
uwsgi.wsgi_req = find_wsgi_req_by_fd(&uwsgi, uwsgi.async_events[i].ASYNC_FD, uwsgi.async_events[i].ASYNC_EV);
if (uwsgi.wsgi_req) {
uwsgi.wsgi_req->async_status = UWSGI_AGAIN ;
uwsgi.wsgi_req->async_waiting_fd = -1 ;
uwsgi.wsgi_req->async_waiting_fd_monitored = 0 ;
}
if (epoll_ctl(uwsgi.async_queue, EPOLL_CTL_DEL, uwsgi.async_events[i].data.fd, &uwsgi.async_events[i])) {
perror("epoll_ctl()");
}
async_del(uwsgi.async_queue, uwsgi.async_events[i].ASYNC_FD, uwsgi.async_events[i].ASYNC_EV);
}
}
+21
View File
@@ -62,6 +62,10 @@
#ifdef __linux__
#include <sys/sendfile.h>
#include <sys/epoll.h>
#elif defined(__sun___)
#else
#include <sys/event.h>
#endif
#undef _XOPEN_SOURCE
@@ -357,8 +361,13 @@ struct uwsgi_server {
int async_running;
int async_queue ;
int async_nevents ;
#ifdef __linux__
struct epoll_event *async_events;
#elif defined(__sun__)
#else
struct kevent *async_events;
struct timespec async_timeout;
#endif
int max_vars;
@@ -626,5 +635,17 @@ 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);
int async_add(int, int , int) ;
int async_del(int, int , int) ;
int async_queue_init(int);
#ifdef __linux__
#define ASYNC_FD data.fd
#define ASYNC_EV events
#elif defined(__sun__)
#else
#define ASYNC_FD ident
#define ASYNC_EV filter
#endif
#endif
+1 -1
View File
@@ -14,7 +14,7 @@ PROFILER=True
NAGIOS=True
PROXY=True
MINTERPRETERS=True
ASYNC=False
ASYNC=True
PLUGINS = []
UWSGI_BIN_NAME = 'uwsgi'
GCC='gcc'