<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p>Hi Sverker, thanks.</p>
    <p>I'm only using enif_alloc_env() to create the static ErlNifEnv,
      in the NIF load(). I haven't had compiler warnings about it -
      certainly haven't noticed any, and just did a clean+build to
      check.<br>
    </p>
    <p>(I'm using the rebar3 port compiler on erlang 18.3, erts-7.3 on
      OSX 10.11.5. It doesn't seem to show warnings without errors, and
      I can't find a verbose mode - so I used 'rebar comp --verbose' to
      inspect 'cc' lines and warnings, and there's nothing there about
      the static ErlNifEnv, either.)</p>
    <p>I haven't been doing any digging in erts headers, as I'd be
      pretty nervous about doing anything undocumented :-)</p>
    <p>Am I missing something?</p>
    <p>Cheers,</p>
    <p>Igor<br>
    </p>
    <div class="moz-cite-prefix"><br>
      On 01/07/2016 08:18, Sverker Eriksson wrote:<br>
    </div>
    <blockquote cite="mid:577689CD.6090201@ericsson.com" type="cite">
      <meta content="text/html; charset=windows-1252"
        http-equiv="Content-Type">
      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<br>
      <br>
      <br>
      <div class="moz-cite-prefix">On 06/30/2016 08:31 PM, Igor Clark
        wrote:<br>
      </div>
      <blockquote
        cite="mid:508348d9-30ee-c5ce-cc80-a4ce5d530759@gmail.com"
        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 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>
          On Thu, Jun 30, 2016 at 6:02 AM Igor Clark <<a
            moz-do-not-send="true" class="moz-txt-link-abbreviated"
            href="mailto:igor.clark@gmail.com"><a class="moz-txt-link-abbreviated" href="mailto:igor.clark@gmail.com">igor.clark@gmail.com</a></a>
          <a moz-do-not-send="true" class="moz-txt-link-rfc2396E"
            href="mailto:igor.clark@gmail.com"><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>
              <a moz-do-not-send="true"
            class="moz-txt-link-abbreviated"
            href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>
          <a moz-do-not-send="true" class="moz-txt-link-rfc2396E"
            href="mailto:erlang-questions@erlang.org"><mailto:erlang-questions@erlang.org></a>
          <br>
              <a moz-do-not-send="true" class="moz-txt-link-freetext"
            href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a>
          <br>
          <br>
        </blockquote>
        <br>
        <br>
        <br>
        <fieldset class="mimeAttachmentHeader"></fieldset>
        <br>
        <pre wrap="">_______________________________________________
erlang-questions mailing list
<a moz-do-not-send="true" class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a>
</pre>
      </blockquote>
      <br>
    </blockquote>
    <br>
  </body>
</html>