<div dir="ltr">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?<div><br></div><div>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.</div><div><br></div><div><br><br><div class="gmail_quote"><div dir="ltr">On Fri, Jul 1, 2016 at 10:18 AM Sverker Eriksson <<a href="mailto:sverker.eriksson@ericsson.com">sverker.eriksson@ericsson.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF" text="#000000">
    The only legit way to create an ErlNifEnv is to call
    enif_alloc_env().<br>
    <br>
    I bet the compiler warned about your static ErlNifEnv<br>
    just before you went hunting for erts internal header files :-)<br>
    <br>
    In OTP-19.0 the 'msg_env' argument to enif_send() can be NULL<br>
    in which case the message will be copied and you can reuse<br>
    the environment for the next message with enif_clear_env().<br>
    This is effective if the message is small.<br>
    <br>
    /Sverker, Erlang/OTP</div><div bgcolor="#FFFFFF" text="#000000"><br>
    <br>
    <br>
    <div>On 06/30/2016 08:31 PM, Igor Clark
      wrote:<br>
    </div>
    </div><div bgcolor="#FFFFFF" text="#000000"><blockquote type="cite">Thanks Daniel, good to hear.
      <br>
      <br>
      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.
      <br>
      <br>
      Cheers!
      <br>
      <br>
      Igor
      <br>
      <br>
      On 30/06/2016 07:45, Daniel Goertzen wrote:
      <br>
      </blockquote></div><div bgcolor="#FFFFFF" text="#000000"><blockquote type="cite"><blockquote type="cite">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.
        <br>
        <br></blockquote></blockquote></div><div bgcolor="#FFFFFF" text="#000000"><blockquote type="cite"><blockquote type="cite">
        On Thu, Jun 30, 2016 at 6:02 AM Igor Clark
        <<a href="mailto:igor.clark@gmail.com" target="_blank">igor.clark@gmail.com</a> <a href="mailto:igor.clark@gmail.com" target="_blank"><mailto:igor.clark@gmail.com></a>>
        wrote:
        <br>
        <br>
        Â Â Â  Hi folks,
        <br>
        <br>
        Â Â Â  I've got a NIF that uses some library code to talk to
        specific
        <br>
        Â Â Â  hardware.
        <br>
        Â Â Â  It's a hobby project with only one user (me) and no real
        performance
        <br>
        Â Â Â  concerns, so what I've got works well at the moment, but I
        think I'm
        <br>
        Â Â Â  doing some sneaky/dirty stuff and would like to know the
        best way
        <br>
        Â Â Â  to do
        <br>
        Â Â Â  what I need.
        <br>
        <br>
        Â Â Â  Sending messages outwards from erlang->C->HW is easy,
        very quick, and
        <br>
        Â Â Â  works fine. I return a pointer to the HW reference back to
        erlang
        <br>
        Â Â Â  using
        <br>
        Â Â Â  the enif_*_resource functions, and manage keeping track of
        <br>
        Â Â Â  everything on
        <br>
        Â Â Â  the erlang side, which feels pretty natural.
        <br>
        <br>
        Â Â Â  Coming the other way works fine too, but relies on a C
        function
        <br>
        Â Â Â  callback
        <br>
        Â Â Â  which gets called when the hardware has a message for me.
        Right now I
        <br>
        Â Â Â  just have a static function in the NIF C code which I pass
        to the
        <br>
        Â Â Â  library. I create a static ErlNifEnv on NIF load() which I
        keep around
        <br>
        Â Â Â  and use in the callback to send messages to a specified
        erlang Pid,
        <br>
        Â Â Â  passed in via enif_get_local_pid() in another NIF function
        and also
        <br>
        Â Â Â  stored statically. This works a treat, but I'm feeling some
        pretty
        <br>
        Â Â Â  strong dread that it's very much the wrong way to do things,
        and
        <br>
        Â Â Â  asking
        <br>
        Â Â Â  for scheduler headaches/explosions.
        <br>
        <br>
        Â Â Â  I'm planning to try storing the various resources in
        priv_data at
        <br>
        Â Â Â  load()
        <br>
        Â Â Â  time, on the theory that that way the memory would at least
        be managed
        <br>
        Â Â Â  by the NIF system rather than just as enif_alloc()'ing
        static
        <br>
        Â Â Â  pointers,
        <br>
        Â Â Â  but I'm not sure if that would make any diffrence if code
        external to
        <br>
        Â Â Â  the scheduler calls back into it.
        <br>
        <br>
        Â Â Â  I've looked into running this part as a C node or a port
        that sends
        <br>
        Â Â Â  messages with the HW data in a callback in its own process,
        and the
        <br>
        Â Â Â  communication seems straightforward enough, but it also
        seems like I
        <br>
        Â Â Â  immediately need to start designing mechanisms to deal with
        <br>
        Â Â Â  working out
        <br>
        Â Â Â  where to send received messages, almost a protocol in
        itself. Whereas
        <br>
        Â Â Â  with the NIF+callback method I have a lot of the work done
        for me -
        <br>
        Â Â Â  except, of course, for the synchronisation and memory
        management,
        <br>
        Â Â Â  which
        <br>
        Â Â Â  is the bit I'm worried about.
        <br>
        <br>
        Â Â Â  FWIW the callback code doesn't modify any of the static data
        <br>
        Â Â Â  structures
        <br>
        Â Â Â  directly, it just calls library code which uses the stored
        <br>
        Â Â Â  references to
        <br>
        Â Â Â  work out which hardware device & channel to send the
        message to.
        <br>
        <br>
        Â Â Â  What's the best practice here? Is a callback in a NIF OK if
        it's
        <br>
        Â Â Â  stored
        <br>
        Â Â Â  in priv_data, or is it never OK? What's the best way to do
        this if
        <br>
        Â Â Â  not?
        <br>
        <br>
        Â Â Â  Would appreciate any tips!
        <br>
        <br>
        Â Â Â  Cheers,
        <br>
        Â Â Â  Igor
        <br>
        Â Â Â  _______________________________________________
        <br>
        Â Â Â  erlang-questions mailing list
        <br></blockquote></blockquote></div><div bgcolor="#FFFFFF" text="#000000"><blockquote type="cite"><blockquote type="cite">
        Â Â Â  <a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a>
        <a href="mailto:erlang-questions@erlang.org" target="_blank"><mailto:erlang-questions@erlang.org></a>
        <br>
        Â Â Â  <a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a>
        <br>
        <br>
      </blockquote></blockquote></div><div bgcolor="#FFFFFF" text="#000000"><blockquote type="cite">
      <br>
      <br>
      <br>
      <fieldset></fieldset>
      <br>
      <pre>_______________________________________________
erlang-questions mailing list
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a>
</pre>
    </blockquote></div>

_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
</blockquote></div></div></div>