gen_fsm:send_after | start_timer
Francesco Cesarini
francesco@REDACTED
Mon Jul 9 18:11:03 CEST 2001
Hi Sean,
why don't you use timer:apply_after/4 and create your own timeout events?
%% Called when you set the timer.
timer(Ms) ->
timer:apply_after(Ms, ?MODULE, timeout, [self()]).
%% Call back function
timeout(GenFsg) ->
gen_fsm:send_event(GenFSM, timeout).
Regards,
Francesco
--
http://www.erlang-consulting.com
Sean Hinde wrote:
> Hi,
>
> Anyone else think it would be useful to extend gen_fsm to have it's own
> state aware timer functionality?
>
> At the moment all timers sent with erlang:send_after or erlang:start_timer
> arrive in handle_info rather than in the callback for the current state. I
> find that handle_info becomes very large and unwieldy with more than a
> couple of timers running and 4 or more states..
>
> Usage would be something like:
>
> %%----------------------------------------------------------------------
> %% Func: init/1
> %% Returns: {ok, StateName, StateData} |
> %% {ok, StateName, StateData, Timeout} |
> %% ignore |
> %% {stop, StopReason}
> %%----------------------------------------------------------------------
> init([]) ->
> gen_fsm:start_timer(2000, "Hello from init"),
> {ok, state1, #state{}}.
>
> %%----------------------------------------------------------------------
> %% Func: StateName/2
> %% Returns: {next_state, NextStateName, NextStateData} |
> %% {next_state, NextStateName, NextStateData, Timeout} |
> %% {stop, Reason, NewStateData}
> %%----------------------------------------------------------------------
> state1(Event, StateData) ->
> gen_fsm:start_timer(2000, "Hello from state 1"),
> io:format("SH:~p~n",[Event]),
> {next_state, state2, StateData}.
>
> state2(Event, StateData) ->
> io:format("SH:~p~n",[Event]),
> gen_fsm:send_after(2000, "Hello from state 2"),
> {next_state, state1, StateData}.
>
> Possible implementation follows as a diff -c:
>
> *** /opt/rcs/5.0.2.5/lib/stdlib-1.9.4/src/gen_fsm.erl Thu Jun 7 15:04:40
> 2001
> --- gen_fsm.erl Mon Jul 9 13:14:09 2001
>
> ***************
>
> *** 110,115 ****
>
> --- 110,117 ----
>
> sync_send_all_state_event/2, sync_send_all_state_event/3,
>
> reply/2]).
>
>
>
> + -export([start_timer/2, send_after/2]).
>
> +
>
> %% Internal exports
>
> -export([init_it/6, print_event/3,
>
> system_continue/3,
>
> ***************
>
> *** 199,204 ****
>
> --- 201,217 ----
>
> [Name, Event, Timeout]}})
>
> end.
>
>
>
> + %% Designed to be only callable within one of the callbacks
>
> + %% hence using the self() of this instance of the process.
>
> + %% This is to ensure that timers don't go astray in global
>
> + %% e.g. when straddling a failover, or turn up in a restarted
>
> + %% instance of the process.
>
> + start_timer(Time, Msg) ->
>
> + erlang:start_timer(Time, self(), {'$gen_fsm_timer', Msg}).
>
> +
>
> + send_after(Time, Msg) ->
>
> + erlang:send_after(Time, self(), {'$gen_fsm_timer', Msg}).
>
> +
>
> %%% ---------------------------------------------------
>
> %%% Initiate the new process.
>
> %%% Register the name using the Rfunc function
>
> ***************
>
> *** 288,293 ****
>
> --- 301,314 ----
>
> io:format(Dev,
>
> "*DBG* ~p got all_state_event ~p in state ~w~n",
>
> [Name, Event, StateName]);
>
> + {'$gen_fsm_timer', Msg} ->
>
> + io:format(Dev,
>
> + "*DBG* ~p got timer ~p in state ~w~n",
>
> + [Name, Msg, StateName]);
>
> + {timeout, Ref, {'$gen_fsm_timer', Msg}} ->
>
> + io:format(Dev,
>
> + "*DBG* ~p got timer ~p in state ~w~n",
>
> + [Name, {timeout, Ref, Msg}, StateName]);
>
> _ ->
>
> io:format(Dev, "*DBG* ~p got ~p in state ~w~n",
>
> [Name, Msg, StateName])
>
> ***************
>
> *** 367,372 ****
>
> --- 388,397 ----
>
> dispatch({'$gen_sync_all_state_event', From, Event},
>
> Mod, StateName, StateData) ->
>
> apply(Mod, handle_sync_event, [Event, From, StateName, StateData]);
>
> + dispatch({'$gen_fsm_timer', Msg}, Mod, StateName, StateData) ->
>
> + apply(Mod, StateName, [Msg, StateData]);
>
> + dispatch({timeout, Ref, {'$gen_fsm_timer', Msg}}, Mod, StateName,
> StateData) -
> >
>
> + apply(Mod, StateName, [{timeout, Ref, Msg}, StateData]);
>
> dispatch(Info, Mod, StateName, StateData) ->
>
> apply(Mod, handle_info, [Info, StateName, StateData]).
>
>
>
> ***************
>
> *** 423,428 ****
>
> --- 448,457 ----
>
> "** Last event in was ~p (for all states)~n";
>
> get_msg_str({'$gen_sync_all_state_event', Event}) ->
>
> "** Last sync event in was ~p (for all states)~n";
>
> + get_msg_str({'$gen_fsm_timer', Msg}) ->
>
> + "** Last timer event in was ~p~n";
>
> + get_msg_str({timeout, Ref, {'$gen_fsm_timer', Msg}}) ->
>
> + "** Last timer event in was ~p~n";
>
> get_msg_str(Msg) ->
>
> "** Last message in was ~p~n".
>
>
>
> ***************
>
> *** 430,435 ****
>
> --- 459,466 ----
>
> get_msg({'$gen_sync_event', Event}) -> Event;
>
> get_msg({'$gen_all_state_event', Event}) -> Event;
>
> get_msg({'$gen_sync_all_state_event', Event}) -> Event;
>
> + get_msg({'$gen_fsm_timer', Msg}) -> Msg;
>
> + get_msg({timeout, Ref, {'$gen_fsm_timer', Msg}}) -> {timeout, Ref, Msg};
>
> get_msg(Msg) -> Msg.
>
>
>
> %%-----------------------------------------------------------------
>
>
>
> - Sean
>
> NOTICE AND DISCLAIMER:
> This email (including attachments) is confidential. If you have received
> this email in error please notify the sender immediately and delete this
> email from your system without copying or disseminating it or placing any
> reliance upon its contents. We cannot accept liability for any breaches of
> confidence arising through use of email. Any opinions expressed in this
> email (including attachments) are those of the author and do not necessarily
> reflect our opinions. We will not accept responsibility for any commitments
> made by our employees outside the scope of our business. We do not warrant
> the accuracy or completeness of such information.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: francesco.vcf
Type: text/x-vcard
Size: 352 bytes
Desc: Card for Francesco Cesarini
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20010709/1464ff12/attachment.vcf>
More information about the erlang-questions
mailing list