summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authorandreas_kupries <akupries@shaw.ca>2010-09-24 17:53:39 (GMT)
committerandreas_kupries <akupries@shaw.ca>2010-09-24 17:53:39 (GMT)
commit87af30e0e77b0228943003952af1742423ed0b6d (patch)
tree189b336d0b4ff26b839257006aebc30915af1c05 /win
parenta186bdb4397f2d831f6bb04e453fdf14e21c9c97 (diff)
downloadtcl-87af30e0e77b0228943003952af1742423ed0b6d.zip
tcl-87af30e0e77b0228943003952af1742423ed0b6d.tar.gz
tcl-87af30e0e77b0228943003952af1742423ed0b6d.tar.bz2
* tclWinsock.c: [Bug 3056775]: Fixed race condition between thread
and internal co-thread access of a socket's structure because of the thread not using the socketListLock in TcpAccept(). Added documentation on how the module works to the top.
Diffstat (limited to 'win')
-rw-r--r--win/tclWinSock.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index b4ef80b..f3127d5 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -8,7 +8,43 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinSock.c,v 1.74 2010/09/13 14:20:39 nijtmans Exp $
+ * RCS: @(#) $Id: tclWinSock.c,v 1.75 2010/09/24 17:53:39 andreas_kupries Exp $
+ *
+ * -----------------------------------------------------------------------
+ *
+ * General information on how this module works.
+ *
+ * - Each Tcl-thread with its sockets maintains an internal window to receive
+ * socket messages from the OS.
+ *
+ * - To ensure that message reception is always running this window is
+ * actually owned and handled by an internal thread. This we call the
+ * co-thread of Tcl's thread.
+ *
+ * - The whole structure is set up by InitSockets() which is called for each
+ * Tcl thread. The implementation of the co-thread is in SocketThread(),
+ * and the messages are handled by SocketProc(). The connection between
+ * both is not directly visible, it is done through a Win32 window class.
+ * This class is initialized by InitSockets() as well, and used in the
+ * creation of the message receiver windows.
+ *
+ * - An important thing to note is that *both* thread and co-thread have
+ * access to the list of sockets maintained in the private TSD data of the
+ * thread. The co-thread was given access to it upon creation through the
+ * new thread's client-data.
+ *
+ * Because of this dual access the TSD data contains an OS mutex, the
+ * "socketListLock", to mediate exclusion between thread and co-thread.
+ *
+ * The co-thread's access is all in SocketProc(). The thread's access is
+ * through SocketEventProc() (1) and the functions called by it.
+ *
+ * (Ad 1) This is the handler function for all queued socket events, which
+ * all the OS messages are translated to through the EventSource (2)
+ * driven by the OS messages.
+ *
+ * (Ad 2) The main functions for this are SocketSetupProc() and
+ * SocketCheckProc().
*/
#include "tclWinInt.h"
@@ -1463,6 +1499,12 @@ TcpAccept(
&len);
/*
+ * Protect access to sockets (acceptEventCount, readyEvents) in socketList
+ * by the lock. Fix for SF Tcl Bug 3056775.
+ */
+ WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
+
+ /*
* Clear the ready mask so we can detect the next connection request. Note
* that connection requests are level triggered, so if there is a request
* already pending, a new event will be generated.
@@ -1471,6 +1513,8 @@ TcpAccept(
if (newSocket == INVALID_SOCKET) {
infoPtr->acceptEventCount = 0;
infoPtr->readyEvents &= ~(FD_ACCEPT);
+
+ SetEvent(tsdPtr->socketListLock);
return;
}
@@ -1486,6 +1530,8 @@ TcpAccept(
infoPtr->readyEvents &= ~(FD_ACCEPT);
}
+ SetEvent(tsdPtr->socketListLock);
+
/*
* Win-NT has a misfeature that sockets are inherited in child processes
* by default. Turn off the inherit bit.
n2'>| | | | | | | | | | | | | longer set to NULL (Tcl_CreateObjCommand docs already say that it should not be accessed). * | | | * generic/tclObj.c (tclCmdNameType): Corrected variable use of thedgp2003-05-122-7/+8 | | | | | | | | | | | | | | | | | | | | otherValuePtr or the twoPtrValue.ptr1 fields to store a (ResolvedCmdName *) as the internal rep. [Bug 726018]. * | | | * doc/Eval.3: Corrected prototype for Tcl_GlobalEvalObj [Bug 727622].dgp2003-05-122-2/+6 | | | | * | | | * generic/tclVar.c (TclObjLookupVar): [Bug 735335] temporary fix,Miguel Sofer2003-05-123-2/+34 | | | | | | | | | | | | | | | | | | | | disabling usage of tclNsVarNameType. * tests/var.test (var-15.1): test for [Bug 735335] * | | | Added comment about correcting the #723502 bug.vasiljevic2003-05-121-0/+4 | | | | * | | | Corrected the Tcl bug #723502vasiljevic2003-05-121-1/+1 | | | | * | | | * generic/tclIOUtil.c: ensure cd is thread-safe.hobbs2003-05-112-68/+105 | | | | | | | | | | | | | | | | [Bug #710642] (vasiljevic) * | | | * win/tclWinSerial.c (SerialCloseProc): correct mem leak onhobbs2003-05-112-1/+6 | | | | | | | | | | | | | | | | closing a Windows serial port [Bug #718002] (schroedter) * | | | * generic/tclCmdMZ.c (Tcl_StringObjCmd): prevent string repeathobbs2003-05-102-18/+32 | | | | | | | | | | | | | | | | crash when overflow sizes were given (throws error). [Bug #714106] * | | | fix for [Bugs 733156, 733221]Joe Mistachkin2003-05-101-0/+15 | | | | * | | | fix for [Bug 733221]Joe Mistachkin2003-05-101-4/+11 | | | | * | | | fix for [Bugs 733221, 733156]Joe Mistachkin2003-05-101-21/+70 | | | | * | | | fix bad cvs lf conversionJoe Mistachkin2003-05-101-1/+2 | | | | * | | | fix for [Bug 731754]Joe Mistachkin2003-05-101-5/+1 | | | | * | | | * library/tcltest/tcltest.tcl: The -returnCodes option to [test]dgp2003-05-052-2/+7 | | | | | | | | | | | | | | | | failed to recognize the symbolic name "ok" for return code 0. * | | | Corrected error message for grammar and spelling.dkf2003-05-054-9/+14 | | | | * | | | glob and square brackets fixvincentdarley2003-04-293-4/+32 | | | | * | | | * generic/tclBasic.c: Tcl_EvalObjv() failed to honor thedgp2003-04-252-4/+15 | | | | | | | | | | | | | | | | | | | | | | | | TCL_EVAL_GLOBAL flag when resolving command names. Tcl_EvalEx passed a string rep including leading whitespace and comments to TclEvalObjvInternal(). * | | | * win/tclWinThrd.c: Applied SF patch #727271. This patch changesandreas_kupries2003-04-252-9/+65 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | the code to catch any errors returned by the windows functions handling TLS ASAP instead of waiting to get some mysterious crash later on due to bogus pointers. Patch provided by Joe Mistachkin. This is a stop-gap measure to deal with the low number of ?TLS slots provided by some of the variants of Windows (60-80). * | | | * library/tcltest/tcltest.tcl: When the return code of a test doesdgp2003-04-212-10/+17 | | | | | | | | | | | | | | | | | | | | | | | | not meet expectations, report that as the reason for test failure, and do not attempt to check the test result for correctness. [Bug 725253] * | | | Corrected bogus commentsdgp2003-04-181-7/+2 | | | | * | | | * generic/tclExecute.c (ExprCallMathFunc): remove incorrecthobbs2003-04-182-15/+20 | | | | | | | | | | | | | | | | extraneous cast from Tcl_WideAsDouble. * | | | Moved serial line options to their creator, open.n, from the generic pagedkf2003-04-183-203/+185 | | | | | | | | | | | | | | | | fconfigure.n which was never an obvious spot for them. [Bug 679010] * | | | * generic/tcl.h Made changes so that the "wideInt" Tcl_ObjTypedgp2003-04-1611-287/+135 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * generic/tclObj.c is defined on all platforms, even those where * generic/tclPort.h TCL_WIDE_INT_IS_LONG is defined. Also made the Tcl_Value struct have a wideValue field on all platforms. This is a ***POTENTIAL INCOMPATIBILITY*** for TCL_WIDE_INT_IS_LONG platforms because that struct changes size. This is the same TIP 72 incompatibility that was seen on other platforms at the 8.4.0 release, when this change should have happened as well. [Bug 713562] * generic/tclInt.h: New internal macros TclGetWide() and TclGetLongFromWide() to deal with both forms of the "wideInt" Tcl_ObjType, so that conditional TCL_WIDE_INT_IS_LONG code is confined to the header file. * generic/tclCmdAH.c: Replaced most coding that was conditional * generic/tclCmdIL.c: on TCL_WIDE_INT_IS_LONG with code that * generic/tclExecute.c: works across platforms, sometimes using * generic/tclTest.c: the new macros above to do it. * generic/tclUtil.c: * generic/tclVar.c: * | | | If you deal with network sockets, you should care about encodings. Tcl cannotdkf2003-04-162-2/+14 | | | | | | | | | | | | | | | | guess it for you. Updated socket docs to remind people about this. [Bug 630621] * | | | Math funcs might have to deal with wide ints; document this. [Bug 709720]dkf2003-04-16