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

      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

    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:

   -export([init/1, handle_call/3, terminate/2]).
   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

   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.


More information about the erlang-questions mailing list