gen_server/gen_fsm trap exit signals?
Vance Shipley
vances@REDACTED
Fri Dec 19 23:28:07 CET 2003
I have discovered the following descrepancy between observed
and documented behaviour in gen_server and gen_fsm.
The documentation for both gen_server and gen_fsm states:
"Note that a gen_fsm does not trap exit signals automatically,
this must be explicitly initiated in the callback module."
Later in describing the terminate callback it states:
"If the gen_server is part of a supervision tree and is
ordered by its supervisor to terminate, this function will
be called with Reason=shutdown if the following conditions
apply:
o the gen_server has been set to trap exit signals, and
o the shutdown strategy as defined in the supervisor's
child specification is an integer timeout value, not
brutal_kill.
Otherwise, the gen_server will be immediately terminated."
So what I have always assumed is that it was neccesary to use
the following init/1 callback:
init(Arg) ->
...
%% trap exit signals
process_flag(trap_exit, true),
...
{ok, State}.
However that doesn't prove to be neccessary in R9C.
Consider the following gen_server module:
-module(server).
-export([init/1, handle_call/3, terminate/2]).
-behaviour(gen_server).
init(_) ->
{ok, []}.
handle_call(assert, _From, State) ->
a = b,
{reply, not_reached, State};
handle_call({stop, Reason}, _From, State) ->
{stop, Reason, State};
terminate(Reason, State) ->
io:fwrite("Called terminate(~w, ~w)~n",
[Reason, State]).
This is what results when it's run:
1> gen_server:call(S, {stop, normal}).
Called terminate(normal, [])
** exited: {normal,{gen_server,call,[<0.39.0>,{stop,normal}]}} **
The handle_call/3 function clause returns {stop, normal, State} so
the gen_fsm calls terminate to do an orderly shutdown.
3> gen_server:call(S, assert).
Called terminate({{badmatch,b},[{server,handle_call,3},{proc_lib,init_p,5}]}, [])
=ERROR REPORT==== 19-Dec-2003::17:03:42 ===
** Generic server <0.56.0> terminating
** Last message in was assert
** When Server state == []
** Reason for termination ==
** {{badmatch,b},[{server,handle_call,3},{proc_lib,init_p,5}]}
** exited: {{badmatch,b},[{server,handle_call,3},{proc_lib,init_p,5}]} **
I did not expect this to call terminate as it is not trapping exit
signals. It doesn't appear to matter whether or not
process_flag(trap_exit, true is called at all. It behaves the same
each way. Adding the following test shows that the current value is
false:
init(_) ->
OldValue = process_flag(trap_exit, true),
io:format("Old value of trap_exit flag was ~w.~n"),
{ok, []}.
1> gen_fsm:start_link(fsm, [], []).
Old value of trap_exit flag was false.
So while I'm content with the staus quo it does seem that the documentation
could have these statements removed as they no longer seem to apply.
-Vance
More information about the erlang-questions
mailing list