[erlang-questions] Static callback in NIF

Sverker Eriksson <>
Fri Jul 1 17:18:37 CEST 2016


The only legit way to create an ErlNifEnv is to call enif_alloc_env().

I bet the compiler warned about your static ErlNifEnv
just before you went hunting for erts internal header files :-)

In OTP-19.0 the 'msg_env' argument to enif_send() can be NULL
in which case the message will be copied and you can reuse
the environment for the next message with enif_clear_env().
This is effective if the message is small.

/Sverker, Erlang/OTP


On 06/30/2016 08:31 PM, Igor Clark wrote:
> Thanks Daniel, good to hear.
>
> Thanks also Roger & Sergej for your replies. I'll try out 
> enif_alloc_env()'ing a new ErlNifEnv each time the callback uses 
> enif_send(), rather than just leaving it static.
>
> Cheers!
>
> Igor
>
> On 30/06/2016 07:45, Daniel Goertzen wrote:
>> Static vs priv_data are functionally the same here so it doesn't 
>> matter which way you go.  I can empathize with your sense of dread; 
>> there are a lot of rules to keep track of for keeping Undefined 
>> Behavior at bay.  But you seem to have a good handle on things.
>>
>> On Thu, Jun 30, 2016 at 6:02 AM Igor Clark < 
>> <mailto:>> wrote:
>>
>>     Hi folks,
>>
>>     I've got a NIF that uses some library code to talk to specific
>>     hardware.
>>     It's a hobby project with only one user (me) and no real performance
>>     concerns, so what I've got works well at the moment, but I think I'm
>>     doing some sneaky/dirty stuff and would like to know the best way
>>     to do
>>     what I need.
>>
>>     Sending messages outwards from erlang->C->HW is easy, very quick, 
>> and
>>     works fine. I return a pointer to the HW reference back to erlang
>>     using
>>     the enif_*_resource functions, and manage keeping track of
>>     everything on
>>     the erlang side, which feels pretty natural.
>>
>>     Coming the other way works fine too, but relies on a C function
>>     callback
>>     which gets called when the hardware has a message for me. Right 
>> now I
>>     just have a static function in the NIF C code which I pass to the
>>     library. I create a static ErlNifEnv on NIF load() which I keep 
>> around
>>     and use in the callback to send messages to a specified erlang Pid,
>>     passed in via enif_get_local_pid() in another NIF function and also
>>     stored statically. This works a treat, but I'm feeling some pretty
>>     strong dread that it's very much the wrong way to do things, and
>>     asking
>>     for scheduler headaches/explosions.
>>
>>     I'm planning to try storing the various resources in priv_data at
>>     load()
>>     time, on the theory that that way the memory would at least be 
>> managed
>>     by the NIF system rather than just as enif_alloc()'ing static
>>     pointers,
>>     but I'm not sure if that would make any diffrence if code 
>> external to
>>     the scheduler calls back into it.
>>
>>     I've looked into running this part as a C node or a port that sends
>>     messages with the HW data in a callback in its own process, and the
>>     communication seems straightforward enough, but it also seems like I
>>     immediately need to start designing mechanisms to deal with
>>     working out
>>     where to send received messages, almost a protocol in itself. 
>> Whereas
>>     with the NIF+callback method I have a lot of the work done for me -
>>     except, of course, for the synchronisation and memory management,
>>     which
>>     is the bit I'm worried about.
>>
>>     FWIW the callback code doesn't modify any of the static data
>>     structures
>>     directly, it just calls library code which uses the stored
>>     references to
>>     work out which hardware device & channel to send the message to.
>>
>>     What's the best practice here? Is a callback in a NIF OK if it's
>>     stored
>>     in priv_data, or is it never OK? What's the best way to do this if
>>     not?
>>
>>     Would appreciate any tips!
>>
>>     Cheers,
>>     Igor
>>     _______________________________________________
>>     erlang-questions mailing list
>>      <mailto:>
>>     http://erlang.org/mailman/listinfo/erlang-questions
>>
>
>
>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20160701/6e26dde6/attachment.html>


More information about the erlang-questions mailing list