freetdm: * Avoid acquiring the span mutex if the pendingchans queue is available for use *
* FreeTDM modules using the old FTDM_SPAN_STATE_CHANGE flag should be updated * * until then, they are still vulnerable to deadlock situations * * Modules pending update: (ftmod_analog, ftmod_libpri, ftmod_isdn) * * Fixes Sangoma redmine ticket #1791 0 FTDM span stop deadlock *
This commit is contained in:
parent
946f8af5a9
commit
3b74246b16
|
@ -370,12 +370,19 @@ end:
|
|||
}
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->span->mutex);
|
||||
ftdm_set_flag(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
|
||||
if (ftdmchan->span->pendingchans) {
|
||||
ftdm_queue_enqueue(ftdmchan->span->pendingchans, ftdmchan);
|
||||
} else {
|
||||
/* there is a potential deadlock here, if a signaling module is processing
|
||||
* state changes while the ftdm_span_stop() function is called, the signaling
|
||||
* thread will block until it can acquire the span lock, but the thread calling
|
||||
* ftdm_span_stop() which holds the span lock is waiting on the signaling thread
|
||||
* to finish ... The only reason to acquire the span lock is this flag, new
|
||||
* signaling modules should use the pendingchans queue instead of this flag,
|
||||
* as of today a few modules need still to be updated before we can get rid of
|
||||
* this flag (ie, ftmod_libpri, ftmod_isdn, ftmod_analog) */
|
||||
ftdm_set_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
|
||||
}
|
||||
ftdm_mutex_unlock(ftdmchan->span->mutex);
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NONBLOCK)) {
|
||||
/* the channel should not block waiting for state processing */
|
||||
|
|
|
@ -173,6 +173,12 @@ typedef enum {
|
|||
FTDM_SPAN_SUSPENDED = (1 << 3),
|
||||
FTDM_SPAN_IN_THREAD = (1 << 4),
|
||||
FTDM_SPAN_STOP_THREAD = (1 << 5),
|
||||
/*! Signaling modules set this flag to use fchan->pendingchans queue instead
|
||||
* of the FTDM_SPAN_STATE_CHANGE flag to detect when there is channels with
|
||||
* a state change pending in the span. If you set this member you can't rely
|
||||
* on FTDM_SPAN_STATE_CHANGE anymore and must use the queue only instead. This
|
||||
* is the new way of detecting state changes, new modules should always set this
|
||||
* flag, the old modules still relying on FTDM_SPAN_STATE_CHANGE should be updated */
|
||||
FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6),
|
||||
FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7),
|
||||
FTDM_SPAN_USE_AV_RATE = (1 << 8),
|
||||
|
|
Loading…
Reference in New Issue