<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p>Thanks Daniel, good to hear.</p>
    <p>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>
    </p>
    <p>Cheers!</p>
    <p>Igor<br>
    </p>
    <div class="moz-cite-prefix">On 30/06/2016 07:45, Daniel Goertzen
      wrote:<br>
    </div>
    <blockquote
cite="mid:CAJCf5Rz25ynXUPOsD05FtJC8-6wGxWD8f5=VGmGLpVXNAoTi0Q@mail.gmail.com"
      type="cite">
      <div dir="ltr">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>
        <div class="gmail_quote">
          <div dir="ltr">On Thu, Jun 30, 2016 at 6:02 AM Igor Clark <<a
              moz-do-not-send="true" href="mailto:igor.clark@gmail.com"><a class="moz-txt-link-abbreviated" href="mailto:igor.clark@gmail.com">igor.clark@gmail.com</a></a>>
            wrote:<br>
          </div>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi folks,<br>
            <br>
            I've got a NIF that uses some library code to talk to
            specific 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 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 using<br>
            the enif_*_resource functions, and manage keeping track of
            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 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 asking<br>
            for scheduler headaches/explosions.<br>
            <br>
            I'm planning to try storing the various resources in
            priv_data at 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 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
            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, which<br>
            is the bit I'm worried about.<br>
            <br>
            FWIW the callback code doesn't modify any of the static data
            structures<br>
            directly, it just calls library code which uses the stored
            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 stored<br>
            in priv_data, or is it never OK? What's the best way to do
            this if 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"
              href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
            <a moz-do-not-send="true"
              href="http://erlang.org/mailman/listinfo/erlang-questions"
              rel="noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
          </blockquote>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>