Eliminate deadlock potential in dahdi_fixup().
authorRichard Mudgett <rmudgett@digium.com>
Wed, 9 Jun 2010 16:54:38 +0000 (16:54 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Wed, 9 Jun 2010 16:54:38 +0000 (16:54 +0000)
Calling dahdi_indicate() within dahdi_fixup() while the owner pointers are
in a potentially inconsistent state is a potentially bad thing in
principle.

However, calling dahdi_indicate() when the channel private lock is already
held can cause a deadlock if the PRI lock is needed because
dahdi_indicate() will also get the channel private lock.  The pri_grab()
function assumes that the channel private lock is held once to avoid
deadlock.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@269307 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_dahdi.c

index a71f3ab..d054323 100644 (file)
@@ -7085,9 +7085,6 @@ static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
                                dahdi_unlink(NULL, p, 0);
                        p->subs[x].owner = newchan;
                }
-       if (newchan->_state == AST_STATE_RINGING)
-               dahdi_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
-
        if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
                analog_fixup(oldchan, newchan, p->sig_pvt);
        } 
@@ -7099,6 +7096,10 @@ static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
 
        update_conf(p);
        ast_mutex_unlock(&p->lock);
+
+       if (newchan->_state == AST_STATE_RINGING) {
+               dahdi_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
+       }
        return 0;
 }