diff options
author | Evgeny Khramtsov <xramtsov@gmail.com> | 2014-09-07 07:27:07 +0400 |
---|---|---|
committer | Evgeny Khramtsov <xramtsov@gmail.com> | 2014-09-07 07:27:07 +0400 |
commit | f0887e45b8d5452a4b348ec7be60d4a2ce6c2ad6 (patch) | |
tree | 39abd0d2cb4dfbda4e48c4309206104f65473d45 | |
parent | allow guide not to be compiled for install (diff) | |
parent | XEP-0198: Change state on gen_tcp:send/2 failure (diff) |
Merge pull request #295 from weiss/xep-0198
XEP-0198: Change state immediately when gen_tcp:send/2 returns failure
-rw-r--r-- | src/ejabberd_c2s.erl | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index ee293404..c734d91e 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -1196,9 +1196,7 @@ session_established({xmlstreamerror, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), send_trailer(StateData), {stop, normal, StateData}; -session_established(closed, StateData) - when StateData#state.mgmt_timeout > 0, - StateData#state.mgmt_state == active -> +session_established(closed, #state{mgmt_state = active} = StateData) -> fsm_next_state(wait_for_resume, StateData); session_established(closed, StateData) -> {stop, normal, StateData}. @@ -1682,8 +1680,7 @@ handle_info({route, From, To, handle_info({'DOWN', Monitor, _Type, _Object, _Info}, _StateName, StateData) when Monitor == StateData#state.socket_monitor -> - if StateData#state.mgmt_timeout > 0, - StateData#state.mgmt_state == active orelse + if StateData#state.mgmt_state == active; StateData#state.mgmt_state == pending -> fsm_next_state(wait_for_resume, StateData); true -> @@ -1841,7 +1838,8 @@ send_text(StateData, Text) when StateData#state.mgmt_state == active -> ?DEBUG("Send XML on stream = ~p", [Text]), case catch (StateData#state.sockmod):send(StateData#state.socket, Text) of {'EXIT', _} -> - (StateData#state.sockmod):close(StateData#state.socket); + (StateData#state.sockmod):close(StateData#state.socket), + error; _ -> ok end; @@ -1860,8 +1858,13 @@ send_element(StateData, El) -> send_stanza(StateData, Stanza) when StateData#state.mgmt_state == pending -> mgmt_queue_add(StateData, Stanza); send_stanza(StateData, Stanza) when StateData#state.mgmt_state == active -> - send_stanza_and_ack_req(StateData, Stanza), - mgmt_queue_add(StateData, Stanza); + NewStateData = case send_stanza_and_ack_req(StateData, Stanza) of + ok -> + StateData; + error -> + StateData#state{mgmt_state = pending} + end, + mgmt_queue_add(NewStateData, Stanza); send_stanza(StateData, Stanza) -> send_element(StateData, Stanza), StateData. @@ -2458,11 +2461,15 @@ fsm_next_state_gc(StateName, PackedStateData) -> %% fsm_next_state: Generate the next_state FSM tuple with different %% 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) -> {next_state, session_established, StateData, ?C2S_HIBERNATE_TIMEOUT}; -fsm_next_state(wait_for_resume, StateData) - when StateData#state.mgmt_state /= pending -> +fsm_next_state(wait_for_resume, #state{mgmt_timeout = 0} = StateData) -> + {stop, normal, StateData}; +fsm_next_state(wait_for_resume, #state{mgmt_pending_since = undefined} = + StateData) -> ?INFO_MSG("Waiting for resumption of stream for ~s", [jlib:jid_to_string(StateData#state.jid)]), {next_state, wait_for_resume, |