Fix crash in chanspy (bug #5332)
authorMark Spencer <markster@digium.com>
Thu, 13 Oct 2005 22:10:16 +0000 (22:10 +0000)
committerMark Spencer <markster@digium.com>
Thu, 13 Oct 2005 22:10:16 +0000 (22:10 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6768 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_chanspy.c
channel.c

index 1c22ddb..10f4959 100755 (executable)
@@ -255,8 +255,9 @@ static int spy_generate(struct ast_channel *chan, void *data, int len, int sampl
        short buf0[1280], buf1[1280], buf[1280];
                
        if (csth->spy.status == CHANSPY_DONE) {
+               /* Channel is already gone more than likely */
                return -1;
-        }
+       }
 
        ast_mutex_lock(&csth->spy.lock);
        while((f = csth->spy.queue[0])) {
@@ -326,7 +327,6 @@ static int spy_generate(struct ast_channel *chan, void *data, int len, int sampl
        frame.datalen = x * 2;
 
        if (ast_write(chan, &frame)) {
-               csth->spy.status = CHANSPY_DONE;
                return -1;
        }
 
@@ -373,24 +373,12 @@ static void stop_spying(struct ast_channel *chan, struct ast_channel_spy *spy)
        struct ast_channel_spy *cptr=NULL, *prev=NULL;
        int count = 0;
 
-       while(ast_mutex_trylock(&chan->lock)) {
-               /* if its locked already it's almost surely hanging up and we are too late 
-                  we can safely remove the head pointer if it points at us without needing a lock.
-                  since everybody spying will be in the same boat whomever is pointing at the head
-                  will surely erase it which is all we really need since it's a linked list of
-                  staticly declared structs that belong to each spy.
-               */
-               if (chan->spiers == spy) {
-                       chan->spiers = NULL;
-                       return;
-               }
-               count++;
-               if (count > 10) {
-                       return;
-               }
-               sched_yield();
-       }
+       /* If our status has changed, then the channel we're spying on is gone....
+          DON'T TOUCH IT!!!  RUN AWAY!!! */
+       if (spy->status != CHANSPY_RUNNING)
+               return;
 
+       ast_mutex_lock(&chan->lock);
        for(cptr=chan->spiers; cptr; cptr=cptr->next) {
                if (cptr == spy) {
                        if (prev) {
index cf972e9..3218c8d 100755 (executable)
--- a/channel.c
+++ b/channel.c
@@ -939,22 +939,14 @@ void ast_channel_free(struct ast_channel *chan)
 static void ast_spy_detach(struct ast_channel *chan) 
 {
        struct ast_channel_spy *chanspy;
-       int to=3000;
-       int sleepms = 100;
 
+       /* Marking the spies as done is sufficient.  Chanspy or spy users will get the picture. */
        for (chanspy = chan->spiers; chanspy; chanspy = chanspy->next) {
                if (chanspy->status == CHANSPY_RUNNING) {
                        chanspy->status = CHANSPY_DONE;
                }
        }
 
-       /* signal all the spys to get lost and allow them time to unhook themselves 
-          god help us if they don't......
-       */
-       while (chan->spiers && to >= 0) {
-               ast_safe_sleep(chan, sleepms);
-               to -= sleepms;
-       }
        chan->spiers = NULL;
        return;
 }