25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-22 16:20:52 +01:00

Merge pull request #295 from weiss/xep-0198

XEP-0198: Change state immediately when gen_tcp:send/2 returns failure
This commit is contained in:
Evgeny Khramtsov 2014-09-07 07:27:07 +04:00
commit f0887e45b8

View File

@ -1196,9 +1196,7 @@ session_established({xmlstreamerror, _}, StateData) ->
send_element(StateData, ?INVALID_XML_ERR), send_element(StateData, ?INVALID_XML_ERR),
send_trailer(StateData), send_trailer(StateData),
{stop, normal, StateData}; {stop, normal, StateData};
session_established(closed, StateData) session_established(closed, #state{mgmt_state = active} = StateData) ->
when StateData#state.mgmt_timeout > 0,
StateData#state.mgmt_state == active ->
fsm_next_state(wait_for_resume, StateData); fsm_next_state(wait_for_resume, StateData);
session_established(closed, StateData) -> session_established(closed, StateData) ->
{stop, normal, StateData}. {stop, normal, StateData}.
@ -1682,8 +1680,7 @@ handle_info({route, From, To,
handle_info({'DOWN', Monitor, _Type, _Object, _Info}, handle_info({'DOWN', Monitor, _Type, _Object, _Info},
_StateName, StateData) _StateName, StateData)
when Monitor == StateData#state.socket_monitor -> when Monitor == StateData#state.socket_monitor ->
if StateData#state.mgmt_timeout > 0, if StateData#state.mgmt_state == active;
StateData#state.mgmt_state == active orelse
StateData#state.mgmt_state == pending -> StateData#state.mgmt_state == pending ->
fsm_next_state(wait_for_resume, StateData); fsm_next_state(wait_for_resume, StateData);
true -> true ->
@ -1841,7 +1838,8 @@ send_text(StateData, Text) when StateData#state.mgmt_state == active ->
?DEBUG("Send XML on stream = ~p", [Text]), ?DEBUG("Send XML on stream = ~p", [Text]),
case catch (StateData#state.sockmod):send(StateData#state.socket, Text) of case catch (StateData#state.sockmod):send(StateData#state.socket, Text) of
{'EXIT', _} -> {'EXIT', _} ->
(StateData#state.sockmod):close(StateData#state.socket); (StateData#state.sockmod):close(StateData#state.socket),
error;
_ -> _ ->
ok ok
end; end;
@ -1860,8 +1858,13 @@ send_element(StateData, El) ->
send_stanza(StateData, Stanza) when StateData#state.mgmt_state == pending -> send_stanza(StateData, Stanza) when StateData#state.mgmt_state == pending ->
mgmt_queue_add(StateData, Stanza); mgmt_queue_add(StateData, Stanza);
send_stanza(StateData, Stanza) when StateData#state.mgmt_state == active -> send_stanza(StateData, Stanza) when StateData#state.mgmt_state == active ->
send_stanza_and_ack_req(StateData, Stanza), NewStateData = case send_stanza_and_ack_req(StateData, Stanza) of
mgmt_queue_add(StateData, Stanza); ok ->
StateData;
error ->
StateData#state{mgmt_state = pending}
end,
mgmt_queue_add(NewStateData, Stanza);
send_stanza(StateData, Stanza) -> send_stanza(StateData, Stanza) ->
send_element(StateData, Stanza), send_element(StateData, Stanza),
StateData. StateData.
@ -2458,11 +2461,15 @@ fsm_next_state_gc(StateName, PackedStateData) ->
%% fsm_next_state: Generate the next_state FSM tuple with different %% fsm_next_state: Generate the next_state FSM tuple with different
%% timeout, depending on the future state %% timeout, depending on the future state
fsm_next_state(session_established, #state{mgmt_state = pending} = StateData) ->
fsm_next_state(wait_for_resume, StateData);
fsm_next_state(session_established, StateData) -> fsm_next_state(session_established, StateData) ->
{next_state, session_established, StateData, {next_state, session_established, StateData,
?C2S_HIBERNATE_TIMEOUT}; ?C2S_HIBERNATE_TIMEOUT};
fsm_next_state(wait_for_resume, StateData) fsm_next_state(wait_for_resume, #state{mgmt_timeout = 0} = StateData) ->
when StateData#state.mgmt_state /= pending -> {stop, normal, StateData};
fsm_next_state(wait_for_resume, #state{mgmt_pending_since = undefined} =
StateData) ->
?INFO_MSG("Waiting for resumption of stream for ~s", ?INFO_MSG("Waiting for resumption of stream for ~s",
[jlib:jid_to_string(StateData#state.jid)]), [jlib:jid_to_string(StateData#state.jid)]),
{next_state, wait_for_resume, {next_state, wait_for_resume,