diff options
author | Damien Wedhorn <voip@facts.com.au> | 2014-02-04 02:07:18 +0000 |
---|---|---|
committer | Damien Wedhorn <voip@facts.com.au> | 2014-02-04 02:07:18 +0000 |
commit | a744b29ab5561185929f861744dbdd0af477eabc (patch) | |
tree | 15ba39dd9f740406b1f402db6caf4f4e193e3cc7 /channels/chan_skinny.c | |
parent | 01af8d6e12b4ff76a7b234bf2a78d3e0c27cd657 (diff) |
Skinny - Fix deadlock when pickup of no call.
Locking issues in skinny when picking up a call that doesn't exist. Cleaned
up sub locking by fully removing and using the chan lock instead. Also
changed ast_call_pickup to check whether chan was masq'd.
(closes issue ASTERISK-23249)
Reported by: wedhorn
Tested by: snuffy, myself
Patches:
skinny-locking01.diff uploaded by wedhorn (license 5019)
........
Merged revisions 407197 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@407198 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_skinny.c')
-rw-r--r-- | channels/chan_skinny.c | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c index ca0cd2cb6..57b657404 100644 --- a/channels/chan_skinny.c +++ b/channels/chan_skinny.c @@ -1384,7 +1384,6 @@ static int matchdigittimeout = 3000; #define DIALTYPE_XFER 1<<2 struct skinny_subchannel { - ast_mutex_t lock; struct ast_channel *owner; struct ast_rtp_instance *rtp; struct ast_rtp_instance *vrtp; @@ -3616,10 +3615,10 @@ static enum ast_rtp_glue_result skinny_get_rtp_peer(struct ast_channel *c, struc if (!(sub = ast_channel_tech_pvt(c))) return AST_RTP_GLUE_RESULT_FORBID; - ast_mutex_lock(&sub->lock); + skinny_locksub(sub); if (!(sub->rtp)){ - ast_mutex_unlock(&sub->lock); + skinny_unlocksub(sub); return AST_RTP_GLUE_RESULT_FORBID; } @@ -3633,7 +3632,7 @@ static enum ast_rtp_glue_result skinny_get_rtp_peer(struct ast_channel *c, struc SKINNY_DEBUG(DEBUG_AUDIO, 4, "skinny_get_rtp_peer() Using AST_RTP_GLUE_RESULT_LOCAL \n"); } - ast_mutex_unlock(&sub->lock); + skinny_unlocksub(sub); return res; @@ -4802,7 +4801,7 @@ static void start_rtp(struct skinny_subchannel *sub) int hasvideo = 0; struct ast_sockaddr bindaddr_tmp; - ast_mutex_lock(&sub->lock); + skinny_locksub(sub); /* Allocate the RTP */ ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr); sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL); @@ -4840,7 +4839,7 @@ static void start_rtp(struct skinny_subchannel *sub) /* Create the RTP connection */ transmit_connect(d, sub); - ast_mutex_unlock(&sub->lock); + skinny_unlocksub(sub); } static void destroy_rtp(struct skinny_subchannel *sub) @@ -5036,13 +5035,11 @@ static int skinny_hangup(struct ast_channel *ast) SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %d - Destroying\n", sub->callid); - ast_mutex_lock(&sub->lock); skinny_set_owner(sub, NULL); ast_channel_tech_pvt_set(ast, NULL); destroy_rtp(sub); ast_free(sub->origtonum); ast_free(sub->origtoname); - ast_mutex_unlock(&sub->lock); ast_free(sub); ast_module_unref(ast_module_info->self); return 0; @@ -5115,9 +5112,9 @@ static struct ast_frame *skinny_read(struct ast_channel *ast) { struct ast_frame *fr; struct skinny_subchannel *sub = ast_channel_tech_pvt(ast); - ast_mutex_lock(&sub->lock); + skinny_locksub(sub); fr = skinny_rtp_read(sub); - ast_mutex_unlock(&sub->lock); + skinny_unlocksub(sub); return fr; } @@ -5144,11 +5141,11 @@ static int skinny_write(struct ast_channel *ast, struct ast_frame *frame) } } if (sub) { - ast_mutex_lock(&sub->lock); + skinny_locksub(sub); if (sub->rtp) { res = ast_rtp_instance_write(sub->rtp, frame); } - ast_mutex_unlock(&sub->lock); + skinny_unlocksub(sub); } return res; } @@ -5425,8 +5422,6 @@ static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subli ast_channel_unref(tmp); return NULL; } else { - ast_mutex_init(&sub->lock); - skinny_set_owner(sub, tmp); sub->callid = callnums++; d->lastlineinstance = l->instance; @@ -7270,9 +7265,14 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse ast_channel_ref(c); sub = ast_channel_tech_pvt(c); ast_pickup_call(c); - ast_hangup(c); - setsubstate(sub, SUBSTATE_CONNECTED); - ast_channel_unref(c); + if (sub->owner == c) { + ast_channel_unref(c); + dumpsub(sub, 1); + } else { + ast_hangup(c); + setsubstate(sub, SUBSTATE_CONNECTED); + ast_channel_unref(c); + } } break; case SOFTKEY_FORCEDIAL: @@ -8765,11 +8765,11 @@ static int unload_module(void) AST_LIST_TRAVERSE(&d->lines, l, list){ ast_mutex_lock(&l->lock); AST_LIST_TRAVERSE(&l->sub, sub, list) { - ast_mutex_lock(&sub->lock); + skinny_locksub(sub); if (sub->owner) { ast_softhangup(sub->owner, AST_SOFTHANGUP_APPUNLOAD); } - ast_mutex_unlock(&sub->lock); + skinny_unlocksub(sub); } if (l->mwi_event_sub) { l->mwi_event_sub = stasis_unsubscribe(l->mwi_event_sub); |