Add private lock deadlock avoidance callback to PRI and SS7.
authorRichard Mudgett <rmudgett@digium.com>
Fri, 8 Apr 2011 16:17:32 +0000 (16:17 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Fri, 8 Apr 2011 16:17:32 +0000 (16:17 +0000)
Factor out the equivalent function for analog.

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

channels/chan_dahdi.c
channels/sig_analog.c
channels/sig_pri.c
channels/sig_pri.h
channels/sig_ss7.c
channels/sig_ss7.h

index 04105ad..de2d0f4 100644 (file)
@@ -3320,6 +3320,7 @@ static struct sig_pri_callback dahdi_pri_callbacks =
        .dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
        .lock_private = my_lock_private,
        .unlock_private = my_unlock_private,
+       .deadlock_avoidance_private = my_deadlock_avoidance_private,
        .new_ast_channel = my_new_pri_ast_channel,
        .fixup_chans = my_pri_fixup_chans,
        .set_alarm = my_set_alarm,
@@ -3483,6 +3484,7 @@ static struct sig_ss7_callback dahdi_ss7_callbacks =
 {
        .lock_private = my_lock_private,
        .unlock_private = my_unlock_private,
+       .deadlock_avoidance_private = my_deadlock_avoidance_private,
 
        .set_echocanceller = my_set_echocanceller,
        .set_loopback = my_ss7_set_loopback,
index 1b40a9f..92eb191 100644 (file)
@@ -518,23 +518,31 @@ static void analog_all_subchannels_hungup(struct analog_pvt *p)
        }
 }
 
-#if 0
 static void analog_unlock_private(struct analog_pvt *p)
 {
        if (p->calls->unlock_private) {
                p->calls->unlock_private(p->chan_pvt);
        }
 }
-#endif
 
-#if 0
 static void analog_lock_private(struct analog_pvt *p)
 {
        if (p->calls->lock_private) {
                p->calls->lock_private(p->chan_pvt);
        }
 }
-#endif
+
+static void analog_deadlock_avoidance_private(struct analog_pvt *p)
+{
+       if (p->calls->deadlock_avoidance_private) {
+               p->calls->deadlock_avoidance_private(p->chan_pvt);
+       } else {
+               /* Fallback to manual avoidance if callback not present. */
+               analog_unlock_private(p);
+               usleep(1);
+               analog_lock_private(p);
+       }
+}
 
 /*!
  * \internal
@@ -563,12 +571,7 @@ static void analog_lock_sub_owner(struct analog_pvt *pvt, enum analog_sub sub_id
                        break;
                }
                /* We must unlock the private to avoid the possibility of a deadlock */
-               if (pvt->calls->deadlock_avoidance_private) {
-                       pvt->calls->deadlock_avoidance_private(pvt->chan_pvt);
-               } else {
-                       /* Don't use 100% CPU if required callback not present. */
-                       usleep(1);
-               }
+               analog_deadlock_avoidance_private(pvt);
        }
 }
 
index e76db86..308fa5d 100644 (file)
@@ -321,6 +321,16 @@ static void sig_pri_lock_private(struct sig_pri_chan *p)
                p->calls->lock_private(p->chan_pvt);
 }
 
+static void sig_pri_deadlock_avoidance_private(struct sig_pri_chan *p)
+{
+       if (p->calls->deadlock_avoidance_private) {
+               p->calls->deadlock_avoidance_private(p->chan_pvt);
+       } else {
+               /* Fallback to the old way if callback not present. */
+               PRI_DEADLOCK_AVOIDANCE(p);
+       }
+}
+
 static inline int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
 {
        int res;
@@ -328,7 +338,7 @@ static inline int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
        do {
                res = ast_mutex_trylock(&pri->lock);
                if (res) {
-                       PRI_DEADLOCK_AVOIDANCE(p);
+                       sig_pri_deadlock_avoidance_private(p);
                }
        } while (res);
        /* Then break the poll */
@@ -1123,7 +1133,7 @@ static void sig_pri_lock_owner(struct sig_pri_span *pri, int chanpos)
                }
                /* We must unlock the PRI to avoid the possibility of a deadlock */
                ast_mutex_unlock(&pri->lock);
-               PRI_DEADLOCK_AVOIDANCE(pri->pvts[chanpos]);
+               sig_pri_deadlock_avoidance_private(pri->pvts[chanpos]);
                ast_mutex_lock(&pri->lock);
        }
 }
index 148397f..0c9a5e1 100644 (file)
@@ -167,6 +167,8 @@ struct sig_pri_callback {
        void (* const unlock_private)(void *pvt);
        /* Lock the private in the signalling private structure.  ... */
        void (* const lock_private)(void *pvt);
+       /* Do deadlock avoidance for the private signaling structure lock.  */
+       void (* const deadlock_avoidance_private)(void *pvt);
        /* Function which is called back to handle any other DTMF events that are received.  Called by analog_handle_event.  Why is this
         * important to use, instead of just directly using events received before they are passed into the library?  Because sometimes,
         * (CWCID) the library absorbs DTMF events received. */
index 68ebc5a..ebc5ca8 100644 (file)
@@ -64,6 +64,16 @@ static void sig_ss7_lock_private(struct sig_ss7_chan *p)
        }
 }
 
+static void sig_ss7_deadlock_avoidance_private(struct sig_ss7_chan *p)
+{
+       if (p->calls->deadlock_avoidance_private) {
+               p->calls->deadlock_avoidance_private(p->chan_pvt);
+       } else {
+               /* Fallback to the old way if callback not present. */
+               SIG_SS7_DEADLOCK_AVOIDANCE(p);
+       }
+}
+
 void sig_ss7_set_alarm(struct sig_ss7_chan *p, int in_alarm)
 {
        p->inalarm = in_alarm;
@@ -255,7 +265,7 @@ static void sig_ss7_lock_owner(struct sig_ss7_linkset *ss7, int chanpos)
                }
                /* We must unlock the SS7 to avoid the possibility of a deadlock */
                ast_mutex_unlock(&ss7->lock);
-               SIG_SS7_DEADLOCK_AVOIDANCE(ss7->pvts[chanpos]);
+               sig_ss7_deadlock_avoidance_private(ss7->pvts[chanpos]);
                ast_mutex_lock(&ss7->lock);
        }
 }
@@ -1109,7 +1119,7 @@ static inline int ss7_grab(struct sig_ss7_chan *pvt, struct sig_ss7_linkset *ss7
        do {
                res = ast_mutex_trylock(&ss7->lock);
                if (res) {
-                       SIG_SS7_DEADLOCK_AVOIDANCE(pvt);
+                       sig_ss7_deadlock_avoidance_private(pvt);
                }
        } while (res);
        /* Then break the poll */
index 15b4a2a..73839b1 100644 (file)
@@ -105,6 +105,8 @@ struct sig_ss7_callback {
        void (* const unlock_private)(void *pvt);
        /* Lock the private in the signaling private structure. */
        void (* const lock_private)(void *pvt);
+       /* Do deadlock avoidance for the private signaling structure lock.  */
+       void (* const deadlock_avoidance_private)(void *pvt);
 
        int (* const set_echocanceller)(void *pvt, int enable);
        void (* const set_loopback)(void *pvt, int enable);