mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	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:
		| @@ -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, | ||||
|   | ||||
| @@ -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); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -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. */ | ||||
|   | ||||
| @@ -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 */ | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user