Diff
Not logged in

Differences From Artifact [5c83b12d3a]:

To Artifact [6f8a787df2]:


1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18










-
+







/* 
 * tclWinSock.c --
 *
 *	This file contains Windows-specific socket related code.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 *
 * 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"

/*
 * The following variable is used to tell whether this module has been
 * initialized.
106
107
108
109
110
111
112







113
114
115
116
117
118
119
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126







+
+
+
+
+
+
+








/*
 * The following defines declare the messages used on socket windows.
 */

#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.
 */

typedef struct SocketInfo {
    Tcl_Channel channel;	   /* Channel associated with this socket. */
2333
2334
2335
2336
2337
2338
2339









2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356

2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368

2369
2370

2371

2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371

2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383

2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404







2405
2406
2407
2408
2409
2410
2411







+
+
+
+
+
+
+
+
+
















-
+











-
+


+

+















-
-
-
-
-
-
-







}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 * Side effects:
 *
 *----------------------------------------------------------------------
 */

static DWORD WINAPI
SocketThread(LPVOID arg)
{
    SocketInfo *infoPtr;
    WSAEVENT events[2];
    ThreadSpecificData *tsdPtr;
    DWORD result;
    
		
    /*
     * Find the specified socket on the socket list and update its
     * eventState flag.
     */

    events[0] = killEvent;
    events[1] = socketEvent;
    
    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.
		 */

		EnterCriticalSection(&socketCS);
		for (tsdPtr = firstWaitingThread; tsdPtr != NULL;
		     tsdPtr = tsdPtr->next) {
		    
		    for (infoPtr = tsdPtr->socketList; infoPtr != NULL; 
			 infoPtr = infoPtr->nextPtr) {
			
			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;
			}
		    }
		}
		LeaveCriticalSection(&socketCS);
		(*winSock.WSAResetEvent)(socketEvent);
		break;