Return-Path: Delivered-To: apmail-apache-cvs-archive@apache.org Received: (qmail 15218 invoked by uid 500); 6 Jul 2000 15:13:38 -0000 Mailing-List: contact apache-cvs-help@apache.org; run by ezmlm Precedence: bulk X-No-Archive: yes Reply-To: new-httpd@apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list apache-cvs@apache.org Received: (qmail 15203 invoked by uid 500); 6 Jul 2000 15:13:37 -0000 Delivered-To: apmail-apache-2.0-cvs@apache.org Date: Thu, 6 Jul 2000 08:13:32 -0700 (PDT) From: Bill Stoddard Message-Id: <200007061513.IAA15191@locus.apache.org> To: apache-2.0-cvs@apache.org Subject: cvs commit: apache-2.0/src/modules/standard mod_file_cache.c stoddard 00/07/06 08:13:31 Modified: src CHANGES src/lib/apr/include apr_network_io.h src/lib/apr/network_io/unix sendrecv.c src/lib/apr/network_io/win32 networkio.h sendrecv.c sockets.c sockopt.c src/main http_protocol.c src/modules/mpm/winnt mpm_winnt.c src/modules/standard mod_file_cache.c Log: WinNT: Implement acceptex socket reuse. Make sure that the ap_sendfile flags argument is properly initialized for all platforms. Revision Changes Path 1.168 +15 -0 apache-2.0/src/CHANGES Index: CHANGES =================================================================== RCS file: /home/cvs/apache-2.0/src/CHANGES,v retrieving revision 1.167 retrieving revision 1.168 diff -u -r1.167 -r1.168 --- CHANGES 2000/06/28 16:55:51 1.167 +++ CHANGES 2000/07/06 15:13:21 1.168 @@ -1,4 +1,19 @@ Changes with Apache 2.0a5 + *) WinNT: Implement accept socket reuse. Using mod_file_cache to + cache open file handles along with accept socket reuse enables + Apache 2.0 to serve non-keepalive requests for static files at + 3x the rate of Apache 1.3.(e.g, Apache 1.3 will serve 400 rps + and Apache 2.0 will serve almost 1200 rps on my system). + [Bill Stoddard] + + *) Merge mod_mmap_static function into mod_file_cache. mod_file_cache + supports two config directives, mmapfile (same behavious as + mod_mmap_static) and cachefile. Use the cachefile directive + to cache open file handles. This directive only works on systems + that have implemented the ap_sendfile API. cachefile works today + on Windows NT, but has not been tested on any flavors of Unix. + [Bill Stoddard] + *) Cleanup the configuration. With the last few changes the configuration process automatically: inherits information about how to build from APR. Allowing 1.45 +4 -1 apache-2.0/src/lib/apr/include/apr_network_io.h Index: apr_network_io.h =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_network_io.h,v retrieving revision 1.44 retrieving revision 1.45 diff -u -r1.44 -r1.45 --- apr_network_io.h 2000/06/29 14:41:22 1.44 +++ apr_network_io.h 2000/07/06 15:13:22 1.45 @@ -87,6 +87,7 @@ #define APR_SO_TIMEOUT 32 #define APR_SO_SNDBUF 64 #define APR_SO_RCVBUF 128 +#define APR_SO_DISCONNECTED 256 #define APR_POLLIN 0x001 #define APR_POLLPRI 0x002 @@ -358,7 +359,7 @@ arg 3) A structure containing the headers and trailers to send arg 4) Offset into the file where we should begin writing arg 5) Number of bytes to send - arg 6) OS-specific flags to pass to sendfile() + arg 6) APR flags that are mapped to OS specific flags B: This functions acts like a blocking write by default. To change this behavior, use ap_setsocketopt with the APR_SO_TIMEOUT option. @@ -440,6 +441,8 @@ don't wait at all. APR_SO_SNDBUF -- Set the SendBufferSize APR_SO_RCVBUF -- Set the ReceiveBufferSize + APR_SO_DISCONNECTED -- Query the disconnected state of the socket. + (Currently only used on Windows) arg 3) Socket option returned on the call. =cut 1.30 +11 -0 apache-2.0/src/lib/apr/network_io/unix/sendrecv.c Index: sendrecv.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sendrecv.c,v retrieving revision 1.29 retrieving revision 1.30 diff -u -r1.29 -r1.30 --- sendrecv.c 2000/06/27 20:37:50 1.29 +++ sendrecv.c 2000/07/06 15:13:23 1.30 @@ -221,6 +221,9 @@ int rv, nbytes = 0; ap_status_t arv; + /* Ignore flags for now. */ + flags = 0; + /* TCP_CORK keeps us from sending partial frames when we shouldn't */ rv = setsockopt(sock->socketdes, SOL_TCP, TCP_CORK, (const void *) &corkflag, sizeof(corkflag)); @@ -310,6 +313,9 @@ struct sf_hdtr headerstruct; size_t bytes_to_send = *len; + /* Ignore flags for now. */ + flags = 0; + /* On FreeBSD, the number of bytes to send must include the length of * the headers. Don't look at the man page for this :( Instead, look * at the the logic in src/sys/kern/uipc_syscalls::sendfile(). @@ -380,6 +386,8 @@ struct iovec hdtrarray[2]; void *headerbuf, *trailerbuf; + /* Ignore flags for now. */ + flags = 0; /* HP-UX can only send one header iovec and one footer iovec */ @@ -479,6 +487,9 @@ void * hbuf=NULL, * tbuf=NULL; ap_status_t arv; struct sf_parms parms; + + /* Ignore flags for now. */ + flags = 0; /* AIX can also send the headers/footers as part of the system call */ parms.header_length = 0; 1.11 +1 -0 apache-2.0/src/lib/apr/network_io/win32/networkio.h Index: networkio.h =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/win32/networkio.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- networkio.h 2000/04/16 16:59:39 1.10 +++ networkio.h 2000/07/06 15:13:25 1.11 @@ -65,6 +65,7 @@ struct sockaddr_in *remote_addr; size_t addr_len; ap_interval_time_t timeout; + ap_int32_t disconnected; }; struct ap_pollfd_t { 1.21 +12 -1 apache-2.0/src/lib/apr/network_io/win32/sendrecv.c Index: sendrecv.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/win32/sendrecv.c,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- sendrecv.c 2000/06/22 19:33:20 1.20 +++ sendrecv.c 2000/07/06 15:13:25 1.21 @@ -144,7 +144,7 @@ * arg 3) A structure containing the headers and trailers to send * arg 4) Offset into the file where we should begin writing * arg 5) Number of bytes to send - * arg 6) OS-specific flags to pass to sendfile() + * arg 6) APR flags that are mapped to OS specific flags */ ap_status_t ap_sendfile(ap_socket_t * sock, ap_file_t * file, ap_hdtr_t * hdtr, ap_off_t * offset, ap_size_t * len, @@ -168,6 +168,7 @@ int lasterror = APR_SUCCESS; DWORD dwFlags = 0; + /* Map APR flags to OS specific flags */ if (flags & APR_SENDFILE_DISCONNECT_SOCKET) { dwFlags |= TF_REUSE_SOCKET; dwFlags |= TF_DISCONNECT; @@ -252,6 +253,16 @@ lasterror = GetLastError(); } } + + /* Mark the socket as disconnected, but do not close it. + * Note: The application must have stored the socket prior to making + * the call to ap_sendfile in order to either reuse it or close it. + */ + if ((lasterror == APR_SUCCESS) && (flags & APR_SENDFILE_DISCONNECT_SOCKET)) { + sock->disconnected = 1; + sock->sock = INVALID_SOCKET; + } + #ifdef WAIT_FOR_EVENT CloseHandle(overlapped.hEvent); #endif 1.32 +19 -13 apache-2.0/src/lib/apr/network_io/win32/sockets.c Index: sockets.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/win32/sockets.c,v retrieving revision 1.31 retrieving revision 1.32 diff -u -r1.31 -r1.32 --- sockets.c 2000/06/26 20:37:46 1.31 +++ sockets.c 2000/07/06 15:13:25 1.32 @@ -63,18 +63,19 @@ static ap_status_t socket_cleanup(void *sock) { ap_socket_t *thesocket = sock; - if (closesocket(thesocket->sock) != SOCKET_ERROR) { + + if (thesocket->sock != INVALID_SOCKET) { + if (closesocket(thesocket->sock) == SOCKET_ERROR) { + return WSAGetLastError(); + } thesocket->sock = INVALID_SOCKET; - return APR_SUCCESS; - } - else { - return WSAGetLastError(); } + return APR_SUCCESS; } ap_status_t ap_create_tcp_socket(ap_socket_t **new, ap_pool_t *cont) { - (*new) = (ap_socket_t *)ap_palloc(cont, sizeof(ap_socket_t)); + (*new) = (ap_socket_t *)ap_pcalloc(cont, sizeof(ap_socket_t)); if ((*new) == NULL) { return APR_ENOMEM; @@ -82,7 +83,7 @@ (*new)->cntxt = cont; (*new)->local_addr = (struct sockaddr_in *)ap_pcalloc((*new)->cntxt, sizeof(struct sockaddr_in)); - (*new)->remote_addr = (struct sockaddr_in *)ap_palloc((*new)->cntxt, + (*new)->remote_addr = (struct sockaddr_in *)ap_pcalloc((*new)->cntxt, sizeof(struct sockaddr_in)); if (((*new)->local_addr == NULL) || ((*new)->remote_addr == NULL)) { @@ -104,8 +105,11 @@ (*new)->local_addr->sin_port = 0; (*new)->timeout = -1; + (*new)->disconnected = 0; + ap_register_cleanup((*new)->cntxt, (void *)(*new), socket_cleanup, ap_null_cleanup); + return APR_SUCCESS; } @@ -160,18 +164,19 @@ ap_status_t ap_accept(ap_socket_t **new, ap_socket_t *sock, ap_pool_t *connection_context) { - (*new) = (ap_socket_t *)ap_palloc(connection_context, + (*new) = (ap_socket_t *)ap_pcalloc(connection_context, sizeof(ap_socket_t)); (*new)->cntxt = connection_context; - (*new)->local_addr = (struct sockaddr_in *)ap_palloc((*new)->cntxt, + (*new)->local_addr = (struct sockaddr_in *)ap_pcalloc((*new)->cntxt, sizeof(struct sockaddr_in)); - (*new)->remote_addr = (struct sockaddr_in *)ap_palloc((*new)->cntxt, + (*new)->remote_addr = (struct sockaddr_in *)ap_pcalloc((*new)->cntxt, sizeof(struct sockaddr_in)); memcpy((*new)->local_addr, sock->local_addr, sizeof(struct sockaddr_in)); (*new)->addr_len = sizeof(struct sockaddr_in); (*new)->timeout = -1; + (*new)->disconnected = 0; (*new)->sock = accept(sock->sock, (struct sockaddr *)(*new)->local_addr, &(*new)->addr_len); @@ -251,11 +256,11 @@ return APR_ENOPOOL; } if ((*sock) == NULL) { - (*sock) = (ap_socket_t *)ap_palloc(cont, sizeof(ap_socket_t)); + (*sock) = (ap_socket_t *)ap_pcalloc(cont, sizeof(ap_socket_t)); (*sock)->cntxt = cont; - (*sock)->local_addr = (struct sockaddr_in *)ap_palloc((*sock)->cntxt, + (*sock)->local_addr = (struct sockaddr_in *)ap_pcalloc((*sock)->cntxt, sizeof(struct sockaddr_in)); - (*sock)->remote_addr = (struct sockaddr_in *)ap_palloc((*sock)->cntxt, + (*sock)->remote_addr = (struct sockaddr_in *)ap_pcalloc((*sock)->cntxt, sizeof(struct sockaddr_in)); if ((*sock)->local_addr == NULL || (*sock)->remote_addr == NULL) { @@ -264,6 +269,7 @@ (*sock)->addr_len = sizeof(*(*sock)->local_addr); (*sock)->timeout = -1; + (*sock)->disconnected = 0; } (*sock)->sock = *thesock; return APR_SUCCESS; 1.20 +3 -0 apache-2.0/src/lib/apr/network_io/win32/sockopt.c Index: sockopt.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/win32/sockopt.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- sockopt.c 2000/06/27 02:23:29 1.19 +++ sockopt.c 2000/07/06 15:13:25 1.20 @@ -174,6 +174,9 @@ *on = sock->timeout * 1000; /* Convert from milliseconds (windows units) to microseconds * (APR units) */ break; + case APR_SO_DISCONNECTED: + *on = sock->disconnected; + break; case APR_SO_KEEPALIVE: case APR_SO_DEBUG: case APR_SO_REUSEADDR: 1.92 +10 -1 apache-2.0/src/main/http_protocol.c Index: http_protocol.c =================================================================== RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.91 retrieving revision 1.92 diff -u -r1.91 -r1.92 --- http_protocol.c 2000/07/05 18:00:58 1.91 +++ http_protocol.c 2000/07/06 15:13:28 1.92 @@ -2250,6 +2250,7 @@ { ap_size_t len = r->finfo.size; #if APR_HAS_SENDFILE + ap_int32_t flags = 0; if (!r->chunked) { ap_status_t rv; ap_bsetopt(r->connection->client, BO_TIMEOUT, @@ -2257,12 +2258,20 @@ ? &r->server->keep_alive_timeout : &r->server->timeout); ap_bflush(r->connection->client); + + if (!r->connection->keepalive) { + /* Prepare the socket to be reused. Ignored on systems + * that do not support reusing the accept socket + */ + flags |= APR_SENDFILE_DISCONNECT_SOCKET; + } + rv = iol_sendfile(r->connection->client->iol, fd, /* The file to send */ NULL, /* header and trailer iovecs */ 0, /* Offset in file to begin sending from */ &len, - 0); + flags); if (rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "ap_send_fd: iol_sendfile failed."); 1.84 +15 -3 apache-2.0/src/modules/mpm/winnt/mpm_winnt.c Index: mpm_winnt.c =================================================================== RCS file: /home/cvs/apache-2.0/src/modules/mpm/winnt/mpm_winnt.c,v retrieving revision 1.83 retrieving revision 1.84 diff -u -r1.83 -r1.84 --- mpm_winnt.c 2000/07/05 19:40:39 1.83 +++ mpm_winnt.c 2000/07/06 15:13:29 1.84 @@ -944,7 +944,6 @@ "reset_acceptex_context: AcceptEx failed for " "listening socket: %d and accept socket: %d", nsd, context->accept_socket); - context->accept_socket = INVALID_SOCKET; return lasterror; } } @@ -1071,6 +1070,7 @@ while (1) { conn_rec *current_conn; ap_iol *iol; + ap_int32_t disconnected; /* Grab a connection off the network */ if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { @@ -1099,8 +1099,20 @@ child_num); ap_process_connection(current_conn); - ap_lingering_close(current_conn); - context->accept_socket = INVALID_SOCKET; + + + ap_getsocketopt(context->sock, APR_SO_DISCONNECTED, &disconnected); + if (disconnected) { + /* Kill the clean-up registered by the iol. We want to leave + * the accept socket open because we are about to try to + * reuse it + */ + ap_bpop_iol(&iol, context->conn_io); + } + else { + context->accept_socket = INVALID_SOCKET; + ap_lingering_close(current_conn); + } } ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, server_conf, 1.14 +10 -2 apache-2.0/src/modules/standard/mod_file_cache.c Index: mod_file_cache.c =================================================================== RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_file_cache.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- mod_file_cache.c 2000/07/05 18:52:57 1.13 +++ mod_file_cache.c 2000/07/06 15:13:30 1.14 @@ -421,7 +421,15 @@ struct iovec iov; ap_hdtr_t hdtr; ap_hdtr_t *phdtr = &hdtr; + ap_int32_t flags = 0; + if (!r->connection->keepalive) { + /* Prepare the socket to be reused. Ignored on systems + * that do not support reusing the accept socket + */ + flags |= APR_SENDFILE_DISCONNECT_SOCKET; + } + /* * We want to send any data held in the client buffer on the * call to iol_sendfile. So hijack it then set outcnt to 0 @@ -446,7 +454,7 @@ phdtr, &offset, &length, - 0); + flags); } else { while (ap_each_byterange(r, &offset, &length)) { @@ -455,7 +463,7 @@ phdtr, &offset, &length, - 0); + flags); phdtr = NULL; } }