freetdm: Fixes for native signaling bridge (now tested, and works for basic call flows)

- Fix typo when unlocking channel that resulted in deadlock
         - Defer clearing of the peer data until it is completely safe (next call)
This commit is contained in:
Moises Silva 2012-01-26 23:31:29 -05:00
parent 23a328389b
commit f2cdb8c6c7
2 changed files with 14 additions and 15 deletions

View File

@ -263,6 +263,9 @@ static ftdm_status_t ftdm_core_set_state(const char *file, const char *func, int
} }
} }
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
goto perform_state_change;
}
if (ftdmchan->span->state_map) { if (ftdmchan->span->state_map) {
ok = ftdm_parse_state_map(ftdmchan, state, ftdmchan->span->state_map); ok = ftdm_parse_state_map(ftdmchan, state, ftdmchan->span->state_map);
@ -354,6 +357,8 @@ end:
goto done; goto done;
} }
perform_state_change:
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Changed state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state)); ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Changed state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
ftdmchan->last_state = ftdmchan->state; ftdmchan->last_state = ftdmchan->state;
ftdmchan->state = state; ftdmchan->state = state;

View File

@ -442,7 +442,7 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
ftdm_safe_free(sngss7_event); ftdm_safe_free(sngss7_event);
} }
ftdm_channel_lock(ftdmchan); ftdm_channel_unlock(ftdmchan);
} }
/* clean out all pending stack events */ /* clean out all pending stack events */
@ -564,6 +564,8 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic); SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic);
ftdm_safe_free(event_clone); ftdm_safe_free(event_clone);
} }
/* clear the peer if any */
sngss7_info->peer_data = NULL;
} }
/* clone the event and save it for later usage */ /* clone the event and save it for later usage */
@ -596,7 +598,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
ftdm_channel_lock(peer_chan); ftdm_channel_lock(peer_chan);
if (peer_chan->state != FTDM_CHANNEL_STATE_DOWN) { if (peer_chan->state != FTDM_CHANNEL_STATE_DOWN) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); ftdm_set_state(peer_chan, FTDM_CHANNEL_STATE_DOWN);
} }
ftdm_channel_unlock(peer_chan); ftdm_channel_unlock(peer_chan);
@ -923,19 +925,7 @@ static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t
case FTDM_CHANNEL_STATE_DOWN: case FTDM_CHANNEL_STATE_DOWN:
{ {
/* both peers come here after the channel processing the RLC moves the pair to DOWN */
ftdm_channel_t *close_chan = ftdmchan; ftdm_channel_t *close_chan = ftdmchan;
/* detach native bridging if needed (only the outbound leg is responsible for that to avoid races or messy locks) */
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
sngss7_chan_data_t *peer_info = sngss7_info->peer_data;
sngss7_info->peer_data = NULL;
if (peer_info) {
peer_info->peer_data = NULL;
}
}
/* close the channel */
ftdm_channel_close (&close_chan); ftdm_channel_close (&close_chan);
} }
break; break;
@ -975,6 +965,10 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan)
sngss7_info->ckt_flags, sngss7_info->ckt_flags,
sngss7_info->blk_flags); sngss7_info->blk_flags);
if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
sngss7_info->peer_data = NULL;
}
if (sngss7_info->peer_data) { if (sngss7_info->peer_data) {
return ftdm_sangoma_ss7_native_bridge_state_change(ftdmchan); return ftdm_sangoma_ss7_native_bridge_state_change(ftdmchan);
} }