Documentation/code inconsistency for gen_server?

Martin Bjorklund <>
Fri Dec 15 08:32:16 CET 2000


Samuel Tardieu <> wrote:
> I was browsing through gen_server.erl while waiting for the end of an
> endless compilation, and noticed this fragment of code:
> 
> | handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Time) ->
> |     case catch apply(Mod, handle_call, [Msg, From, State]) of
> | [...]
> | 	  {stop, Reason, Reply, NState} ->
> | 	      {'EXIT', R} =
> | 		  (catch terminate(Reason, Name, Msg, Mod, NState, [])),
> | 	      reply(From, Reply),
> | 	      exit(R);
> | [...]
> 
> Also, at another place:
> 
> | handle_common_reply(Reply, Parent, Name, Msg, Mod, State, Debug) ->
> |     case Reply of
> | [...]
> | 	  {stop, Reason, NState} ->
> | 	      terminate(Reason, Name, Msg, Mod, NState, Debug);
> | [...]
> 
> The doc (at least the man page) of gen_server says, concerning terminate:
> 
> | The  termination reason cannot be changed here. The
> | server will terminate due  toReason  regardless  of
> | what was returned from this function.
> 
> Does it mean the code is wrong? This may impact supervised processes, as
> they may exit without an error even if {stop, Reason, State} is returned,
> or with an unrelated error if {stop, Reason, Reply, State} is returned.

No, I don't think the code is wrong.  In both cases, the code calls
gen_server:terminate/6, which always calls exit/1.  In the first case,
this exit is catched, to guarantee that a reply is sent, and then we
exit with the same Reason.

You could possibly argue that the doc is wrong, at leat it does not
give the entire truth - the exit reason _can_ be chaneged, if
Mod:terminate/2 itself calls exit/1.


/martin



More information about the erlang-questions mailing list