[erlang-questions] question on 'EXIT' messages delivered to exit-trapping gen_servers

0 views
Skip to first unread message

Adam Kocoloski

unread,
Apr 2, 2009, 7:06:58 PM4/2/09
to erlang-q...@erlang.org
Hi Erlangers, I've been doing a little hacking on CouchDB and running
into some behavior that I don't understand. We have a standalone
gen_server (let's call it A) that traps exits and was started by
another gen_server (B) using start_link. B does not trap exits, and
is linked to some other process C. Now we have the following sequence
of events:

* exit(C, kill)
* B exits immediately with Reason killed
* A calls terminate with Reason killed

That last line surprised me. I was expecting to receive {'EXIT', B,
killed} in A's mailbox, and in fact I had written a handle_info to
process all 'EXIT' messages, but none arrived. I checked that
trap_exit is still true in A's terminate. {trap_exit, true} clearly
has some effect, as without it terminate isn't even called.

I tried changing the exit signal to some other atom, but I still get
the same basic results (just with goodbye_cruel_world instead of kill/
killed in the Reasons). I'm stumped. Regards, Adam
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions

Chandru

unread,
Apr 2, 2009, 7:29:22 PM4/2/09
to Adam Kocoloski, erlang-q...@erlang.org
Hi Adam,

It looks like if a gen_server process was spawned using proc_lib:spawn and an EXIT signal is received indicating that the Parent process has died, the terminate() function is called!

The documentation should probably clarify this.

Here is the extract from gen_server.erl in R11B-5

loop(Parent, Name, State, Mod, Time, Debug) ->
    Msg = receive
          Input ->
            Input
      after Time ->
          timeout
      end,
    case Msg of
    {system, From, Req} ->
        sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
                  [Name, State, Mod, Time]);
    {'EXIT', Parent, Reason} ->
        terminate(Reason, Name, Msg, Mod, State, Debug);
    _Msg when Debug =:= [] ->
        handle_msg(Msg, Parent, Name, State, Mod, Time);
    _Msg ->
        Debug1 = sys:handle_debug(Debug, {?MODULE, print_event},
                      Name, {in, Msg}),
        handle_msg(Msg, Parent, Name, State, Mod, Time, Debug1)
    end.

cheers
Chandru


2009/4/3 Adam Kocoloski <adam.ko...@gmail.com>

Adam Kocoloski

unread,
Apr 2, 2009, 10:07:36 PM4/2/09
to Chandru, erlang-q...@erlang.org
Aha, glad to know I wasn't going crazy. Thanks Chandru!

Adam

Reply all
Reply to author
Forward
0 new messages