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:
Moises Silva
2011-10-24 12:43:54 -04:00
parent 4aa0285a22
commit d79f95f2d6
2 changed files with 16 additions and 3 deletions

View File

@@ -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 */