diff options
author | Joe Mistachkin <joe@mistachkin.com> | 2015-05-17 22:13:39 (GMT) |
---|---|---|
committer | Joe Mistachkin <joe@mistachkin.com> | 2015-05-17 22:13:39 (GMT) |
commit | beea2ed90e5ef5ef3f760f1697e207d493813a0d (patch) | |
tree | 4e4355a066d0f52d57167288aae475eb521391f3 /win | |
parent | cf546fcc60e29ae9c2f87f51580c1da4bf18b448 (diff) | |
download | tcl-beea2ed90e5ef5ef3f760f1697e207d493813a0d.zip tcl-beea2ed90e5ef5ef3f760f1697e207d493813a0d.tar.gz tcl-beea2ed90e5ef5ef3f760f1697e207d493813a0d.tar.bz2 |
This should completely fix the race conditions at the cost of more complexity. Also, on Unix, a more reliable means than Tcl_Sleep() of sleeping for a short time is needed.
Diffstat (limited to 'win')
-rw-r--r-- | win/tclWinThrd.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c index ef42a83..7fd5ff5 100644 --- a/win/tclWinThrd.c +++ b/win/tclWinThrd.c @@ -24,6 +24,16 @@ _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. */ @@ -641,14 +651,20 @@ retry: } MASTER_UNLOCK; } - TclpMutexLock(); - csPtr = *((CRITICAL_SECTION **)mutexPtr); - if (csPtr == NULL) { - TclpMutexUnlock(); - goto retry; + while (1) { + TclpMutexLock(); + csPtr = *((CRITICAL_SECTION **)mutexPtr); + if (csPtr == NULL) { + TclpMutexUnlock(); + goto retry; + } + if (TryEnterCriticalSection(csPtr)) { + TclpMutexUnlock(); + return; + } + TclpMutexUnlock(); + Tcl_Sleep(TCL_MUTEX_LOCK_SLEEP_TIME); } - TclpMutexUnlock(); - EnterCriticalSection(csPtr); } /* |