Return-Path: Delivered-To: apmail-tomcat-dev-archive@www.apache.org Received: (qmail 58700 invoked from network); 1 Jul 2007 11:55:15 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 1 Jul 2007 11:55:15 -0000 Received: (qmail 11224 invoked by uid 500); 1 Jul 2007 11:55:10 -0000 Delivered-To: apmail-tomcat-dev-archive@tomcat.apache.org Received: (qmail 11169 invoked by uid 500); 1 Jul 2007 11:55:10 -0000 Mailing-List: contact dev-help@tomcat.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Tomcat Developers List" Delivered-To: mailing list dev@tomcat.apache.org Received: (qmail 11154 invoked by uid 500); 1 Jul 2007 11:55:10 -0000 Delivered-To: apmail-jakarta-tomcat-dev@jakarta.apache.org Received: (qmail 11151 invoked by uid 99); 1 Jul 2007 11:55:10 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 01 Jul 2007 04:55:10 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 01 Jul 2007 04:55:06 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 7CBDA1A981A; Sun, 1 Jul 2007 04:54:46 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r552292 - in /tomcat/connectors/trunk/jk/native/common: jk_ajp_common.c jk_connect.c Date: Sun, 01 Jul 2007 11:54:46 -0000 To: tomcat-dev@jakarta.apache.org From: mturk@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070701115446.7CBDA1A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mturk Date: Sun Jul 1 04:54:45 2007 New Revision: 552292 URL: http://svn.apache.org/viewvc?view=rev&rev=552292 Log: Use shutdown instead hard close for connected sockets. This ensures that the FIN will be send to the Tomcat thus switching from CLOSE_WAIT to TIME_WAIT. The rewritten shutdown_socket is basically Apache 1.3 linering_close. It needs testing, but mine tests shows the large decrease in CLOSE_WAIT socket states when connectionTimeout is set on Tomcat side. Modified: tomcat/connectors/trunk/jk/native/common/jk_ajp_common.c tomcat/connectors/trunk/jk/native/common/jk_connect.c Modified: tomcat/connectors/trunk/jk/native/common/jk_ajp_common.c URL: http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/common/jk_ajp_common.c?view=diff&rev=552292&r1=552291&r2=552292 ============================================================================== --- tomcat/connectors/trunk/jk/native/common/jk_ajp_common.c (original) +++ tomcat/connectors/trunk/jk/native/common/jk_ajp_common.c Sun Jul 1 04:54:45 2007 @@ -681,7 +681,7 @@ static void ajp_reset_endpoint(ajp_endpoint_t * ae, jk_logger_t *l) { if (IS_VALID_SOCKET(ae->sd) && !ae->reuse) { - jk_close_socket(ae->sd); + jk_shutdown_socket(ae->sd); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "reset socket with sd = %u", ae->sd ); @@ -720,11 +720,12 @@ { int rc; ajp_worker_t *aw = ae->worker; - jk_sock_t sock = ae->sd; + jk_sock_t sock; + JK_ENTER_CS(&aw->cs, rc); + sock = ae->sd; /* Mark existing endpoint socket as closed */ ae->sd = JK_INVALID_SOCKET; - JK_ENTER_CS(&aw->cs, rc); if (rc) { unsigned int i; for (i = 0; i < aw->ep_cache_sz; i++) { @@ -739,7 +740,7 @@ } /* Close previous socket */ if (IS_VALID_SOCKET(sock)) - jk_close_socket(sock); + jk_shutdown_socket(sock); } /* @@ -1195,7 +1196,7 @@ jk_log(l, JK_LOG_DEBUG, "(%s) socket %d is not connected any more (errno=%d)", ae->worker->name, ae->sd, errno); - jk_close_socket(ae->sd); + jk_shutdown_socket(ae->sd); ae->sd = JK_INVALID_SOCKET; err = 1; } @@ -1242,7 +1243,7 @@ jk_log(l, JK_LOG_ERROR, "(%s) error sending request. Unrecoverable operation", ae->worker->name); - jk_close_socket(ae->sd); + jk_shutdown_socket(ae->sd); ae->sd = JK_INVALID_SOCKET; JK_TRACE_EXIT(l); return JK_FALSE; @@ -1291,7 +1292,7 @@ */ if (ajp_connection_tcp_send_message(ae, op->request, l) != JK_TRUE) { /* Close the socket if unable to send request */ - jk_close_socket(ae->sd); + jk_shutdown_socket(ae->sd); ae->sd = JK_INVALID_SOCKET; jk_log(l, JK_LOG_INFO, "(%s) error sending request on a fresh connection (errno=%d)", @@ -1302,7 +1303,7 @@ } else { /* Close the socket if unable to connect */ - jk_close_socket(ae->sd); + jk_shutdown_socket(ae->sd); ae->sd = JK_INVALID_SOCKET; jk_log(l, JK_LOG_INFO, "(%s) error connecting to the backend server (errno=%d)", @@ -1336,7 +1337,7 @@ if (postlen > AJP_HEADER_LEN) { if (ajp_connection_tcp_send_message(ae, op->post, l) != JK_TRUE) { /* Close the socket if unable to send request */ - jk_close_socket(ae->sd); + jk_shutdown_socket(ae->sd); ae->sd = JK_INVALID_SOCKET; jk_log(l, JK_LOG_ERROR, "(%s) failed resending request body (%d)", ae->worker->name, postlen); @@ -1356,7 +1357,7 @@ if (postlen > AJP_HEADER_LEN) { if (ajp_connection_tcp_send_message(ae, s->reco_buf, l) != JK_TRUE) { /* Close the socket if unable to send request */ - jk_close_socket(ae->sd); + jk_shutdown_socket(ae->sd); ae->sd = JK_INVALID_SOCKET; jk_log(l, JK_LOG_ERROR, "(%s) failed resending request body (lb mode) (%d)", @@ -1406,7 +1407,7 @@ s->content_read = (jk_uint64_t)len; if (ajp_connection_tcp_send_message(ae, op->post, l) != JK_TRUE) { /* Close the socket if unable to send request */ - jk_close_socket(ae->sd); + jk_shutdown_socket(ae->sd); ae->sd = JK_INVALID_SOCKET; jk_log(l, JK_LOG_ERROR, "(%s) error sending request body", ae->worker->name); @@ -1751,7 +1752,7 @@ jk_log(l, JK_LOG_ERROR, "(%s) Tomcat is down or network problems", p->worker->name); - jk_close_socket(p->sd); + jk_shutdown_socket(p->sd); p->sd = JK_INVALID_SOCKET; JK_TRACE_EXIT(l); return JK_FALSE; Modified: tomcat/connectors/trunk/jk/native/common/jk_connect.c URL: http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/common/jk_connect.c?view=diff&rev=552292&r1=552291&r2=552292 ============================================================================== --- tomcat/connectors/trunk/jk/native/common/jk_connect.c (original) +++ tomcat/connectors/trunk/jk/native/common/jk_connect.c Sun Jul 1 04:54:45 2007 @@ -495,14 +495,13 @@ #else return close(s); #endif - return -1; } #ifndef MAX_SECS_TO_LINGER -#define MAX_SECS_TO_LINGER 16 +#define MAX_SECS_TO_LINGER 30 #endif -#define SECONDS_TO_LINGER 1 +#define SECONDS_TO_LINGER 2 #ifndef SHUT_WR #ifdef SD_SEND @@ -513,15 +512,12 @@ #endif int jk_shutdown_socket(jk_sock_t s) { - unsigned char dummy[512]; - int nbytes; - int ttl = 0; + char dummy[512]; int rc = 0; -#if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) - int tmout = SECONDS_TO_LINGER * 1000; -#elif defined(SO_RCVTIMEO) && defined(USE_SO_RCVTIMEO) + fd_set rs; struct timeval tv; -#endif + time_t start = time(NULL); + if (!IS_VALID_SOCKET(s)) return -1; @@ -531,29 +527,41 @@ if (shutdown(s, SHUT_WR)) { return jk_close_socket(s); } -#if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) - if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, - (const char *) &tmout, sizeof(int)) == 0) - rc = 1; -#elif defined(SO_RCVTIMEO) && defined(USE_SO_RCVTIMEO) - tv.tv_sec = SECONDS_TO_LINGER; - tv.tv_usec = 0; - if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, - (const void *) &tv, sizeof(tv))) - rc = 1; + + /* Set up to wait for readable data on socket... */ + FD_ZERO(&rs); + + do { + /* Read all data from the peer until we reach "end-of-file" + * (FIN from peer) or we've exceeded our overall timeout. If the + * backend does not send us bytes within 2 seconds + * (a value pulled from Apache 1.3 which seems to work well), + * close the connection. + */ + FD_SET(s, &rs); + tv.tv_sec = SECONDS_TO_LINGER; + tv.tv_usec = 0; + + if (select((int)s + 1, &rs, NULL, NULL, &tv) > 0) { + do { +#if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) + rc = recv(s, &dummy[0], sizeof(dummy), 0); + /* Assuming SOCKET_ERROR is -1 on NETWARE too */ + if (rc == SOCKET_ERROR) + errno = WSAGetLastError() - WSABASEERR; +#else + rc = read(s, &dummy[0], sizeof(dummy)); #endif - /* Read all data from the peer until we reach "end-of-file" (FIN - * from peer) or we've exceeded our overall timeout. If the client does - * not send us bytes within 16 second, close the connection. - */ - while (rc) { - nbytes = jk_tcp_socket_recvfull(s, dummy, sizeof(dummy)); - if (nbytes <= 0) - break; - ttl += SECONDS_TO_LINGER; - if (ttl > MAX_SECS_TO_LINGER) + } while (rc == -1 && (errno == EINTR || errno == EAGAIN)); + + if (rc <= 0) + break; + } + else break; - } + + } while (difftime(time(NULL), start) < MAX_SECS_TO_LINGER); + return jk_close_socket(s); } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org For additional commands, e-mail: dev-help@tomcat.apache.org