You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by mt...@apache.org on 2005/04/24 11:52:57 UTC
cvs commit: jakarta-tomcat-connectors/jk/native/common jk_connect.c jk_connect.h
mturk 2005/04/24 02:52:57
Modified: jk/native/common jk_connect.c jk_connect.h
Log:
Added jk_shutdown_socket function, that cracefully closes the AJP
connection by sending FIN. Should help resolving WAIT_CLOSE sockets
on some unixes.
Revision Changes Path
1.54 +56 -2 jakarta-tomcat-connectors/jk/native/common/jk_connect.c
Index: jk_connect.c
===================================================================
RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_connect.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -r1.53 -r1.54
--- jk_connect.c 21 Apr 2005 11:36:29 -0000 1.53
+++ jk_connect.c 24 Apr 2005 09:52:57 -0000 1.54
@@ -460,6 +460,60 @@
return -1;
}
+#ifndef MAX_SECS_TO_LINGER
+#define MAX_SECS_TO_LINGER 30
+#endif
+#define SECONDS_TO_LINGER 2
+
+int jk_shutdown_socket(int s)
+{
+ unsigned char dummy[512];
+ int nbytes;
+ int ttl = 0;
+#if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__))
+ int tmout = SECONDS_TO_LINGER * 1000;
+ if (s == INVALID_SOCKET)
+#else
+ struct timeval tv;
+ if (s < 0)
+#endif
+ return -1;
+
+ /* Shut down the socket for write, which will send a FIN
+ * to the peer.
+ */
+ if (shutdown(s, SD_SEND)) {
+ return jk_close_socket(s);
+ }
+#if defined(WIN32)
+ setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
+ (const char *) &tmout, sizeof(int));
+ setsockopt(s, SOL_SOCKET, SO_SNDTIMEO,
+ (const char *) &tmout, sizeof(int));
+#elif defined(SO_RCVTIMEO) && defined(USE_SO_RCVTIMEO) && defined(SO_SNDTIMEO) && defined(USE_SO_SNDTIMEO)
+ tv.tv_sec = SECONDS_TO_LINGER;
+ tv.tv_usec = 0;
+ setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
+ (const void *) &tv, sizeof(tv));
+ setsockopt(s, SOL_SOCKET, SO_SNDTIMEO,
+ (const void *) &tv, sizeof(tv));
+#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 2 seconds (a value pulled from Apache 1.3
+ * which seems to work well), close the connection.
+ */
+ while (1) {
+ nbytes = jk_tcp_socket_recvfull(s, dummy, sizeof(dummy));
+ if (nbytes <= 0)
+ break;
+ ttl += SECONDS_TO_LINGER;
+ if (ttl > MAX_SECS_TO_LINGER)
+ break;
+ }
+ return jk_close_socket(s);
+}
+
/** send a long message
* @param sd opened socket.
* @param b buffer containing the data.
@@ -553,7 +607,7 @@
fd_set fd;
struct timeval tv;
int rc;
-
+
FD_ZERO(&fd);
FD_SET(sd, &fd);
1.15 +3 -1 jakarta-tomcat-connectors/jk/native/common/jk_connect.h
Index: jk_connect.h
===================================================================
RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_connect.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- jk_connect.h 21 Apr 2005 11:36:29 -0000 1.14
+++ jk_connect.h 24 Apr 2005 09:52:57 -0000 1.15
@@ -45,6 +45,8 @@
int jk_close_socket(int s);
+int jk_shutdown_socket(int s);
+
int jk_tcp_socket_sendfull(int sd, const unsigned char *b, int len);
int jk_tcp_socket_recvfull(int sd, unsigned char *b, int len);
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org