Return-Path: Delivered-To: apache-cvs-archive@hyperreal.org Received: (qmail 15507 invoked by uid 6000); 24 Feb 1999 20:30:24 -0000 Received: (qmail 15496 invoked by alias); 24 Feb 1999 20:30:21 -0000 Delivered-To: apache-apr-cvs@hyperreal.org Received: (qmail 15493 invoked by uid 236); 24 Feb 1999 20:30:21 -0000 Date: 24 Feb 1999 20:30:21 -0000 Message-ID: <19990224203021.15492.qmail@hyperreal.org> From: rbb@hyperreal.org To: apache-apr-cvs@hyperreal.org Subject: cvs commit: apache-apr/pthreads/src/main buff.c http_core.c http_main.c http_protocol.c Sender: apache-cvs-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org rbb 99/02/24 12:30:20 Modified: pthreads/src/include http_main.h httpd.h pthreads/src/main buff.c http_core.c http_main.c http_protocol.c Log: Implemented timeouts in the hybrid server. We are using non_blocking I/O and and poll to implement the timeouts. I will probably just implement recvwithtimeout on all systems, but this change lets us do some testing. The overall logic won't change with any subsequent change, just where the waiting is done. In order to use poll, we have to have our timeouts in milliseconds, so I convert from sec -> millisec when the user specifies a timeout in the config file. Lastly, I set the default timeout to 2 min. instead of five. May not be a good idea, but it helps me test easier. We can set it higher later if we have to. Revision Changes Path 1.4 +1 -0 apache-apr/pthreads/src/include/http_main.h Index: http_main.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/http_main.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- http_main.h 1999/02/09 21:39:52 1.3 +++ http_main.h 1999/02/24 20:30:14 1.4 @@ -115,6 +115,7 @@ void ap_start_shutdown(void); void ap_start_restart(int); void ap_keepalive_timeout(char *, request_rec *); +int ap_get_timeout(request_rec *r); API_EXPORT(void) ap_child_terminate(request_rec *r); int ap_update_child_status(int child_num, int thread_num, int status, request_rec *r); 1.9 +2 -2 apache-apr/pthreads/src/include/httpd.h Index: httpd.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/httpd.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- httpd.h 1999/02/16 16:00:47 1.8 +++ httpd.h 1999/02/24 20:30:14 1.9 @@ -258,12 +258,12 @@ /* The timeout for waiting for messages */ #ifndef DEFAULT_TIMEOUT -#define DEFAULT_TIMEOUT 300 +#define DEFAULT_TIMEOUT 120000 #endif /* The timeout for waiting for keepalive timeout until next request */ #ifndef DEFAULT_KEEPALIVE_TIMEOUT -#define DEFAULT_KEEPALIVE_TIMEOUT 15 +#define DEFAULT_KEEPALIVE_TIMEOUT 15000 #endif /* The number of requests to entertain per connection */ 1.3 +31 -5 apache-apr/pthreads/src/main/buff.c Index: buff.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/buff.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- buff.c 1999/02/07 06:29:30 1.2 +++ buff.c 1999/02/24 20:30:16 1.3 @@ -539,18 +539,44 @@ return value; } - API_EXPORT(int) ap_bnonblock(BUFF *fb, int direction) { APRFile fd; + int fd_flags; + + fd = (direction == B_RD) ? fb->fd_in : fb->fd; + fd_flags = fcntl(fd, F_GETFL, 0); +#if defined(O_NONBLOCK) + fd_flags |= O_NONBLOCK; + return fcntl(fd, F_SETFL, fd_flags); +#elif defined(O_NDELAY) + fd_flags |= O_NDELAY; + return fcntl(fd, F_SETFL, fd_flags); +#eli f defined(FNDELAY) + fd_flags |= O_FNDELAY; + return fcntl(fd, F_SETFL, fd_flags); +#else + /* XXXX: this breaks things, but an alternative isn't obvious...*/ + return 0; +#endif +} + +API_EXPORT(int) ap_bblock(BUFF *fb, int direction) +{ + APRFile fd; + int fd_flags; fd = (direction == B_RD) ? fb->fd_in : fb->fd; + fd_flags = fcntl(fd, F_GETFL, 0); #if defined(O_NONBLOCK) - return fcntl(fd, F_SETFL, O_NONBLOCK); + fd_flags &= ~O_NONBLOCK; + return fcntl(fd, F_SETFL, fd_flags); #elif defined(O_NDELAY) - return fcntl(fd, F_SETFL, O_NDELAY); -#elif defined(FNDELAY) - return fcntl(fd, F_SETFL, FNDELAY); + fd_flags &= ~O_NDELAY; + return fcntl(fd, F_SETFL, fd_flags); +#eli f defined(FNDELAY) + fd_flags &= ~O_FNDELAY; + return fcntl(fd, F_SETFL, fd_flags); #else /* XXXX: this breaks things, but an alternative isn't obvious...*/ return 0; 1.8 +2 -2 apache-apr/pthreads/src/main/http_core.c Index: http_core.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_core.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- http_core.c 1999/02/23 19:11:21 1.7 +++ http_core.c 1999/02/24 20:30:17 1.8 @@ -1965,7 +1965,7 @@ return err; } - cmd->server->timeout = atoi(arg); + cmd->server->timeout = atoi(arg) * 1000; return NULL; } @@ -1977,7 +1977,7 @@ return err; } - cmd->server->keep_alive_timeout = atoi(arg); + cmd->server->keep_alive_timeout = atoi(arg) * 1000; return NULL; } 1.55 +11 -0 apache-apr/pthreads/src/main/http_main.c Index: http_main.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_main.c,v retrieving revision 1.54 retrieving revision 1.55 diff -u -r1.54 -r1.55 --- http_main.c 1999/02/23 20:37:26 1.54 +++ http_main.c 1999/02/24 20:30:17 1.55 @@ -1005,6 +1005,17 @@ /*** End of accept serialization code. */ +int ap_get_timeout(request_rec *r) +{ + + if (r->connection->keptalive) { + return(r->server->keep_alive_timeout); + } + else { + return(r->server->timeout); + } +} + /* On some architectures it's safe to do unserialized accept()s in the single * Listen case. But it's never safe to do it in the case where there's * multiple Listen statements. Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT 1.5 +18 -2 apache-apr/pthreads/src/main/http_protocol.c Index: http_protocol.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_protocol.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- http_protocol.c 1999/02/07 06:29:31 1.4 +++ http_protocol.c 1999/02/24 20:30:18 1.5 @@ -902,7 +902,9 @@ pool *p; const char *expect; int access_status; + struct pollfd *filedes; + filedes = (struct pollfd *)malloc(sizeof(struct pollfd)); p = ap_make_sub_pool(conn->pool); r = ap_pcalloc(p, sizeof(request_rec)); r->pool = p; @@ -938,8 +940,19 @@ #endif /* Get the request... */ - - if (!read_request_line(r)) { + ap_bnonblock(r->connection->client, B_RD); + while (!read_request_line(r)) { + if (errno == EAGAIN) { + filedes->fd = r->connection->client->fd_in; + filedes->events = POLLIN; + filedes->revents = 0; + if (poll(filedes, 1, ap_get_timeout(r)) == 0) { + ap_bclose(r->connection->client); + } + else { + continue; + } + } if (r->status == HTTP_REQUEST_URI_TOO_LARGE) { ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, @@ -949,8 +962,11 @@ ap_log_transaction(r); return r; } + free(filedes); return NULL; } + free(filedes); + ap_bblock(r->connection->client, B_RD); if (!r->assbackwards) { get_mime_headers(r); if (r->status != HTTP_REQUEST_TIME_OUT) {