Tcl Source Code

Artifact [3bc4762ae1]
Login

Artifact 3bc4762ae1d2802a29a6c4297b42ced8f794880d:

Attachment "cleanup-async-connect.patch" to ticket [1994512fff] added by jenglish 2008-06-16 01:33:20.
From 0ea7418db7e3d636638833ea0cac5a555aedc65e Mon Sep 17 00:00:00 2001
From: Joe English <[email protected]>
Date: Sun, 1 Jun 2008 13:42:52 -0700
Subject: [PATCH] Consolidate error report paths.

---
 unix/tclUnixChan.c |   27 +++++++++------------------
 1 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c
index 629f9d0..d80074e 100644
--- a/unix/tclUnixChan.c
+++ b/unix/tclUnixChan.c
@@ -2279,7 +2279,7 @@ CreateSocket(
 				 * attempt to do an async connect. Otherwise
 				 * do a synchronous connect or bind. */
 {
-    int status, sock, asyncConnect, curState, origState;
+    int status = 0, sock = -1, asyncConnect, curState, origState;
     struct sockaddr_in sockaddr;	/* socket address */
     struct sockaddr_in mysockaddr;	/* Socket address for client */
     TcpState *statePtr;
@@ -2288,16 +2288,16 @@ CreateSocket(
     sock = -1;
     origState = 0;
     if (!CreateSocketAddress(&sockaddr, host, port, 0, &errorMsg)) {
-	goto addressError;
+	goto error;
     }
     if ((myaddr != NULL || myport != 0) &&
 	    !CreateSocketAddress(&mysockaddr, myaddr, myport, 1, &errorMsg)) {
-	goto addressError;
+	goto error;
     }
 
     sock = socket(AF_INET, SOCK_STREAM, 0);
     if (sock < 0) {
-	goto addressError;
+	goto error;
     }
 
     /*
@@ -2337,7 +2337,7 @@ CreateSocket(
 	    status = bind(sock, (struct sockaddr *) &mysockaddr,
 		    sizeof(struct sockaddr));
 	    if (status < 0) {
-		goto bindError;
+		goto error;
 	    }
 	}
 
@@ -2377,11 +2377,14 @@ CreateSocket(
 	}
     }
 
-  bindError:
     if (status < 0) {
+error:
 	if (interp != NULL) {
 	    Tcl_AppendResult(interp, "couldn't open socket: ",
 		    Tcl_PosixError(interp), NULL);
+	    if (errorMsg != NULL) {
+		Tcl_AppendResult(interp, " (", errorMsg, ")", NULL);
+	    }
 	}
 	if (sock != -1) {
 	    close(sock);
@@ -2402,18 +2405,6 @@ CreateSocket(
 
     return statePtr;
 
-  addressError:
-    if (sock != -1) {
-	close(sock);
-    }
-    if (interp != NULL) {
-	Tcl_AppendResult(interp, "couldn't open socket: ",
-		Tcl_PosixError(interp), NULL);
-	if (errorMsg != NULL) {
-	    Tcl_AppendResult(interp, " (", errorMsg, ")", NULL);
-	}
-    }
-    return NULL;
 }
 
 /*
-- 
1.5.3


From 2dae156a23eadaba7df56138e85f93323f675fcd Mon Sep 17 00:00:00 2001
From: Joe English <[email protected]>
Date: Sun, 1 Jun 2008 13:57:32 -0700
Subject: [PATCH] Remove write-only variable origState;
 don't reuse 'status' variable for things other than status.

---
 unix/tclUnixChan.c |   17 +++++++----------
 1 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c
index d80074e..ada5389 100644
--- a/unix/tclUnixChan.c
+++ b/unix/tclUnixChan.c
@@ -2279,14 +2279,12 @@ CreateSocket(
 				 * attempt to do an async connect. Otherwise
 				 * do a synchronous connect or bind. */
 {
-    int status = 0, sock = -1, asyncConnect, curState, origState;
+    int status = 0, sock = -1, asyncConnect;
     struct sockaddr_in sockaddr;	/* socket address */
     struct sockaddr_in mysockaddr;	/* Socket address for client */
     TcpState *statePtr;
     const char *errorMsg = NULL;
 
-    sock = -1;
-    origState = 0;
     if (!CreateSocketAddress(&sockaddr, host, port, 0, &errorMsg)) {
 	goto error;
     }
@@ -2321,9 +2319,9 @@ CreateSocket(
 	 * specified port.
 	 */
 
-	status = 1;
-	(void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &status,
-		sizeof(status));
+	int reuseaddr = 1;
+	(void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, 
+		      (char *) &reuseaddr, sizeof(reuseaddr));
 	status = bind(sock, (struct sockaddr *) &sockaddr,
 		sizeof(struct sockaddr));
 	if (status != -1) {
@@ -2331,9 +2329,9 @@ CreateSocket(
 	}
     } else {
 	if (myaddr != NULL || myport != 0) {
-	    curState = 1;
+	    int reuseaddr = 1;
 	    (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
-		    (char *) &curState, sizeof(curState));
+		    (char *) &reuseaddr, sizeof(reuseaddr));
 	    status = bind(sock, (struct sockaddr *) &mysockaddr,
 		    sizeof(struct sockaddr));
 	    if (status < 0) {
@@ -2350,9 +2348,8 @@ CreateSocket(
 
 	if (async) {
 	    status = TclUnixSetBlockingMode(sock, TCL_MODE_NONBLOCKING);
-	} else {
-	    status = 0;
 	}
+
 	if (status > -1) {
 	    status = connect(sock, (struct sockaddr *) &sockaddr,
 		    sizeof(sockaddr));
-- 
1.5.3


From 9ed0709714f44399df8cc8c710babc8e57953ed8 Mon Sep 17 00:00:00 2001
From: Joe English <[email protected]>
Date: Sun, 15 Jun 2008 10:50:12 -0700
Subject: [PATCH] socket -async: restore blocking mode after connect() call.

File descriptor blocking mode is now consistent with
[fconfigure ... -blocking] setting even while async connect
in progress.

Fixed incorrect comments in WaitForConnect() header.
---
 unix/tclUnixChan.c |   66 +++++++++++++++++++--------------------------------
 1 files changed, 25 insertions(+), 41 deletions(-)

diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c
index ada5389..fbd48a2 100644
--- a/unix/tclUnixChan.c
+++ b/unix/tclUnixChan.c
@@ -1828,14 +1828,13 @@ TcpBlockModeProc(
  *
  * WaitForConnect --
  *
- *	Waits for a connection on an asynchronously opened socket to be
- *	completed.
+ *	Wait for a connection on an asynchronously opened socket to be
+ *	completed.  In nonblocking mode, just test if the connection
+ *	has completed without blocking.
  *
  * Results:
- *	None.
- *
- * Side effects:
- *	The socket is connected after this function returns.
+ * 	0 if the connection has completed, -1 if still in progress
+ * 	or there is an error.
  *
  *----------------------------------------------------------------------
  */
@@ -1862,9 +1861,6 @@ WaitForConnect(
 	errno = 0;
 	state = TclUnixWaitForFile(statePtr->fd,
 		TCL_WRITABLE | TCL_EXCEPTION, timeOut);
-	if (!(statePtr->flags & TCP_ASYNC_SOCKET)) {
-	    (void) TclUnixSetBlockingMode(statePtr->fd, TCL_MODE_BLOCKING);
-	}
 	if (state & TCL_EXCEPTION) {
 	    return -1;
 	}
@@ -1910,11 +1906,10 @@ TcpInputProc(
     int *errorCodePtr)		/* Where to store error code. */
 {
     TcpState *statePtr = (TcpState *) instanceData;
-    int bytesRead, state;
+    int bytesRead;
 
     *errorCodePtr = 0;
-    state = WaitForConnect(statePtr, errorCodePtr);
-    if (state != 0) {
+    if (WaitForConnect(statePtr, errorCodePtr) != 0) {
 	return -1;
     }
     bytesRead = recv(statePtr->fd, buf, (size_t) bufSize, 0);
@@ -1962,11 +1957,9 @@ TcpOutputProc(
 {
     TcpState *statePtr = (TcpState *) instanceData;
     int written;
-    int state;				/* Of waiting for connection. */
 
     *errorCodePtr = 0;
-    state = WaitForConnect(statePtr, errorCodePtr);
-    if (state != 0) {
+    if (WaitForConnect(statePtr, errorCodePtr) != 0) {
 	return -1;
     }
     written = send(statePtr->fd, buf, (size_t) toWrite, 0);
@@ -2279,7 +2272,7 @@ CreateSocket(
 				 * attempt to do an async connect. Otherwise
 				 * do a synchronous connect or bind. */
 {
-    int status = 0, sock = -1, asyncConnect;
+    int status = 0, sock = -1;
     struct sockaddr_in sockaddr;	/* socket address */
     struct sockaddr_in mysockaddr;	/* Socket address for client */
     TcpState *statePtr;
@@ -2311,7 +2304,6 @@ CreateSocket(
 
     TclSockMinimumBuffers(sock, SOCKET_BUFSIZE);
 
-    asyncConnect = 0;
     status = 0;
     if (server) {
 	/*
@@ -2348,29 +2340,25 @@ CreateSocket(
 
 	if (async) {
 	    status = TclUnixSetBlockingMode(sock, TCL_MODE_NONBLOCKING);
+	    if (status < 0) {
+		goto error;
+	    }
 	}
 
-	if (status > -1) {
-	    status = connect(sock, (struct sockaddr *) &sockaddr,
-		    sizeof(sockaddr));
-	    if (status < 0) {
-		if (errno == EINPROGRESS) {
-		    asyncConnect = 1;
-		    status = 0;
-		}
+	status = connect(sock, (struct sockaddr *) &sockaddr,
+		sizeof(sockaddr));
+	if (status < 0) {
+	    if (errno == EINPROGRESS) {
+		status = 0;
 	    } else {
-		/*
-		 * Here we are if the connect succeeds. In case of an
-		 * asynchronous connect we have to reset the channel to
-		 * blocking mode. This appears to happen not very often, but
-		 * e.g. on a HP 9000/800 under HP-UX B.11.00 we enter this
-		 * stage. [Bug: 4388]
-		 */
-
-		if (async) {
-		    status = TclUnixSetBlockingMode(sock, TCL_MODE_BLOCKING);
-		}
+		goto error;
 	    }
+	} 
+	if (async) {
+	    /*
+	     * Restore blocking mode.
+	     */
+	    status = TclUnixSetBlockingMode(sock, TCL_MODE_BLOCKING);
 	}
     }
 
@@ -2394,14 +2382,10 @@ error:
      */
 
     statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState));
-    statePtr->flags = 0;
-    if (asyncConnect) {
-	statePtr->flags = TCP_ASYNC_CONNECT;
-    }
+    statePtr->flags = async ? TCP_ASYNC_CONNECT : 0;
     statePtr->fd = sock;
 
     return statePtr;
-
 }
 
 /*
-- 
1.5.3