[erlang-questions] Static callback in NIF
Sverker Eriksson
sverker.eriksson@REDACTED
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 <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
>>
>
>
>
>
> _______________________________________________
> 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/20160701/6e26dde6/attachment.htm>
More information about the erlang-questions
mailing list