summaryrefslogtreecommitdiffstats
path: root/win/tclWinSock.c
diff options
context:
space:
mode:
authoroehhar <harald.oehlmann@elmicron.de>2014-03-23 11:31:59 (GMT)
committeroehhar <harald.oehlmann@elmicron.de>2014-03-23 11:31:59 (GMT)
commitc12228d755f6bbc24681d68ad69ae7b7dfde5ba4 (patch)
tree681f2b08a9ffb73205f24e279148d2cd2792cc98 /win/tclWinSock.c
parentce028f5b60d1cf34a689f2781b9ac15280d09eb2 (diff)
downloadtcl-c12228d755f6bbc24681d68ad69ae7b7dfde5ba4.zip
tcl-c12228d755f6bbc24681d68ad69ae7b7dfde5ba4.tar.gz
tcl-c12228d755f6bbc24681d68ad69ae7b7dfde5ba4.tar.bz2
Be shure tsd pointer to the info structure is invalidated before memory free
Diffstat (limited to 'win/tclWinSock.c')
-rw-r--r--win/tclWinSock.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index f0b210e..6633b89 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -820,7 +820,7 @@ TcpCloseProc(
SocketInfo *infoPtr = (SocketInfo *) instanceData;
/* TIP #218 */
int errorCode = 0;
- /* ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); */
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
* Check that WinSock is initialized; do not call it if not, to prevent
@@ -842,6 +842,23 @@ TcpCloseProc(
}
/*
+ * Clear an eventual tsd info list pointer.
+ * This may be called, if an async socket connect fails or is closed
+ * between connect and thread action callback.
+ */
+ if (tsdPtr->pendingSocketInfo != NULL
+ && tsdPtr->pendingSocketInfo == infoPtr) {
+
+ /* get infoPtr lock, because this concerns the notifier thread */
+ WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
+
+ tsdPtr->pendingSocketInfo = NULL;
+
+ /* Free list lock */
+ SetEvent(tsdPtr->socketListLock);
+ }
+
+ /*
* TIP #218. Removed the code removing the structure from the global
* socket list. This is now done by the thread action callbacks, and only
* there. This happens before this code is called. We can free without
@@ -1051,6 +1068,8 @@ CreateSocket(
* Buffer new infoPtr in the tsd memory as long as it is not in
* the info list. This allows the event procedure to process the
* event.
+ * Bugfig for 336441ed59 to not ignore notifications until the
+ * infoPtr is in the list..
*/
tsdPtr->pendingSocketInfo = infoPtr;
@@ -1069,7 +1088,11 @@ CreateSocket(
*/
SetEvent(tsdPtr->socketListLock);
- /* activate accept notification and put in async mode */
+ /*
+ * Activate accept notification and put in async mode
+ * Bug 336441ed59: activate notification before connect
+ * so we do not miss a notification of a fialed connect.
+ */
ioctlsocket(sock, (long) FIONBIO, &flag);
SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT,
(LPARAM) infoPtr);
@@ -1119,17 +1142,15 @@ CreateSocket(
Tcl_AppendResult(interp, "couldn't open socket: ",
Tcl_PosixError(interp), NULL);
}
- /*
- * Clear the tsd socket list pointer if we did not wait for
- * the FD_CONNECT asyncroneously
- */
- tsdPtr->pendingSocketInfo = NULL;
if (infoPtr != NULL) {
/*
* Free the allocated socket info structure and close the socket
*/
TcpCloseProc(infoPtr, interp);
} else if (sock != INVALID_SOCKET) {
+ /*
+ * No socket structure jet - just close
+ */
closesocket(sock);
}
return NULL;