summaryrefslogtreecommitdiff
path: root/include/asterisk/lock.h
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2014-12-12 23:49:36 +0000
committerRichard Mudgett <rmudgett@digium.com>2014-12-12 23:49:36 +0000
commit308c1b41dd5e8d89c2950230c1babd826b006629 (patch)
treea130bf67a6080b7c8f7774913289256e230f7d21 /include/asterisk/lock.h
parent901221ffaeae53bf95671261eef405f955cf1d54 (diff)
DEBUG_THREADS: Fix regression and lock tracking initialization problems.
This patch started with David Lee's patch at https://reviewboard.asterisk.org/r/2826/ and includes a regression fix introduced by the ASTERISK-22455 patch. The initialization of a mutex's lock tracking structure was not protected in a critical section. This is fine for any mutex that is explicitly initialized, but a static mutex may have its lock tracking double initialized if multiple threads attempt the first lock simultaneously. * Added a global mutex to properly serialize initialization of the lock tracking structure. The painful global lock can be mitigated by adding a double checked lock flag as discussed on the original review request. * Defer lock tracking initialization until first use. * Don't be "helpful" and initialize an uninitialized lock when DEBUG_THREADS is enabled. Debug code is not supposed to fix or change normal code behavior. We don't need a lock initialization race that would force a re-setup of lock tracking. Lock tracking already handles initialization on first use. * Properly handle allocation failures of the lock tracking structure. * No need to initialize tracking data in __ast_pthread_mutex_destroy() just to turn around and destroy it. The regression introduced by ASTERISK-22455 is the result of manipulating a pthread_mutex_t struct outside of the pthread library code. The pthread_mutex_t struct seems to have a global linked list pointer member that can get changed by other threads. Therefore, saving and restoring the contents of a pthread_mutex_t struct is a bad thing. Thanks to Thomas Airmont for finding this obscure regression. * Don't overwrite the struct ast_lock_track.reentr_mutex member to restore tracking data in __ast_cond_wait() and __ast_cond_timedwait(). The pthread_mutex_t struct must be treated as a read-only opaque variable. Miscellaneous other items fixed by this patch: * Match ast_suspend_lock_info() with ast_restore_lock_info() in __ast_cond_timedwait(). * Made some uninitialized lock sanity checks return EINVAL and try a DO_THREAD_CRASH. * Fix bad canlog initialization expressions. ASTERISK-24614 #close Reported by: Thomas Airmont Review: https://reviewboard.asterisk.org/r/4247/ Review: https://reviewboard.asterisk.org/r/2826/ ........ Merged revisions 429539 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@429541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'include/asterisk/lock.h')
-rw-r--r--include/asterisk/lock.h47
1 files changed, 7 insertions, 40 deletions
diff --git a/include/asterisk/lock.h b/include/asterisk/lock.h
index 7741654a0..5e651600e 100644
--- a/include/asterisk/lock.h
+++ b/include/asterisk/lock.h
@@ -18,7 +18,7 @@
/*! \file
* \brief Asterisk locking-related definitions:
- * - ast_mutext_t, ast_rwlock_t and related functions;
+ * - ast_mutex_t, ast_rwlock_t and related functions;
* - atomic arithmetic instructions;
* - wrappers for channel locking.
*
@@ -102,6 +102,12 @@
struct ast_channel;
+/*!
+ * \brief Lock tracking information.
+ *
+ * \note Any changes to this struct MUST be reflected in the
+ * lock.c:restore_lock_tracking() function.
+ */
struct ast_lock_track {
const char *file[AST_MAX_REENTRANCY];
int lineno[AST_MAX_REENTRANCY];
@@ -474,45 +480,6 @@ static inline void ast_reentrancy_unlock(struct ast_lock_track *lt)
}
}
-static inline void ast_reentrancy_init(struct ast_lock_track **plt)
-{
- int i;
- pthread_mutexattr_t reentr_attr;
- struct ast_lock_track *lt = *plt;
-
- if (!lt) {
- lt = *plt = (struct ast_lock_track *) calloc(1, sizeof(*lt));
- }
-
- for (i = 0; i < AST_MAX_REENTRANCY; i++) {
- lt->file[i] = NULL;
- lt->lineno[i] = 0;
- lt->func[i] = NULL;
- lt->thread[i] = 0;
-#ifdef HAVE_BKTR
- memset(&lt->backtrace[i], 0, sizeof(lt->backtrace[i]));
-#endif
- }
-
- lt->reentrancy = 0;
-
- pthread_mutexattr_init(&reentr_attr);
- pthread_mutexattr_settype(&reentr_attr, AST_MUTEX_KIND);
- pthread_mutex_init(&lt->reentr_mutex, &reentr_attr);
- pthread_mutexattr_destroy(&reentr_attr);
-}
-
-static inline void delete_reentrancy_cs(struct ast_lock_track **plt)
-{
- struct ast_lock_track *lt;
- if (*plt) {
- lt = *plt;
- pthread_mutex_destroy(&lt->reentr_mutex);
- free(lt);
- *plt = NULL;
- }
-}
-
#else /* !DEBUG_THREADS */
#define AO2_DEADLOCK_AVOIDANCE(obj) \