Hello, I don't thikn the shutdown call is to blame - I think it's the large pile of code below. i.e. everything below the if (shutdown(..)) below. The question is, what does it all do and does it actually work? It appears to be the 'drain' code, but given it often results in this message:
"Shutdown socket .. and read 0 lingering bytes in 2 sec." then it would suggest it doesn't work. The comments also suggest the 2 seconds is "guess work". I've sent SECONDS_TO_LINGER and MAX_SECS_TO_LINGER to 0 and the problem goes away, and I've seen this discussed elsewhere on the forum. So, if this code isn't needed, why is it still there? And if it is needed, why does it seem not to work and what is the correct figure for SECONDS_TO_LINGER? If this is being performed inline then I'd suggest 2s is far too long - clients don't want to wait 2s for a request to complete (ideally, socket clean up should not be done in this thread if any linger is required). John .. MAX_SECS_TO_LINGER= 30 SECONDS_TO_LINGER= 2 ... int jk_shutdown_socket(jk_sock_t sd, jk_logger_t *l) { ... /* Shut down the socket for write, which will send a FIN * to the peer. */ if (shutdown(sd, SHUT_WR)) { rc = jk_close_socket(sd, l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Failed sending SHUT_WR for socket %d", sd); errno = save_errno; JK_TRACE_EXIT(l); return rc; } do { #ifdef HAVE_POLL struct pollfd fds; fds.fd = sd; fds.events = POLLIN; #else fd_set rs; FD_ZERO(&rs); /* 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(sd, &rs); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; #endif rp = 0; #ifdef HAVE_POLL if (poll(&fds, 1, timeout) > 0) #else if (select((int)sd + 1, &rs, NULL, NULL, &tv) > 0) #endif { do { #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) rc = recv(sd, &dummy[0], sizeof(dummy), 0); if (JK_IS_SOCKET_ERROR(rc)) JK_GET_SOCKET_ERRNO(); #else rc = read(sd, &dummy[0], sizeof(dummy)); #endif if (rc > 0) rp += rc; } while (JK_IS_SOCKET_ERROR(rc) && (errno == EINTR || errno == EAGAIN)); if (rc < 0) break; } else break; rd += rp; if (rp < sizeof(dummy)) { if (timeout > SECONDS_TO_LINGER) { /* Try once again with 1000 times smaller timeout * In our case 2 msec. */ timeout = SECONDS_TO_LINGER; continue; } /* We have read less then size of buffer * It's a good chance there will be no more data * to read. */ if ((rc = sononblock(sd))) { rc = jk_close_socket(sd, l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "error setting socket %d to nonblocking", sd); errno = save_errno; JK_TRACE_EXIT(l); return rc; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "shutting down the read side of socket %d", sd); shutdown(sd, SHUT_RD); break; } timeout = SECONDS_TO_LINGER * 1000; } while (difftime(time(NULL), start) < MAX_SECS_TO_LINGER); rc = jk_close_socket(sd, l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Shutdown socket %d and read %d lingering bytes in %d sec.", sd, rd, (int)difftime(time(NULL), start)); errno = save_errno; JK_TRACE_EXIT(l); return rc; } --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org