freeswitch
freeswitch copied to clipboard
uuid_transfer may cause the channel to remain in the CS_RESET state
Describe the bug if Aleg is bridged with Bleg, then we call api uuid_transfer(Bleg_uuid, -both conference:conference_name inline) to transfer A-leg and B-leg to conference. Because of thread race problem , Bleg may be remain in the CS_RESTE state.
Code Problem
In function switch_ivr_session_transfer , api uuid_transfer will set Bleg channel state to CS_ROUTING.
But before doing Bleg transfer, switch_ivr_session_transfer will first transfer Aleg to "conference" application. Aleg will unbrige with Bleg now. So Bleg session thread will do as follow(in function switch_ivr_multi_threaded_bridge):
Since switch_channel_get_state is not execute with lock, it may get a state that is not CS_ROUTING, and then other thread (thread execute uuid_transfer) switch_ivr_session_transfer set Bleg to CS_ROUTING, then Bleg session thread set channel state to CS_RESET.
Now, no thread can set Bleg to CS_ROUTING.
Expected behavior I think we should make
state = switch_channel_get_state(caller_channel);
if (!(state == CS_RESET || state == CS_PARK || state == CS_ROUTING || state == CS_EXECUTE)) {
switch_channel_set_state(caller_channel, CS_RESET);
}
to be in a transaction with lock . So other thread modify channel state can be saw by session thread.
Package version or git hash
- master branch