diff options
Diffstat (limited to 'main/utils.c')
-rw-r--r-- | main/utils.c | 97 |
1 files changed, 83 insertions, 14 deletions
diff --git a/main/utils.c b/main/utils.c index 300d057d9..e2c5e2c3f 100644 --- a/main/utils.c +++ b/main/utils.c @@ -597,6 +597,8 @@ struct thr_lock_info { enum ast_lock_type type; /*! This thread is waiting on this lock */ int pending:2; + /*! A condition has suspended this lock */ + int suspended:1; #ifdef HAVE_BKTR struct ast_bt *backtrace; #endif @@ -783,6 +785,60 @@ int ast_find_lock_info(void *lock_addr, char *filename, size_t filename_size, in return 0; } +void ast_suspend_lock_info(void *lock_addr) +{ + struct thr_lock_info *lock_info; + int i = 0; + + if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info)))) { + return; + } + + pthread_mutex_lock(&lock_info->lock); + + for (i = lock_info->num_locks - 1; i >= 0; i--) { + if (lock_info->locks[i].lock_addr == lock_addr) + break; + } + + if (i == -1) { + /* Lock not found :( */ + pthread_mutex_unlock(&lock_info->lock); + return; + } + + lock_info->locks[i].suspended = 1; + + pthread_mutex_unlock(&lock_info->lock); +} + +void ast_restore_lock_info(void *lock_addr) +{ + struct thr_lock_info *lock_info; + int i = 0; + + if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info)))) + return; + + pthread_mutex_lock(&lock_info->lock); + + for (i = lock_info->num_locks - 1; i >= 0; i--) { + if (lock_info->locks[i].lock_addr == lock_addr) + break; + } + + if (i == -1) { + /* Lock not found :( */ + pthread_mutex_unlock(&lock_info->lock); + return; + } + + lock_info->locks[i].suspended = 0; + + pthread_mutex_unlock(&lock_info->lock); +} + + #ifdef HAVE_BKTR void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt) #else @@ -876,7 +932,7 @@ static void append_lock_information(struct ast_str **str, struct thr_lock_info * ast_mutex_t *lock; struct ast_lock_track *lt; - ast_str_append(str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n", + ast_str_append(str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d%s)\n", lock_info->locks[i].pending > 0 ? "Waiting for " : lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i, lock_info->locks[i].file, @@ -884,7 +940,8 @@ static void append_lock_information(struct ast_str **str, struct thr_lock_info * lock_info->locks[i].line_num, lock_info->locks[i].func, lock_info->locks[i].lock_name, lock_info->locks[i].lock_addr, - lock_info->locks[i].times_locked); + lock_info->locks[i].times_locked, + lock_info->locks[i].suspended ? " - suspended" : ""); #ifdef HAVE_BKTR append_backtrace_information(str, lock_info->locks[i].backtrace); #endif @@ -982,20 +1039,32 @@ struct ast_str *ast_dump_locks(void) pthread_mutex_lock(&lock_infos_lock.mutex); AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) { int i; - if (lock_info->num_locks) { - ast_str_append(&str, 0, "=== Thread ID: 0x%lx (%s)\n", (long) lock_info->thread_id, - lock_info->thread_name); - pthread_mutex_lock(&lock_info->lock); - for (i = 0; str && i < lock_info->num_locks; i++) { - append_lock_information(&str, lock_info, i); + int header_printed = 0; + pthread_mutex_lock(&lock_info->lock); + for (i = 0; str && i < lock_info->num_locks; i++) { + /* Don't show suspended locks */ + if (lock_info->locks[i].suspended) { + continue; } - pthread_mutex_unlock(&lock_info->lock); - if (!str) - break; + + if (!header_printed) { + ast_str_append(&str, 0, "=== Thread ID: 0x%lx (%s)\n", (long) lock_info->thread_id, + lock_info->thread_name); + header_printed = 1; + } + + append_lock_information(&str, lock_info, i); + } + pthread_mutex_unlock(&lock_info->lock); + if (!str) { + break; + } + if (header_printed) { ast_str_append(&str, 0, "=== -------------------------------------------------------------------\n" - "===\n"); - if (!str) - break; + "===\n"); + } + if (!str) { + break; } } pthread_mutex_unlock(&lock_infos_lock.mutex); |