diff options
author | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-03-16 15:39:15 +0000 |
---|---|---|
committer | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-03-16 15:39:15 +0000 |
commit | f9f569da87fe9ce4a971858630c944a085fb3253 (patch) | |
tree | 4edb9d49949204e2d365a106e7843b19f9582e26 /channels | |
parent | 24d139ecc3c2dbff6b01406a72d77d4b24151cfa (diff) |
Fixup glare detection, to fix a memory leak of a local pvt structure.
(closes issue #14656)
Reported by: caspy
Patches:
20090313__bug14656__2.diff.txt uploaded by tilghman (license 14)
Tested by: caspy
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@182208 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_local.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/channels/chan_local.c b/channels/chan_local.c index a400a6363..db8bec313 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -168,23 +168,17 @@ static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_fra /* Recalculate outbound channel */ other = isoutbound ? p->owner : p->chan; - /* Set glare detection */ - ast_set_flag(p, LOCAL_GLARE_DETECT); - if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) { - /* We had a glare on the hangup. Forget all this business, - return and destroy p. */ - ast_mutex_unlock(&p->lock); - p = local_pvt_destroy(p); - return -1; - } if (!other) { - ast_clear_flag(p, LOCAL_GLARE_DETECT); return 0; } /* do not queue frame if generator is on both local channels */ - if (us && us->generator && other->generator) + if (us && us->generator && other->generator) { return 0; + } + + /* Set glare detection */ + ast_set_flag(p, LOCAL_GLARE_DETECT); /* Ensure that we have both channels locked */ while (other && ast_channel_trylock(other)) { @@ -202,6 +196,17 @@ static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_fra other = isoutbound ? p->owner : p->chan; } + /* Since glare detection only occurs within this function, and because + * a pvt flag cannot be set without having the pvt lock, this is the only + * location where we could detect a cancelling of the queue. */ + if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) { + /* We had a glare on the hangup. Forget all this business, + return and destroy p. */ + ast_mutex_unlock(&p->lock); + p = local_pvt_destroy(p); + return -1; + } + if (other) { ast_queue_frame(other, f); ast_channel_unlock(other); |