[erlang-questions] erlang:send_after/3 questions

freza@REDACTED freza@REDACTED
Sat Sep 22 00:15:10 CEST 2012


Hi,

My understanding, but I'm not ERTS internals expert:

On Sat, Sep 22, 2012 at 12:38:02AM +0400, Dmitry Demeshchuk wrote:
> It's time to reveal some erlang:send_after/3 mysteries I think :)
> 
> 1. When is the message term stored? It's obviously not the callee process,
> and it doesn't seem to be the target process (I don't see a process part
> that could store it). Is it dangerous to pass large messages through it?

It's copied to a heap fragment -- roughly the same kind of C struct is used
as for regular message passing. Except unlike regular message passing the
copying seems to be done in a way that blocks invoking scheduler thread.

So passing large structures this way is probably a bad idea (and, in my
opinion, quite an exotic thing to want to do). But you could always use
term_to_binary/1 first and cheat around this limitation.

> 2. What happens when the target process dies before send_after/3 occurs?
> The returned ref makes me think that we actually spawn some sort of a
> monitor here, and we just stop waiting if the process died by whatever
> reason. Is that correct?

The returned Ref is precisely the same thing as if make_ref/1 were called.
To each successfuly started timer there corresponds a small C structure.

Timers are inserted into a list hanging off receiving process' structure
if Pid is known and alive at the time send_after/3 is called. This list
enables receiving process to release all pending timers on exit. Timers
are additionally inserted into a global table of some sort.

Otherwise, when receiving process is given by name, timer will presumably
happily live in this global table and will be released upon expiry (the
erlang(3) manpage agrees with this speculation). They can't be released
any sooner than that, registered name may refer to different Pids over
time and by passing name instead of a real Pid you're expressing the
wish to deliver to the latest instance possible.

If receiving process is a Pid but dead already when send_after/3 is
called, send_after/3 degenerates into a sligtly slower variant of
make_ref/1. ;-)

> 3. Is spawning a lot of send_after's or timers a dangerous idea? In case of
> using timer module, we'll just lose some started timers due to port
> restart. But something tells me that crash of erlang internal timers is a
> somewhat more dangerous thing that might even crash the VM.

Not sure I understand you here.

These timers are a facility built directly into ERTS. If there were a
bug somewhere in the implementation, that could be as horribly nasty
as any other bug in ERTS. Other than that, they are dead pieces of
data interpreted in some conventional way by a bunch of C code, so
as such they can't really "crash" in any obvious meaning of the
word.

> Any links or facts would be very appreciated.

Just link to the implementation:

  https://github.com/erlang/otp/blob/maint/erts/emulator/beam/erl_bif_timer.c#L495

BR,
	-- Jachym



More information about the erlang-questions mailing list