[erlang-questions] Static callback in NIF

Daniel Goertzen daniel.goertzen@REDACTED
Mon Jul 4 03:51:44 CEST 2016


Off topic: the docs say to set env to null (not msg_env) when calling
enif_send() from a thread.  What is the consequence of setting it null in a
NIF call?

I'm writing Rust wrappers, and I can't think of a compile time or runtime
check for when env needs to be null.  I've been able to protect basically
everything else in the NIF API, but not that.



On Fri, Jul 1, 2016 at 10:18 AM Sverker Eriksson <
sverker.eriksson@REDACTED> wrote:

> 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 <igor.clark@REDACTED
> <mailto:igor.clark@REDACTED> <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>
> <erlang-questions@REDACTED>
>     http://erlang.org/mailman/listinfo/erlang-questions
>
>
>
>
>
> _______________________________________________
> erlang-questions mailing listerlang-questions@REDACTED://erlang.org/mailman/listinfo/erlang-questions
>
> _______________________________________________
> erlang-questions mailing list
> 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/20160704/b4471a64/attachment.htm>


More information about the erlang-questions mailing list