summaryrefslogtreecommitdiffstats
path: root/win/tclWinSock.c
diff options
context:
space:
mode:
authorredman <redman>1999-05-26 20:24:43 (GMT)
committerredman <redman>1999-05-26 20:24:43 (GMT)
commit6cd14bf5542b934b1b15131087e58f92da9f8a93 (patch)
tree8ccfaadf0fc8865e7c3808ab15f1328fae208b05 /win/tclWinSock.c
parent9b8d0c42d5220c0fe2e393876c547cc86592439b (diff)
downloadtcl-6cd14bf5542b934b1b15131087e58f92da9f8a93.zip
tcl-6cd14bf5542b934b1b15131087e58f92da9f8a93.tar.gz
tcl-6cd14bf5542b934b1b15131087e58f92da9f8a93.tar.bz2
generic/tclThreadTest.c: Fix race condition in testthread code.
win/tclWinSock.c: Fixed hang in WinNT socket driver, now wakes up the socket thread to check for events that didn't trigger the WSAEvent.
Diffstat (limited to 'win/tclWinSock.c')
-rw-r--r--win/tclWinSock.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index 969e2bb..03ded94 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -8,7 +8,7 @@
* 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.9 1999/04/22 20:28:02 redman Exp $
+ * RCS: @(#) $Id: tclWinSock.c,v 1.10 1999/05/26 20:24:43 redman Exp $
*/
#include "tclWinInt.h"
@@ -111,6 +111,13 @@ static struct {
#define SOCKET_MESSAGE WM_USER+1
/*
+ * The following defines the timeout value for the WSAWaitForMultipleEvents
+ * in milliseconds.
+ */
+
+#define TCL_SOCKET_EVENT_TIMEOUT 100
+
+/*
* The following structure is used to store the data associated with
* each socket.
*/
@@ -2337,6 +2344,15 @@ TcpGetHandleProc(instanceData, direction, handlePtr)
*
* SocketThread --
*
+ * Use a separate thread to check state for the sockets in each
+ * thread. Using a window isn't the best way, especially if the
+ * WinSock2 API is available and working. Also, creating N threads
+ * per socket like the pipe, console, and serial drivers isn't
+ * very efficient. Currently, all sockets are tied to one event.
+ * The overhead involved in creating an event for each socket is
+ * a concern. But, in order to avoid deadlocks, the call to
+ * WSAWaitForMultipleEvents() needs to timeout to check for
+ * status changes which haven't been handled (race condition).
*
* Results:
* 0 on success.
@@ -2353,7 +2369,7 @@ SocketThread(LPVOID arg)
WSAEVENT events[2];
ThreadSpecificData *tsdPtr;
DWORD result;
-
+
/*
* Find the specified socket on the socket list and update its
* eventState flag.
@@ -2365,10 +2381,12 @@ SocketThread(LPVOID arg)
while (1) {
result = (*winSock.WSAWaitForMultipleEvents)(2, events, FALSE,
- WSA_INFINITE, FALSE);
+ TCL_SOCKET_EVENT_TIMEOUT, FALSE);
switch (result) {
+ case WSA_WAIT_TIMEOUT:
case (WSA_WAIT_EVENT_0 +1):
+
/*
* A socket event has fired, determine which socket(s) it was
* and which thread(s) it came from.
@@ -2384,13 +2402,6 @@ SocketThread(LPVOID arg)
if (GetSocketState(infoPtr) & infoPtr->watchEvents) {
Tcl_ThreadAlert(tsdPtr->threadId);
SetEvent(tsdPtr->wakeEvent);
-
- /*
- * Only process one at a time for a given thread,
- * so break here.
- */
-
- break;
}
}
}