| ︙ | | | ︙ | |
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
/*
* Static routines for this file:
*/
static int TcpConnect(Tcl_Interp *interp,
TcpState *state);
static void InitSockets(void);
static TcpState * NewSocketInfo(SOCKET socket);
static void SocketExitHandler(void *clientData);
static LRESULT CALLBACK SocketProc(HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam);
static void TcpAccept(TcpFdList *fds, SOCKET newSocket, address addr);
static int WaitForConnect(TcpState *statePtr, int *errorCodePtr);
static int WaitForSocketEvent(TcpState *statePtr, int events,
|
|
|
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
/*
* Static routines for this file:
*/
static int TcpConnect(Tcl_Interp *interp,
TcpState *state);
static void InitSocketWindowClass(void);
static TcpState * NewSocketInfo(SOCKET socket);
static void SocketExitHandler(void *clientData);
static LRESULT CALLBACK SocketProc(HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam);
static void TcpAccept(TcpFdList *fds, SOCKET newSocket, address addr);
static int WaitForConnect(TcpState *statePtr, int *errorCodePtr);
static int WaitForSocketEvent(TcpState *statePtr, int events,
|
| ︙ | | | ︙ | |
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
|
}
/*
*----------------------------------------------------------------------
*
* TclInitSockets --
*
* This function just calls InitSockets(), but is protected by a mutex.
*
* Results:
* Returns TCL_OK if the system supports sockets, or TCL_ERROR with an
* error in interp (if non-NULL).
*
* Side effects:
* If not already prepared, initializes the TSD structure and socket
* message handling thread associated to the calling thread for the
* subsystem of the driver.
*
*----------------------------------------------------------------------
*/
void
TclInitSockets()
{
if (!initialized) {
Tcl_MutexLock(&socketMutex);
if (!initialized) {
InitSockets();
}
Tcl_MutexUnlock(&socketMutex);
}
}
/*
*----------------------------------------------------------------------
*
* TclpFinalizeSockets --
*
|
|
>
<
|
|
>
>
|
>
>
>
|
|
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
|
}
/*
*----------------------------------------------------------------------
*
* TclInitSockets --
*
* Initialization of sockets for the thread. Also creates message
* handling window class for the process if needed.
*
* Results:
* Nothing. Panics on failure.
*
* Side effects:
* If not already prepared, initializes the TSD structure and socket
* message handling thread associated to the calling thread for the
* subsystem of the driver.
*
*----------------------------------------------------------------------
*/
void
TclInitSockets()
{
/* Then Per thread initialization. */
DWORD id;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
if (tsdPtr != NULL) {
return;
}
InitSocketWindowClass();
/*
* OK, this thread has never done anything with sockets before. Construct
* a worker thread to handle asynchronous events related to sockets
* assigned to _this_ thread.
*/
tsdPtr = TCL_TSD_INIT(&dataKey);
tsdPtr->pendingTcpState = NULL;
tsdPtr->socketList = NULL;
tsdPtr->hwnd = NULL;
tsdPtr->threadId = Tcl_GetCurrentThread();
tsdPtr->readyEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
if (tsdPtr->readyEvent == NULL) {
goto initFailure;
}
tsdPtr->socketListLock = CreateEventW(NULL, FALSE, TRUE, NULL);
if (tsdPtr->socketListLock == NULL) {
goto initFailure;
}
tsdPtr->socketThread = CreateThread(NULL, 256, SocketThread, tsdPtr, 0,
&id);
if (tsdPtr->socketThread == NULL) {
goto initFailure;
}
SetThreadPriority(tsdPtr->socketThread, THREAD_PRIORITY_HIGHEST);
/*
* Wait for the thread to signal when the window has been created and if
* it is ready to go.
*/
WaitForSingleObject(tsdPtr->readyEvent, INFINITE);
if (tsdPtr->hwnd != NULL) {
Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL);
return;
}
initFailure:
Tcl_Panic("InitSockets failed");
return;
}
/*
*----------------------------------------------------------------------
*
* TclpFinalizeSockets --
*
|
| ︙ | | | ︙ | |
2330
2331
2332
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
|
host, atoi(port));
}
}
/*
*----------------------------------------------------------------------
*
* InitSockets --
*
* Registers the event window for the socket notifier code.
*
* Assumes socketMutex is held.
*
* Results:
* None.
*
* Side effects:
* Register a new window class and creates a
* window for use in asynchronous socket notification.
*
*----------------------------------------------------------------------
*/
static void
InitSockets(void)
{
DWORD id;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
if (!initialized) {
initialized = 1;
TclCreateLateExitHandler(SocketExitHandler, NULL);
/*
* Create the async notification window with a new class. We must
* create a new class to avoid a Windows 95 bug that causes us to get
|
|
|
<
|
|
<
|
|
|
|
>
|
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
|
host, atoi(port));
}
}
/*
*----------------------------------------------------------------------
*
* InitSocketWindowClass --
*
* Registers the event window class for the socket notifier code.
* Caller must not hold socket mutex lock.
*
* Results:
* None.
*
* Side effects:
* Register a new window class.
*
*----------------------------------------------------------------------
*/
static void
InitSocketWindowClass(void)
{
if (initialized) {
return;
}
Tcl_MutexLock(&socketMutex);
if (!initialized) {
initialized = 1;
TclCreateLateExitHandler(SocketExitHandler, NULL);
/*
* Create the async notification window with a new class. We must
* create a new class to avoid a Windows 95 bug that causes us to get
|
| ︙ | | | ︙ | |
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
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
|
windowClass.hCursor = NULL;
if (!RegisterClassW(&windowClass)) {
Tcl_WinConvertError(GetLastError());
goto initFailure;
}
}
/*
* Check for per-thread initialization.
*/
if (tsdPtr != NULL) {
return;
}
/*
* OK, this thread has never done anything with sockets before. Construct
* a worker thread to handle asynchronous events related to sockets
* assigned to _this_ thread.
*/
tsdPtr = TCL_TSD_INIT(&dataKey);
tsdPtr->pendingTcpState = NULL;
tsdPtr->socketList = NULL;
tsdPtr->hwnd = NULL;
tsdPtr->threadId = Tcl_GetCurrentThread();
tsdPtr->readyEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
if (tsdPtr->readyEvent == NULL) {
goto initFailure;
}
tsdPtr->socketListLock = CreateEventW(NULL, FALSE, TRUE, NULL);
if (tsdPtr->socketListLock == NULL) {
goto initFailure;
}
tsdPtr->socketThread = CreateThread(NULL, 256, SocketThread, tsdPtr, 0,
&id);
if (tsdPtr->socketThread == NULL) {
goto initFailure;
}
SetThreadPriority(tsdPtr->socketThread, THREAD_PRIORITY_HIGHEST);
/*
* Wait for the thread to signal when the window has been created and if
* it is ready to go.
*/
WaitForSingleObject(tsdPtr->readyEvent, INFINITE);
if (tsdPtr->hwnd != NULL) {
Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL);
return;
}
initFailure:
Tcl_Panic("InitSockets failed");
return;
}
/*
*----------------------------------------------------------------------
*
* SocketExitHandler --
*
|
|
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
|
windowClass.hCursor = NULL;
if (!RegisterClassW(&windowClass)) {
Tcl_WinConvertError(GetLastError());
goto initFailure;
}
}
Tcl_MutexUnlock(&socketMutex);
return;
initFailure:
Tcl_MutexUnlock(&socketMutex); /* Probably pointless before panicing */
Tcl_Panic("InitSockets failed");
}
/*
*----------------------------------------------------------------------
*
* SocketExitHandler --
*
|
| ︙ | | | ︙ | |