diff options
author | Joe Mistachkin <joe@mistachkin.com> | 2015-05-17 18:03:15 (GMT) |
---|---|---|
committer | Joe Mistachkin <joe@mistachkin.com> | 2015-05-17 18:03:15 (GMT) |
commit | ec8ad17e258e9758c10c5266ed7d4c4291b3a43b (patch) | |
tree | 3604f9fd49bb4908708f3547e2bebf85ff8fd645 /unix | |
parent | b96efa9cbb68cfff7b6df11f8905b5719eaf7570 (diff) | |
download | tcl-ec8ad17e258e9758c10c5266ed7d4c4291b3a43b.zip tcl-ec8ad17e258e9758c10c5266ed7d4c4291b3a43b.tar.gz tcl-ec8ad17e258e9758c10c5266ed7d4c4291b3a43b.tar.bz2 |
Draft fix for a potential race condition in the new Tcl_MutexUnlockAndFinalize API. Not yet tested.
Diffstat (limited to 'unix')
-rw-r--r-- | unix/tclUnixThrd.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index d34bc88..42b6bda 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -45,6 +45,13 @@ static pthread_mutex_t allocLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t *allocLockPtr = &allocLock; /* + * The mutexLock serializes Tcl_MutexLock. This is necessary to prevent + * races when finalizing a mutex that some other thread may want to lock. + */ + +static pthread_mutex_t mutexLock = PTHREAD_MUTEX_INITIALIZER; + +/* * These are for the critical sections inside this file. */ @@ -365,6 +372,58 @@ TclpMasterUnlock(void) /* *---------------------------------------------------------------------- * + * TclpMutexLock + * + * This procedure is used to grab a lock that serializes locking + * another mutex. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TclpMutexLock(void) +{ +#ifdef TCL_THREADS + pthread_mutex_lock(&mutexLock); +#endif +} + + +/* + *---------------------------------------------------------------------- + * + * TclpMutexUnlock + * + * This procedure is used to release a lock that serializes locking + * another mutex. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TclpMutexUnlock(void) +{ +#ifdef TCL_THREADS + pthread_mutex_unlock(&mutexLock); +#endif +} + + +/* + *---------------------------------------------------------------------- + * * Tcl_GetAllocMutex * * This procedure returns a pointer to a statically initialized mutex for @@ -421,6 +480,8 @@ Tcl_MutexLock( { pthread_mutex_t *pmutexPtr; +retry: + if (*mutexPtr == NULL) { MASTER_LOCK; if (*mutexPtr == NULL) { @@ -435,8 +496,14 @@ Tcl_MutexLock( } MASTER_UNLOCK; } + TclpMutexLock(); pmutexPtr = *((pthread_mutex_t **)mutexPtr); + if (pmutexPtr == NULL) { + TclpMutexUnlock(); + goto retry; + } pthread_mutex_lock(pmutexPtr); + TclpMutexUnlock(); } /* |