[erlang-questions] Calling (equivalent of) erlang:send_after/3 from a NIF?

Roger Lipscombe roger@REDACTED
Mon Oct 29 22:24:49 CET 2018

On 29 October 2018 at 19:38, Nathaniel Waisbrot <nathaniel@REDACTED> wrote:
> Is the idea that your NIF would pause the system for some time and then send
> its message and unpause the system?

I've got a reactor-style thing going on inside my NIF, where I service
a large number of timers and sockets. We're hitting scalability issues
with our current implementation, so I'm evaluating alternatives.

Since this is already in a NIF, I'd like to experiment with replacing
the socket polling with Erlang's enif_select, because I suspect it'll
be more scalable -- I'd like to find out, anyway. The plan is that, on
receiving the message from enif_select, I can quickly dip back into
NIF-land and service the relevant socket.

Some of these sockets are actually libcurl-driven, and one of the
things that libcurl wants is for us to start a timer. I was hoping
that there'd be an equivalent of enif_select, but for timers (i.e.
enif_send_after). We also service a large number of non-curl timers,
and so I was hoping to use Erlang's timer implementation for these as

I found that erlang:send_after calls directly into the send_after_3
BIF, which calls setup_bif_timer, which manages Erlang's timers (it
appears to use a pair of timer wheels for short and medium timeouts,
and a red-black tree for longer timeouts). It'd fit my use-case
perfectly if I could just use that directly from a NIF.

> If you're looking for enif_send_after my first thought would be that you
> should just wrap your NIF in an Erlang process and you NIF tells that
> process how and when to wait.

The timeouts could be as short as 1ms. It'd be way less overhead to
just make use of Erlang's existing timer implementation, rather than
enif_send to a process which would then call erlang:send_after.

More information about the erlang-questions mailing list