From c12228d755f6bbc24681d68ad69ae7b7dfde5ba4 Mon Sep 17 00:00:00 2001 From: oehhar Date: Sun, 23 Mar 2014 11:31:59 +0000 Subject: Be shure tsd pointer to the info structure is invalidated before memory free --- win/tclWinSock.c | 35 ++++++++++++++++++++++++++++------- 1 file 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; -- cgit v0.12