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