diff options
author | mmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-06-25 22:25:20 +0000 |
---|---|---|
committer | mmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-06-25 22:25:20 +0000 |
commit | 802aa72966c5fd4ea72f8334942dee062dcec88b (patch) | |
tree | 32f13c0d80f4b8d22ee4cd815f07ad24d5e08fc6 /include | |
parent | f635bc335f80a8b6e02e1e7148b494821ea77f04 (diff) |
Fix a bug in the rwlock tracking. ast_rwlock_unlock did not take into
account that multiple threads could hold the same rdlock at the same time.
As such, it expected that when a thread released a lock that it must have
been the last to acquire the lock as well. Erroneous error messages would
be sent to the console stating that a thread was attempting to unlock a lock
it did not own.
Now all threads are examined to be sure that the message is only printed
when it is supposed to be printed.
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@125133 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'include')
-rw-r--r-- | include/asterisk/lock.h | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/include/asterisk/lock.h b/include/asterisk/lock.h index 4122978fb..f97b3f91a 100644 --- a/include/asterisk/lock.h +++ b/include/asterisk/lock.h @@ -1048,15 +1048,31 @@ static inline int _ast_rwlock_unlock(ast_rwlock_t *t, const char *name, #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ ast_reentrancy_lock(lt); - if (lt->reentrancy && (lt->thread[lt->reentrancy-1] != pthread_self())) { - __ast_mutex_logger("%s line %d (%s): attempted unlock rwlock '%s' without owning it!\n", - filename, line, func, name); - __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n", - lt->file[lt->reentrancy-1], lt->lineno[lt->reentrancy-1], lt->func[lt->reentrancy-1], name); + if (lt->reentrancy) { + int lock_found = 0; + int i; + for (i = lt->reentrancy-1; i >= 0; --i) { + if (lt->thread[i] == pthread_self()) { + lock_found = 1; + if (i != lt->reentrancy-1) { + lt->file[i] = lt->file[lt->reentrancy-1]; + lt->lineno[i] = lt->lineno[lt->reentrancy-1]; + lt->func[i] = lt->func[lt->reentrancy-1]; + lt->thread[i] = lt->thread[lt->reentrancy-1]; + } + break; + } + } + if (!lock_found) { + __ast_mutex_logger("%s line %d (%s): attempted unlock rwlock '%s' without owning it!\n", + filename, line, func, name); + __ast_mutex_logger("%s line %d (%s): '%s' was last locked here.\n", + lt->file[lt->reentrancy-1], lt->lineno[lt->reentrancy-1], lt->func[lt->reentrancy-1], name); #ifdef HAVE_BKTR __dump_backtrace(<->backtrace[lt->reentrancy-1], canlog); #endif DO_THREAD_CRASH; + } } if (--lt->reentrancy < 0) { @@ -1065,13 +1081,6 @@ static inline int _ast_rwlock_unlock(ast_rwlock_t *t, const char *name, lt->reentrancy = 0; } - if (lt->reentrancy < AST_MAX_REENTRANCY) { - lt->file[lt->reentrancy] = NULL; - lt->lineno[lt->reentrancy] = 0; - lt->func[lt->reentrancy] = NULL; - lt->thread[lt->reentrancy] = 0; - } - #ifdef HAVE_BKTR if (lt->reentrancy) { bt = <->backtrace[lt->reentrancy - 1]; |