mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-02 03:48:02 +00:00
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: https://origsvn.digium.com/svn/asterisk/trunk@125133 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -1048,15 +1048,31 @@ static inline int _ast_rwlock_unlock(ast_rwlock_t *t, const char *name,
|
|||||||
#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
|
#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
|
||||||
|
|
||||||
ast_reentrancy_lock(lt);
|
ast_reentrancy_lock(lt);
|
||||||
if (lt->reentrancy && (lt->thread[lt->reentrancy-1] != pthread_self())) {
|
if (lt->reentrancy) {
|
||||||
__ast_mutex_logger("%s line %d (%s): attempted unlock rwlock '%s' without owning it!\n",
|
int lock_found = 0;
|
||||||
filename, line, func, name);
|
int i;
|
||||||
__ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
|
for (i = lt->reentrancy-1; i >= 0; --i) {
|
||||||
lt->file[lt->reentrancy-1], lt->lineno[lt->reentrancy-1], lt->func[lt->reentrancy-1], name);
|
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
|
#ifdef HAVE_BKTR
|
||||||
__dump_backtrace(<->backtrace[lt->reentrancy-1], canlog);
|
__dump_backtrace(<->backtrace[lt->reentrancy-1], canlog);
|
||||||
#endif
|
#endif
|
||||||
DO_THREAD_CRASH;
|
DO_THREAD_CRASH;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (--lt->reentrancy < 0) {
|
if (--lt->reentrancy < 0) {
|
||||||
@@ -1065,13 +1081,6 @@ static inline int _ast_rwlock_unlock(ast_rwlock_t *t, const char *name,
|
|||||||
lt->reentrancy = 0;
|
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
|
#ifdef HAVE_BKTR
|
||||||
if (lt->reentrancy) {
|
if (lt->reentrancy) {
|
||||||
bt = <->backtrace[lt->reentrancy - 1];
|
bt = <->backtrace[lt->reentrancy - 1];
|
||||||
|
|||||||
Reference in New Issue
Block a user