[erlang-questions] erl_nif: questions regarding resource handling

Sverker Eriksson sverker@REDACTED
Thu Nov 17 12:18:35 CET 2011

Michael Uvarov wrote:
>> Ideally, I would want to return the same reference when two calls to "add"
>> use the same term parameter.
>> However, it is not clear to me how to do that using the erl_nif
>> primitives, AND supporting garbage collection.
>> It is not trivial, non-trivial things cause errors.
If I understand you correctly you want the garbage collector to control 
the lifetime of the
resources, but you also want to find them (as long as they are alive) 
via your own
data structures (tables).

This is possible to do as long as
1. The destructor really finds and invalidates all of your own "hidden" 
pointers to the resource.
2. You supply your own synchronization for code that access your shared 
data structure (including the destructor).

>> - Is it allowed to call enif_make_copy with a term containing a
>> "non-controlled" resource "pointer" as an argument?
It's ok as long as the term passed to enif_make_copy() belongs to a 
valid environment.
Resource terms does not make any difference here.

>> - Does enif_make_copy increase the reference count for resources embedded
>> in the argument?
Yes. Keeping a copy of a resource term in an environment  from 
enif_alloc_env() is
another way of retaining a resource object. The resource can not be 
destructed until
you do enif_free_env() or enif_clear_env().

>> - Concretely, should one always change the environment (i.e., call
>> enif_make_copy) of a resource when embedding them in an environment
>> different from the environment used as an argument when creating the
>> ErlNifResourceType to which the resource belongs?
A resource TYPE is not bound to any environment in any way. The only 
reason to call
enif_make_copy() is to make a copy of the term with a lifetime that either
(1) you have control over or (2) the calling Erlang process has control 

>> - Better ways of handling the above table problem? (I could create a new
>> resource for each call, and never reuse them to enable gc, is there a large
>> memory/speed penalty associated with creating resources?)
Creating resources is not that expensive. Do some measures.

The current implementation of environments from enif_make_env() has a 
quite large constant
memory overhead. A lot of environments with small/few terms in them will 
not be
memory efficient.

>> - By the way, should destructors functions be thread-safe, or are they
>> called in isolation?
Yes they should. However, in the normal "vanilla" case the destructor 
has the very last
reference to the resource. You then don't need any synchronization 
because there
can not exist any other threads to synchronize with.

In your case there may be concurrent threads accessing the dying 
resource through
shared data structures. Synchronize!

/Sverker, Erlang/OTP, Ericsson

More information about the erlang-questions mailing list