diff options
author | twilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2011-06-16 22:49:49 +0000 |
---|---|---|
committer | twilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2011-06-16 22:49:49 +0000 |
commit | 62b90dd0a4ea809bdb11bc27288b6acf717edcd8 (patch) | |
tree | b2aaf8bd69e1f83f2b40fa94e3fddeb927b658b9 /channels/chan_local.c | |
parent | f81499e93954a8a4ca7993374e10398b063f4eab (diff) |
Merged revisions 324048 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8
........
r324048 | twilson | 2011-06-16 17:35:41 -0500 (Thu, 16 Jun 2011) | 8 lines
Lock the channel before calling the setoption callback
The channel needs to be locked before calling these callback functions. Also,
sip_setoption needs to lock the pvt and a check p->rtp is non-null before using
it.
Review: https://reviewboard.asterisk.org/r/1220/
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@324050 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_local.c')
-rw-r--r-- | channels/chan_local.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/channels/chan_local.c b/channels/chan_local.c index 0ceb432b0..3c16fc51a 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -217,6 +217,7 @@ static void awesome_locking(struct local_pvt *p, struct ast_channel **outchan, s *outchan = p->chan; } +/* Called with ast locked */ static int local_setoption(struct ast_channel *ast, int option, void * data, int datalen) { int res = 0; @@ -225,27 +226,22 @@ static int local_setoption(struct ast_channel *ast, int option, void * data, int ast_chan_write_info_t *write_info; if (option != AST_OPTION_CHANNEL_WRITE) { - res = -1; - goto setoption_cleanup; + return -1; } write_info = data; if (write_info->version != AST_CHAN_WRITE_INFO_T_VERSION) { ast_log(LOG_ERROR, "The chan_write_info_t type has changed, and this channel hasn't been updated!\n"); - res = -1; - goto setoption_cleanup; + return -1; } /* get the tech pvt */ - ast_channel_lock(ast); if (!(p = ast->tech_pvt)) { - ast_channel_unlock(ast); - res = -1; - goto setoption_cleanup; + return -1; } ao2_ref(p, 1); - ast_channel_unlock(ast); + ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */ /* get the channel we are supposed to write to */ ao2_lock(p); @@ -272,6 +268,7 @@ setoption_cleanup: if (otherchan) { ast_channel_unref(otherchan); } + ast_channel_lock(ast); /* Lock back before we leave */ return res; } @@ -348,6 +345,7 @@ static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct return bridged; } +/* Called with ast locked */ static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen) { struct local_pvt *p; @@ -361,21 +359,18 @@ static int local_queryoption(struct ast_channel *ast, int option, void *data, in } /* for some reason the channel is not locked in channel.c when this function is called */ - ast_channel_lock(ast); if (!(p = ast->tech_pvt)) { - ast_channel_unlock(ast); return -1; } ao2_lock(p); if (!(tmp = IS_OUTBOUND(ast, p) ? p->owner : p->chan)) { ao2_unlock(p); - ast_channel_unlock(ast); return -1; } ast_channel_ref(tmp); ao2_unlock(p); - ast_channel_unlock(ast); + ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */ ast_channel_lock(tmp); if (!(bridged = ast_bridged_channel(tmp))) { @@ -394,6 +389,7 @@ query_cleanup: if (tmp) { tmp = ast_channel_unref(tmp); } + ast_channel_lock(ast); /* Lock back before we leave */ return res; } |