aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authormmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2008-06-25 22:25:20 +0000
committermmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2008-06-25 22:25:20 +0000
commit802aa72966c5fd4ea72f8334942dee062dcec88b (patch)
tree32f13c0d80f4b8d22ee4cd815f07ad24d5e08fc6 /include
parentf635bc335f80a8b6e02e1e7148b494821ea77f04 (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.h33
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(&lt->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 = &lt->backtrace[lt->reentrancy - 1];