mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +00:00 
			
		
		
		
	Merged revisions 100581 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r100581 | russell | 2008-01-28 11:15:41 -0600 (Mon, 28 Jan 2008) | 9 lines Make some deadlock related fixes. These bugs were discovered and reported internally at Digium by Steve Pitts. - Fix up chan_local to ensure that the channel lock is held before the local pvt lock. - Don't hold the channel lock when executing the timing function, as it can cause a deadlock when using chan_local. This actually changes the code back to be how it was before the change for issue #10765. But, I added some other locking that I think will prevent the problem reported there, as well. ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@100582 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -161,8 +161,6 @@ static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_fra | ||||
| { | ||||
| 	struct ast_channel *other = NULL; | ||||
|  | ||||
| retrylock:		 | ||||
|  | ||||
| 	/* Recalculate outbound channel */ | ||||
| 	other = isoutbound ? p->owner : p->chan; | ||||
|  | ||||
| @@ -180,27 +178,28 @@ retrylock: | ||||
| 		ast_clear_flag(p, LOCAL_GLARE_DETECT); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	if (ast_channel_trylock(other)) { | ||||
| 		/* Failed to lock.  Release main lock and try again */ | ||||
| 		ast_mutex_unlock(&p->lock); | ||||
| 		if (us) { | ||||
| 			if (ast_channel_unlock(us)) { | ||||
| 				ast_log(LOG_WARNING, "%s wasn't locked while sending %d/%d\n", | ||||
| 					us->name, f->frametype, f->subclass); | ||||
| 				us = NULL; | ||||
| 			} | ||||
| 		} | ||||
| 		/* Wait just a bit */ | ||||
| 		usleep(1); | ||||
| 		/* Only we can destroy ourselves, so we can't disappear here */ | ||||
| 		if (us) | ||||
|  | ||||
| 	ast_mutex_unlock(&p->lock); | ||||
|  | ||||
| 	/* Ensure that we have both channels locked */ | ||||
| 	if (us) { | ||||
| 		while (ast_channel_trylock(other)) { | ||||
| 			ast_channel_unlock(us); | ||||
| 			usleep(1); | ||||
| 			ast_channel_lock(us); | ||||
| 		ast_mutex_lock(&p->lock); | ||||
| 		goto retrylock; | ||||
| 		} | ||||
| 	} else { | ||||
| 		ast_channel_lock(other); | ||||
| 	} | ||||
|  | ||||
| 	ast_queue_frame(other, f); | ||||
|  | ||||
| 	ast_channel_unlock(other); | ||||
|  | ||||
| 	ast_mutex_lock(&p->lock); | ||||
|  | ||||
| 	ast_clear_flag(p, LOCAL_GLARE_DETECT); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user