handle_sync_event/4,
code_change/4,
handle_info/3,
- terminate/3]).
+ terminate/3,
+ print_state/1
+ ]).
-include("ejabberd.hrl").
-include("jlib.hrl").
?ERROR_MSG("Unexpected info: ~p", [Info]),
fsm_next_state(StateName, StateData).
+
+%%----------------------------------------------------------------------
+%% Func: print_state/1
+%% Purpose: Prepare the state to be printed on error log
+%% Returns: State to print
+%%----------------------------------------------------------------------
+print_state(State = #state{pres_t = T, pres_f = F, pres_a = A, pres_i = I}) ->
+ State#state{pres_t = {pres_t, ?SETS:size(T)},
+ pres_f = {pres_f, ?SETS:size(F)},
+ pres_a = {pres_a, ?SETS:size(A)},
+ pres_i = {pres_i, ?SETS:size(I)}
+ }.
+
%%----------------------------------------------------------------------
%% Func: terminate/3
%% Purpose: Shutdown the fsm
%% - You can limit the time processing a message (TODO): If the
%% message processing does not return in a given period of time, the
%% process will be terminated.
-%%
+%% - You might customize the State data before sending it to error_logger
+%% in case of a crash (just export the function print_state/1)
%% $Id$
%%
-module(p1_fsm).
behaviour_info(callbacks) ->
[{init,1},{handle_event,3},{handle_sync_event,4},{handle_info,3},
- {terminate,3},{code_change,4}];
+ {terminate,3},{code_change,4}, {print_state,1}];
behaviour_info(_Other) ->
undefined.
Debug, Limits, Queue1, QueueLen - 1, false);
{empty, _} ->
Reason = internal_queue_error,
- error_info(Reason, Name, hibernate, StateName, StateData, Debug),
+ error_info(Mod, Reason, Name, hibernate, StateName, StateData, Debug),
exit(Reason)
end;
loop(Parent, Name, StateName, StateData, Mod, hibernate, Debug,
terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug) ->
case catch Mod:terminate(Reason, StateName, StateData) of
{'EXIT', R} ->
- error_info(R, Name, Msg, StateName, StateData, Debug),
+ error_info(Mod, R, Name, Msg, StateName, StateData, Debug),
exit(R);
_ ->
case Reason of
[self(), Limit]),
exit(shutdown);
_ ->
- error_info(Reason, Name, Msg, StateName, StateData, Debug),
+ error_info(Mod, Reason, Name, Msg, StateName, StateData, Debug),
exit(Reason)
end
end.
-error_info(Reason, Name, Msg, StateName, StateData, Debug) ->
+error_info(Mod, Reason, Name, Msg, StateName, StateData, Debug) ->
Reason1 =
case Reason of
{undef,[{M,F,A}|MFAs]} ->
_ ->
Reason
end,
+ StateToPrint = case erlang:function_exported(Mod, print_state, 1) of
+ true -> (catch Mod:print_state(StateData));
+ false -> StateData
+ end,
Str = "** State machine ~p terminating \n" ++
get_msg_str(Msg) ++
"** When State == ~p~n"
"** Data == ~p~n"
"** Reason for termination = ~n** ~p~n",
- format(Str, [Name, get_msg(Msg), StateName, StateData, Reason1]),
+ format(Str, [Name, get_msg(Msg), StateName, StateToPrint, Reason1]),
sys:print_log(Debug),
ok.