[erlang-questions] From whence do monitors come?

8 views
Skip to first unread message

Matthew Sackman

unread,
Sep 10, 2010, 9:07:58 AM9/10/10
to erlang-q...@erlang.org
gen.erl has the following code in do_call:

catch erlang:send(Process, {Label, {self(), Mref}, Request},
[noconnect]),
receive
{Mref, Reply} ->
erlang:demonitor(Mref, [flush]),
{ok, Reply};
{'DOWN', Mref, _, _, noconnection} ->
exit({nodedown, Node});
{'DOWN', Mref, _, _, Reason} ->
exit(Reason)

If the callee is something like a gen_server, and on handling that msg
returns a {stop, Reply, Reason, State} quple, there seems to be a race
between the reply and the monitor. Or more simply, say the callee does
something like:

receive {'$gen_call', From, _Msg} -> gen_server:reply(From, done) end.

There seems to be a race - what's stopping the DOWN from the monitor
overtaking the reply from the callee?

The only thing that I can think of is that the DOWN is considered to
come *from* the callee. Is that right?

Matthew

________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questio...@erlang.org

Ulf Wiger

unread,
Sep 10, 2010, 9:21:02 AM9/10/10
to erlang-q...@erlang.org
On 09/10/2010 03:07 PM, Matthew Sackman wrote:
> gen.erl has the following code in do_call:
>
> catch erlang:send(Process, {Label, {self(), Mref}, Request},
> [noconnect]),
> receive
> {Mref, Reply} ->
> erlang:demonitor(Mref, [flush]),
> {ok, Reply};
> {'DOWN', Mref, _, _, noconnection} ->
> exit({nodedown, Node});
> {'DOWN', Mref, _, _, Reason} ->
> exit(Reason)
>
> If the callee is something like a gen_server, and on handling that msg
> returns a {stop, Reply, Reason, State} quple, there seems to be a race
> between the reply and the monitor. Or more simply, say the callee does
> something like:
>
> receive {'$gen_call', From, _Msg} -> gen_server:reply(From, done) end.
>
> There seems to be a race - what's stopping the DOWN from the monitor
> overtaking the reply from the callee?
>
> The only thing that I can think of is that the DOWN is considered to
> come *from* the callee. Is that right?

This is the only conclusion that would be compatible with the ordering
guarantee, IMHO. The gen_server explicitly sends the reply before it
dies, and it would be almost impossible to write an efficient and
safe implementation of do_call if one couldn't be sure that the DOWN
message will never be delivered before the last message sent to the
same recipient.

The ordering guarantee should be clearly documented in the reference
manual, together with a clear statement on how EXIT signals and
DOWN messages play along with that guarantee.

BR,
Ulf W

Robert Virding

unread,
Sep 11, 2010, 10:41:49 AM9/11/10
to Ulf Wiger, erlang-q...@erlang.org
It's the [flush] option to demonitor which saves you here. Apart from
removing the monitor it automatically removes any monitor message form
that process in the process mailbox. And yes the {'DOWN',...} message
does work as a normal message.

Robert

Matthew Sackman

unread,
Sep 11, 2010, 10:53:18 AM9/11/10
to Robert Virding, Ulf Wiger, erlang-q...@erlang.org
On Sat, Sep 11, 2010 at 04:41:49PM +0200, Robert Virding wrote:
> It's the [flush] option to demonitor which saves you here. Apart from
> removing the monitor it automatically removes any monitor message form
> that process in the process mailbox.

No, you've misunderstood the problem. The problem is that unless the
DOWN message is considered to come *from* the terminating process, there
is no guarantee of the order in which the reply and the DOWN message
will arrive. The problematic case being the potential for the DOWN to
arrive before the reply.

> And yes the {'DOWN',...} message
> does work as a normal message.

Does that also hold for exit signals which are being sent to processes
that have trap_exit on?

Matthew

Reply all
Reply to author
Forward
0 new messages