]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Re-initialize logmsgs mutex upon logger initialization to prevent lock errors
authorMatthew Jordan <mjordan@digium.com>
Thu, 22 Nov 2012 23:56:00 +0000 (23:56 +0000)
committerMatthew Jordan <mjordan@digium.com>
Thu, 22 Nov 2012 23:56:00 +0000 (23:56 +0000)
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

include/asterisk/lock.h
main/lock.c
main/logger.c

index fbcbecccf916a04db3037745af2fd3bad8cb9eda..61b84d1a9d0fe0866cc0f17014adcfd1d7761571 100644 (file)
@@ -428,12 +428,24 @@ int ast_find_lock_info(void *lock_addr, char *filename, size_t filename_size, in
 
 static inline void ast_reentrancy_lock(struct ast_lock_track *lt)
 {
-       pthread_mutex_lock(&lt->reentr_mutex);
+       int res;
+       if ((res = pthread_mutex_lock(&lt->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(&lt->reentr_mutex);
+       int res;
+       if ((res = pthread_mutex_unlock(&lt->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)
index c48c71e7c95601a4b1ba29c3a7e074613f4feb9c..dedbf79cb748b11f963a5c0715c033c56284167b 100644 (file)
@@ -51,8 +51,8 @@ int __ast_pthread_mutex_init(int tracking, const char *filename, int lineno, con
        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)) {
 /*
index a582f94e57b36a7c1d0abe1e43871ffdef5b7764..91102f040d0c43a7624d857106b3677fdfff48d4 100644 (file)
@@ -1124,8 +1124,17 @@ int init_logger(void)
        /* 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;