<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Mon, May 2, 2016 at 4:24 PM 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">
A resource will be deallocated when<br>
<br>
* all terms created with enif_make_resource() have been garbage
collected<br>
<br>
* AND the call to enif_alloc_resource() has been balanced by a call
to enif_release_resource()<br>
<br>
* AND all calls to enif_keep_resource() have been balanced by an
equal number of calls to enif_release_resource()</div><div bgcolor="#FFFFFF" text="#000000"><br>
<br>
<br>
<div>On 05/02/2016 11:47 AM, Benoit Chesneau
wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">I had a look in the doc but I can't figure exactly
how much a nif resource could live outside the process that
created it, ie. how others processes can write/read to it and
how to make sure the resource will be accessible to them.
<div><br>
</div>
<div>So I created a nif resource that have the following
properties:</div>
<div><span style="line-height:1.5">- it is ref counted, each
time a call is made to it, the counter is incremented and
decremented when it return.</span><br>
</div>
</div>
</blockquote></div><div bgcolor="#FFFFFF" text="#000000">
A resource already has an internal ref counter, which is decremented
by the GC and by enif_release_resource().<br>
<br>
Adding your own ref counter is probably either redundant or just
plain wrong.<br>
Every call to enif_release_resource() must be balanced by a prior
call<br>
to either enif_alloc_resource() or enif_keep_resource(). You cannot<br>
release a resource that is still referred to by one of more terms.</div><div bgcolor="#FFFFFF" text="#000000"><br></div></blockquote><div><br></div><div>The ref counter is here mainly to makes sure that parent resources knows everything has been cleaned since it's it's needed in the other API.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div bgcolor="#FFFFFF" text="#000000">
<br>
<blockquote type="cite">
<div dir="ltr">
<div>- the process that create it will live until the vm is
closed</div>
</div>
</blockquote></div><div bgcolor="#FFFFFF" text="#000000">
A resource it not tied to the process that created it,<br>
it is tied to the terms that refer it.</div></blockquote><div><br></div><div>Oh perfect then. </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div bgcolor="#FFFFFF" text="#000000">
<br>
<blockquote type="cite">
<div dir="ltr">
<div>- write and reads to the resource are thread safe, at least
the functions that use resource</div>
<div><br>
</div>
</div>
</blockquote></div><div bgcolor="#FFFFFF" text="#000000">
Maintaining the thread safety of the *content* of a resource<br>
is no different than the thread safety of any shared data in any
multi threaded program.</div></blockquote><div><br></div><div>Well of course. But Isn't there some cases where the VM fork a process instead of using threads on some systems? I thought it did that on openbsd for example.</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div bgcolor="#FFFFFF" text="#000000"><br>
<br>
<blockquote type="cite">
<div dir="ltr">
<div>For now I was thinking to share this resources between
others processes via an ETS table. But I am wondering if
instead it shouldn't be safer to makes all the call via a nif.
With the result of creating some kind of bottleneck. </div>
</div>
</blockquote></div><div bgcolor="#FFFFFF" text="#000000">
It's totally fine to share resources via local ETS tables.<br>
The resource does not care where the terms that are keeping it alive
are residing.<br>
<br>
The only thing that does not work is sending a resource term<br>
to another node or do term_to_binary/binary_to_term.<br>
<br>
<br>
The bottom line is:<br>
If enif_get_resource() succeeds, then you will obtain<br>
a pointer to a resource that is guaranteed to be alive<br>
until the ErlNifEnv of the term is invalidated.<br>
<br>
<br>
<br>
/Sverker, Erlang/OTP<br>
<br>
<br></div></blockquote><div><br></div><div>Thanks for the detailed answer. It's useful :)</div><div><br></div><div>- benoît </div></div></div>