mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +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 */ | ||||
| 	 | ||||
| 	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]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user