Mon Oct 31 15:18:47 CET 2005
Aaah, well, yes.. This is an old flaw.
Once upon a time there were only links to supervise other
processes, so the only way to know if a server died during
a library call e.g inside gen_server:call after sending
the request while receiving the response, was that an
'EXIT' message was received instead; and then the library
code for gen_server:call would have to trap exit messages
and set a link to the server.
But that can not be done by library code, since there can
be only one link between any pair of processes. Possibly
exit message trapping could be done, but there is a time
window after receive before disabling exit message trapping
that can not be controlled, so the library code can not
be sure to not accidentally convert a link exit to an
So, it was then designed so that _if_ the calling process
had activated exit message trapping _and_ set a link to the
server, then the gen_server:call could receive the 'EXIT'
message and return an error code as a result of the server call.
Later, when monitors was introduced we could not change
the behaviour of gen_server:call to not consume 'EXIT'
messages at all (which would be the right(TM) way, in
the precence of monitors); the result would be passing
undesired 'EXIT' messages onto old calling applications.
So, there we are today. The calling process should check
the result from gen_server:call plus receive 'EXIT' messages.
Or set a monitor of its own.
(Sean Hinde) writes:
> This behaviour seems broken to me:
> 1. One process is linked to another (for supervision reasons), and a
> gen_*:call/2 synchronous request is made from one to the other.
> 2. The called process crashes while handling the call.
> 3. gen:call consumes *both* it's own monitor 'DOWN' message *and* the
> 'EXIT' message arising from the link
> Result: calling process doesn't get 'EXIT' message, and hence doesn't
> know about the crash. It does not then function well as a supervisor...
/ Raimo Niskanen, Erlang/OTP, Ericsson AB
More information about the erlang-questions