From bf1f800cf4dbc4d63cebcc6f4c69451eff56c0aa Mon Sep 17 00:00:00 2001 From: "roberto@sirius" Date: Wed, 10 Mar 2010 15:50:06 +0100 Subject: [PATCH] epoll fixes --- apache2/mod_uwsgi.c | 22 ++++++++++++++-------- proxy.c | 24 +++++++++++++++++++++++- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/apache2/mod_uwsgi.c b/apache2/mod_uwsgi.c index 3f2bd2ce..67b4418c 100644 --- a/apache2/mod_uwsgi.c +++ b/apache2/mod_uwsgi.c @@ -253,7 +253,7 @@ static int uwsgi_handler(request_rec *r) { uint16_t pkt_size = 0; char buf[4096] ; int i ; - apr_size_t cnt ; + ssize_t cnt ; const apr_array_header_t *headers; apr_table_entry_t *h; char *penv, *cp; @@ -445,16 +445,24 @@ static int uwsgi_handler(request_rec *r) { uwsgi_poll.events = POLLIN ; + + for(;;) { /* put -1 to disable timeout on zero */ cnt = poll(&uwsgi_poll, 1, (c->socket_timeout*1000)-1) ; if (cnt == 0) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "uwsgi: recv() timeout"); - break; + apr_brigade_destroy(bb); + return HTTP_INTERNAL_SERVER_ERROR; } else if (cnt > 0) { cnt = recv(uwsgi_poll.fd, buf, 4096, 0) ; - if (cnt > 0) { + if (cnt < 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "uwsgi: recv() %s", strerror(errno)); + apr_brigade_destroy(bb); + return HTTP_INTERNAL_SERVER_ERROR; + } + else if (cnt > 0) { if (!c->cgi_mode && uwsgi_http_status_read < 12) { if (uwsgi_http_status_read + cnt >= 12) { memcpy(uwsgi_http_status+uwsgi_http_status_read, buf, 12-uwsgi_http_status_read); @@ -469,16 +477,14 @@ static int uwsgi_handler(request_rec *r) { apr_brigade_write(bb, NULL, NULL, buf, cnt); } - else if (cnt == 0) { - break; - } else { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "uwsgi: recv() %s", strerror(errno)); + break; } } else { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "uwsgi: poll() %s", strerror(errno)); - break; + apr_brigade_destroy(bb); + return HTTP_INTERNAL_SERVER_ERROR; } } diff --git a/proxy.c b/proxy.c index b10c0f60..97ea42d9 100644 --- a/proxy.c +++ b/proxy.c @@ -71,6 +71,24 @@ static void reload_proxy (void) { exit (UWSGI_RELOAD_CODE); } +static void send_http_service_unavailable(int fd) { + + if (write(fd, "HTTP/1.0 503 Service Unavailable\r\n", 34) != 34) { + perror("write()"); + return ; + } + + if (write(fd, "Content-type: text/html\r\n\r\n", 27) != 27) { + perror("write()"); + return ; + } + + if (write(fd, "

Service Unavailable

", 28) != 28) { + perror("write()"); + return ; + } + +} static void uwsgi_proxy_close(struct uwsgi_proxy_connection *upcs, int fd) { @@ -194,7 +212,7 @@ void uwsgi_proxy(int proxyfd) { } // allocate memory for events - events = malloc(sizeof(struct epoll_event)*max_events) ; + eevents = malloc(sizeof(struct epoll_event)*max_events) ; if (!eevents) { perror("malloc()"); exit(1); @@ -289,6 +307,7 @@ void uwsgi_proxy(int proxyfd) { next_node = uwsgi_proxy_find_next_node(next_node); if (next_node == -1) { fprintf(stderr,"unable to find an available worker in the cluster !\n"); + send_http_service_unavailable(NEV_FD); uwsgi_proxy_close(upcs, NEV_FD); continue; } @@ -449,6 +468,8 @@ void uwsgi_proxy(int proxyfd) { NEV_FD = upcs[NEV_FD].dest_fd ; upcs[NEV_FD].status = 0; + +#ifdef UWSGI_PROXY_USE_KQUEUE EV_SET(&kev, NEV_FD, EVFILT_WRITE, EV_ADD|EV_DISABLE, 0, 0, NULL); if (NEV_MOD) { perror(EV_NAME); @@ -456,6 +477,7 @@ void uwsgi_proxy(int proxyfd) { continue; } EV_SET(&kev, NEV_FD, EVFILT_READ, EV_ADD, 0, 0, NULL); +#endif if (NEV_MOD) { perror(EV_NAME); uwsgi_proxy_close(upcs, NEV_FD);