diff --git a/async.c b/async.c index d8a2a6af..4c25924c 100644 --- a/async.c +++ b/async.c @@ -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) { diff --git a/snmp.c b/snmp.c index 077ac2c8..54eaf3e7 100644 --- a/snmp.c +++ b/snmp.c @@ -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--; diff --git a/tests/cpubound_async.py b/tests/cpubound_async.py index 18ab1ceb..901392d6 100644 --- a/tests/cpubound_async.py +++ b/tests/cpubound_async.py @@ -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 "

%s

" % i diff --git a/uwsgi.c b/uwsgi.c index cf480b84..09a02399 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -35,10 +35,6 @@ in particular) #define Py_ssize_t ssize_t #endif -#ifdef __linux__ -#include -#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; ipoll.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); } } diff --git a/uwsgi.h b/uwsgi.h index c33c2bf0..c3c2404a 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -62,6 +62,10 @@ #ifdef __linux__ #include +#include +#elif defined(__sun___) +#else +#include #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 diff --git a/uwsgiconfig.py b/uwsgiconfig.py index eaafe4eb..74518dd3 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -14,7 +14,7 @@ PROFILER=True NAGIOS=True PROXY=True MINTERPRETERS=True -ASYNC=False +ASYNC=True PLUGINS = [] UWSGI_BIN_NAME = 'uwsgi' GCC='gcc'