Diff
Not logged in

Differences From Artifact [bb3d989f2d]:

To Artifact [befa27a974]:


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
19
20
21
22
23
24
25










26
27
28
29
30
31
32







-
-
-
-
-
-
-
-
-
-







#ifndef _MCW_EM
#   define	_MCW_EM		0x0008001F	/* Error masks */
#   define	_MCW_RC		0x00000300	/* Rounding */
#   define	_MCW_PC		0x00030000	/* Precision */
_CRTIMP unsigned int __cdecl _controlfp (unsigned int unNew, unsigned int unMask);
#endif

/*
 * This is the number of milliseconds to wait between internal retries in
 * the Tcl_MutexLock function.  This value must be greater than or equal
 * to zero and should be a suitable value for the given platform.
 */

#ifndef TCL_MUTEX_LOCK_SLEEP_TIME
#  define TCL_MUTEX_LOCK_SLEEP_TIME	(0)
#endif

/*
 * This is the master lock used to serialize access to other serialization
 * data structures.
 */

static CRITICAL_SECTION masterLock;
static int init = 0;
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
52
53
54
55
56
57
58







59
60
61
62
63
64
65







-
-
-
-
-
-
-







    CRITICAL_SECTION crit;
} allocLock;
static Tcl_Mutex allocLockPtr = &allocLock;
static int allocOnce = 0;

#endif /* TCL_THREADS */

/*
 * The mutexLock serializes Tcl_MutexLock. This is necessary to prevent
 * races when finalizing a mutex that some other thread may want to lock.
 */

static CRITICAL_SECTION mutexLock;

/*
 * The joinLock serializes Create- and ExitThread. This is necessary to
 * prevent a race where a new joinable thread exits before the creating thread
 * had the time to create the necessary data structures in the emulation
 * layer.
 */

382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
365
366
367
368
369
370
371

372
373
374
375
376
377
378







-







	 * There is a fundamental race here that is solved by creating the
	 * first Tcl interpreter in a single threaded environment. Once the
	 * interpreter has been created, it is safe to create more threads
	 * that create interpreters in parallel.
	 */

	init = 1;
	InitializeCriticalSection(&mutexLock);
	InitializeCriticalSection(&joinLock);
	InitializeCriticalSection(&initLock);
	InitializeCriticalSection(&masterLock);
    }
    EnterCriticalSection(&initLock);
}

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
512
513
514
515
516
517
518

519
520
521
522
523
524
525







-







 *----------------------------------------------------------------------
 */

void
TclFinalizeLock(void)
{
    MASTER_LOCK;
    DeleteCriticalSection(&mutexLock);
    DeleteCriticalSection(&joinLock);

    /*
     * Destroy the critical section that we are holding!
     */

    DeleteCriticalSection(&masterLock);
601
602
603
604
605
606
607
608

609
610
611


612
613
614
615



616
617
618
619
620
621
622
623
624
625
626
627
628
582
583
584
585
586
587
588

589



590
591




592
593
594






595
596
597
598
599
600
601







-
+
-
-
-
+
+
-
-
-
-
+
+
+
-
-
-
-
-
-







	    csPtr = ckalloc(sizeof(CRITICAL_SECTION));
	    InitializeCriticalSection(csPtr);
	    *mutexPtr = (Tcl_Mutex)csPtr;
	    TclRememberMutex(mutexPtr);
	}
	MASTER_UNLOCK;
    }
    while (1) {

	EnterCriticalSection(&mutexLock);
	csPtr = *((CRITICAL_SECTION **)mutexPtr);
	if (csPtr == NULL) {
    csPtr = *((CRITICAL_SECTION **)mutexPtr);
    if (csPtr == NULL) {
	    LeaveCriticalSection(&mutexLock);
	    goto retry;
	}
	if (TryEnterCriticalSection(csPtr)) {
	goto retry;
    }
    EnterCriticalSection(csPtr);
	    LeaveCriticalSection(&mutexLock);
	    return;
	}
	LeaveCriticalSection(&mutexLock);
	Tcl_Sleep(TCL_MUTEX_LOCK_SLEEP_TIME);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_MutexUnlock --
 *