[erlang-questions] erlang nif resource & thread safety

Sverker Eriksson sverker.eriksson@REDACTED
Mon May 2 16:24:04 CEST 2016


A resource will be deallocated when

* all terms created with enif_make_resource() have been garbage collected

* AND the call to enif_alloc_resource() has been balanced by a call to 
enif_release_resource()

* AND all calls to enif_keep_resource() have been balanced by an equal 
number of calls to enif_release_resource()


On 05/02/2016 11:47 AM, Benoit Chesneau wrote:
> 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.
>
> So I created a nif resource that have the following properties:
> - it  is ref counted, each time a call is made to it, the counter is 
> incremented and decremented when it return.
A resource already has an internal ref counter, which is decremented by 
the GC and by enif_release_resource().

Adding your own ref counter is probably either redundant or just plain 
wrong.
Every call to enif_release_resource() must be balanced by a prior call
to either enif_alloc_resource() or enif_keep_resource(). You cannot
release a resource that is still referred to by one of more terms.

> - the process that create it will live until the vm is closed
A resource it not tied to the process that created it,
it is tied to the terms that refer it.

> - write and reads to the resource are thread safe, at least the 
> functions that use resource
>
Maintaining the thread safety of the *content* of a resource
is no different than the thread safety of any shared data in any multi 
threaded program.

> 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.
It's totally fine to share resources via local ETS tables.
The resource does not care where the terms that are keeping it alive are 
residing.

The only thing that does not work is sending a resource term
to another node or do term_to_binary/binary_to_term.


The bottom line is:
If enif_get_resource() succeeds, then you will obtain
a pointer to a resource that is guaranteed to be alive
until the ErlNifEnv of the term is invalidated.



/Sverker, Erlang/OTP



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20160502/5e0a749c/attachment.htm>


More information about the erlang-questions mailing list