Similar to the patch that moved the fork earlier in the startup sequence to
prevent mutex errors in the recursive mutex surrounding the read/write thread
registration lock, this patch re-initializes the logmsgs mutex. Part of the
start up sequence before forking the process into the background includes
reading asterisk.conf; this has to occur prior to the call to daemon in order
to read startup parameters. When reading in a conf file, log statements can
be generated. Since this can't be avoided, the mutex instead is
re-initialized to ensure a reset of any thread tracking information.
This patch also includes some additional debugging to catch errors when
locking or unlocking the recursive mutex that surrounds locks when the
DEBUG_THREADS build option is enabled. DO_CRASH or THREAD_CRASH will
cause an abort() if a mutex error is detected.
(issue ASTERISK-19463)
Reported by: mjordan
Tesetd by: mjordan
........
Merged revisions 376586 from http://svn.asterisk.org/svn/asterisk/branches/1.8
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@376587
65c4cc65-6c06-0410-ace0-
fbb531ad65f3
static inline void ast_reentrancy_lock(struct ast_lock_track *lt)
{
- pthread_mutex_lock(<->reentr_mutex);
+ int res;
+ if ((res = pthread_mutex_lock(<->reentr_mutex))) {
+ fprintf(stderr, "ast_reentrancy_lock failed: '%s' (%d)\n", strerror(res), res);
+#if defined(DO_CRASH) || defined(THREAD_CRASH)
+ abort();
+#endif
+ }
}
static inline void ast_reentrancy_unlock(struct ast_lock_track *lt)
{
- pthread_mutex_unlock(<->reentr_mutex);
+ int res;
+ if ((res = pthread_mutex_unlock(<->reentr_mutex))) {
+ fprintf(stderr, "ast_reentrancy_unlock failed: '%s' (%d)\n", strerror(res), res);
+#if defined(DO_CRASH) || defined(THREAD_CRASH)
+ abort();
+#endif
+ }
}
static inline void ast_reentrancy_init(struct ast_lock_track **plt)
int res;
pthread_mutexattr_t attr;
- t->track = NULL;
#ifdef DEBUG_THREADS
+ t->track = NULL;
#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE)
if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
/*
/* auto rotate if sig SIGXFSZ comes a-knockin */
sigaction(SIGXFSZ, &handle_SIGXFSZ, NULL);
- /* start logger thread */
+ /* Re-initialize the logmsgs mutex. The recursive mutex can be accessed prior
+ * to Asterisk being forked into the background, which can cause the thread
+ * ID tracked by the underlying pthread mutex to be different than the ID of
+ * the thread that unlocks the mutex. Since init_logger is called after the
+ * fork, it is safe to initialize the mutex here for future accesses.
+ */
+ ast_mutex_destroy(&logmsgs.lock);
+ ast_mutex_init(&logmsgs.lock);
ast_cond_init(&logcond, NULL);
+
+ /* start logger thread */
if (ast_pthread_create(&logthread, NULL, logger_thread, NULL) < 0) {
ast_cond_destroy(&logcond);
return -1;