Add private lock deadlock avoidance callback to PRI and SS7.
Factor out the equivalent function for analog. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@313100 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
parent
68dd87ef0d
commit
ce17f956dc
|
@ -3320,6 +3320,7 @@ static struct sig_pri_callback dahdi_pri_callbacks =
|
||||||
.dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
|
.dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
|
||||||
.lock_private = my_lock_private,
|
.lock_private = my_lock_private,
|
||||||
.unlock_private = my_unlock_private,
|
.unlock_private = my_unlock_private,
|
||||||
|
.deadlock_avoidance_private = my_deadlock_avoidance_private,
|
||||||
.new_ast_channel = my_new_pri_ast_channel,
|
.new_ast_channel = my_new_pri_ast_channel,
|
||||||
.fixup_chans = my_pri_fixup_chans,
|
.fixup_chans = my_pri_fixup_chans,
|
||||||
.set_alarm = my_set_alarm,
|
.set_alarm = my_set_alarm,
|
||||||
|
@ -3483,6 +3484,7 @@ static struct sig_ss7_callback dahdi_ss7_callbacks =
|
||||||
{
|
{
|
||||||
.lock_private = my_lock_private,
|
.lock_private = my_lock_private,
|
||||||
.unlock_private = my_unlock_private,
|
.unlock_private = my_unlock_private,
|
||||||
|
.deadlock_avoidance_private = my_deadlock_avoidance_private,
|
||||||
|
|
||||||
.set_echocanceller = my_set_echocanceller,
|
.set_echocanceller = my_set_echocanceller,
|
||||||
.set_loopback = my_ss7_set_loopback,
|
.set_loopback = my_ss7_set_loopback,
|
||||||
|
|
|
@ -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)
|
static void analog_unlock_private(struct analog_pvt *p)
|
||||||
{
|
{
|
||||||
if (p->calls->unlock_private) {
|
if (p->calls->unlock_private) {
|
||||||
p->calls->unlock_private(p->chan_pvt);
|
p->calls->unlock_private(p->chan_pvt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void analog_lock_private(struct analog_pvt *p)
|
static void analog_lock_private(struct analog_pvt *p)
|
||||||
{
|
{
|
||||||
if (p->calls->lock_private) {
|
if (p->calls->lock_private) {
|
||||||
p->calls->lock_private(p->chan_pvt);
|
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
|
* \internal
|
||||||
|
@ -563,12 +571,7 @@ static void analog_lock_sub_owner(struct analog_pvt *pvt, enum analog_sub sub_id
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* We must unlock the private to avoid the possibility of a deadlock */
|
/* We must unlock the private to avoid the possibility of a deadlock */
|
||||||
if (pvt->calls->deadlock_avoidance_private) {
|
analog_deadlock_avoidance_private(pvt);
|
||||||
pvt->calls->deadlock_avoidance_private(pvt->chan_pvt);
|
|
||||||
} else {
|
|
||||||
/* Don't use 100% CPU if required callback not present. */
|
|
||||||
usleep(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -321,6 +321,16 @@ static void sig_pri_lock_private(struct sig_pri_chan *p)
|
||||||
p->calls->lock_private(p->chan_pvt);
|
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)
|
static inline int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
@ -328,7 +338,7 @@ static inline int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
|
||||||
do {
|
do {
|
||||||
res = ast_mutex_trylock(&pri->lock);
|
res = ast_mutex_trylock(&pri->lock);
|
||||||
if (res) {
|
if (res) {
|
||||||
PRI_DEADLOCK_AVOIDANCE(p);
|
sig_pri_deadlock_avoidance_private(p);
|
||||||
}
|
}
|
||||||
} while (res);
|
} while (res);
|
||||||
/* Then break the poll */
|
/* 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 */
|
/* We must unlock the PRI to avoid the possibility of a deadlock */
|
||||||
ast_mutex_unlock(&pri->lock);
|
ast_mutex_unlock(&pri->lock);
|
||||||
PRI_DEADLOCK_AVOIDANCE(pri->pvts[chanpos]);
|
sig_pri_deadlock_avoidance_private(pri->pvts[chanpos]);
|
||||||
ast_mutex_lock(&pri->lock);
|
ast_mutex_lock(&pri->lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,6 +167,8 @@ struct sig_pri_callback {
|
||||||
void (* const unlock_private)(void *pvt);
|
void (* const unlock_private)(void *pvt);
|
||||||
/* Lock the private in the signalling private structure. ... */
|
/* Lock the private in the signalling private structure. ... */
|
||||||
void (* const lock_private)(void *pvt);
|
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
|
/* 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,
|
* 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. */
|
* (CWCID) the library absorbs DTMF events received. */
|
||||||
|
|
|
@ -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)
|
void sig_ss7_set_alarm(struct sig_ss7_chan *p, int in_alarm)
|
||||||
{
|
{
|
||||||
p->inalarm = 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 */
|
/* We must unlock the SS7 to avoid the possibility of a deadlock */
|
||||||
ast_mutex_unlock(&ss7->lock);
|
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);
|
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 {
|
do {
|
||||||
res = ast_mutex_trylock(&ss7->lock);
|
res = ast_mutex_trylock(&ss7->lock);
|
||||||
if (res) {
|
if (res) {
|
||||||
SIG_SS7_DEADLOCK_AVOIDANCE(pvt);
|
sig_ss7_deadlock_avoidance_private(pvt);
|
||||||
}
|
}
|
||||||
} while (res);
|
} while (res);
|
||||||
/* Then break the poll */
|
/* Then break the poll */
|
||||||
|
|
|
@ -105,6 +105,8 @@ struct sig_ss7_callback {
|
||||||
void (* const unlock_private)(void *pvt);
|
void (* const unlock_private)(void *pvt);
|
||||||
/* Lock the private in the signaling private structure. */
|
/* Lock the private in the signaling private structure. */
|
||||||
void (* const lock_private)(void *pvt);
|
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);
|
int (* const set_echocanceller)(void *pvt, int enable);
|
||||||
void (* const set_loopback)(void *pvt, int enable);
|
void (* const set_loopback)(void *pvt, int enable);
|
||||||
|
|
Loading…
Reference in New Issue