[erlang-questions] erl_nif: questions regarding resource handling

Lars-Åke Fredlund lfredlund@REDACTED
Wed Nov 16 18:12:49 CET 2011


I have been looking at possibly using the erl_nif library for 
implementing a table in C, with operations like:
     add: term() -> reference()
such that reference is a tuple {nif_resource(), other_stuff...} to 
enable the references to be garbage collected (a erl_nif destructor 
called when resource usage is zero).

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.

To enable garbage collection of resources I have to call 
enif_release_resource in the C part, but I still have to keep "some" 
control of the resources to be able to return the same resource for the 
next call of add with the same term parameter.

Concretely the pseudo-code for the case of a new term is:

     r = enif_alloc_resource();
     enif_make_resource(env, r);
     enif_release_resource(r);         // to enable gc
     return "tuple with resource inside";

For an "old" term:

     return enif_make_copy(env, "old tuple with resource inside");

- Is it allowed to call enif_make_copy with a term containing a 
"non-controlled" resource "pointer" as an argument?

- Does enif_make_copy increase the reference count for resources 
embedded in the argument?

- What is the role of an environment with regards to resources?
- 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?

- 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?)

For this application it would actually be nice to have reference 
counting only for the Erlang runtime part, and to have the destructor 
function called when the Erlang side have no references left. That is, 
forgetting about reference counting for the C part.

- By the way, should destructors functions be thread-safe, or are they 
called in isolation?

Sorry for the many questions,

More information about the erlang-questions mailing list