[erlang-questions] Static callback in NIF

Igor Clark igor.clark@REDACTED
Thu Jun 30 20:31:50 CEST 2016

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.



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 <igor.clark@REDACTED 
> <mailto:igor.clark@REDACTED>> 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
>     erlang-questions@REDACTED <mailto:erlang-questions@REDACTED>
>     http://erlang.org/mailman/listinfo/erlang-questions

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20160630/f98108d1/attachment.htm>

More information about the erlang-questions mailing list