From f7af5e52d7ada47a38d309aea76e166be27f6288 Mon Sep 17 00:00:00 2001 From: Steve Vinoski Date: Thu, 3 Mar 2011 10:07:15 -0500 Subject: clarify NIF resource object deallocation documentation In the erl_nif documentation, clarify how and when NIF resource objects can be deallocated. Specifically, add focus for the case of calling enif_release_resource immediately after obtaining a resource term from enif_make_resource, since this is likely to be a common approach NIFs use to manage resources. Also fix a couple misspellings in the erl_nif documentation. --- erts/doc/src/erl_nif.xml | 49 +++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) (limited to 'erts/doc/src') diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index 5987ddbd5e..4bbd4e2a54 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -193,9 +193,9 @@ ok A handle ("safe pointer") to this memory block can then be returned to Erlang by the use of enif_make_resource. The term returned by enif_make_resource - is totally opaque in nature. It can be stored and passed between processses - on the same node, but the only real end usage is to pass it back as argument to a NIF. - The NIF can then do enif_get_resource + is totally opaque in nature. It can be stored and passed between processes + on the same node, but the only real end usage is to pass it back as an argument to a NIF. + The NIF can then call enif_get_resource and get back a pointer to the memory block that is guaranteed to still be valid. A resource object will not be deallocated until the last handle term has been garbage collected by the VM and the resource has been @@ -212,17 +212,7 @@ ok the garbage collector or enif_release_resource). Resource types are uniquely identified by a supplied name string and the name of the implementing module.

-

Resource types support upgrade in runtime by allowing a loaded NIF - library to takeover an already existing resource type and thereby - "inherit" all existing objects of that type. The destructor of the new - library will thereafter be called for the inherited objects and the - library with the old destructor function can be safely unloaded. Existing - resource objects, of a module that is upgraded, must either be deleted - or taken over by the new NIF library. The unloading of a library will be - postponed as long as there exist resource objects with a destructor - function in the library. -

-

Here is a template example of how to create and return a resource object.

+

Here is a template example of how to create and return a resource object.

ERL_NIF_TERM term; @@ -240,8 +230,13 @@ ok /* resource now only owned by "Erlang" */ } return term; -} - + +

Note that once enif_make_resource creates the term to + return to Erlang, the code can choose to either keep its own + native pointer to the allocated struct and release it later, or + release it immediately and rely solely on the garbage collector + to eventually deallocate the resource object when it collects + the term.

Another usage of resource objects is to create binary terms with user defined memory management. enif_make_resource_binary @@ -251,6 +246,16 @@ ok this can be a binary term consisting of data from a mmap'ed file. The destructor can then do munmap to release the memory region.

+

Resource types support upgrade in runtime by allowing a loaded NIF + library to takeover an already existing resource type and thereby + "inherit" all existing objects of that type. The destructor of the new + library will thereafter be called for the inherited objects and the + library with the old destructor function can be safely unloaded. Existing + resource objects, of a module that is upgraded, must either be deleted + or taken over by the new NIF library. The unloading of a library will be + postponed as long as there exist resource objects with a destructor + function in the library. +

Threads and concurrency

A NIF is thread-safe without any explicit synchronization as @@ -368,7 +373,7 @@ ok environments between NIF calls.

A process independent environment is created by calling enif_alloc_env. It can be - used to store terms beteen NIF calls and to send terms with + used to store terms between NIF calls and to send terms with enif_send. A process independent environment with all its terms is valid until you explicitly invalidates it with enif_free_env @@ -832,8 +837,14 @@ typedef enum { Create an opaque handle to a resource object

Create an opaque handle to a memory managed resource object obtained by enif_alloc_resource. - No ownership transfer is done, the resource object still needs to be released by - enif_release_resource.

+ No ownership transfer is done, as the resource object still needs to be released by + enif_release_resource, + but note that the call to enif_release_resource can occur + immediately after obtaining the term from enif_make_resource, + in which case the resource object will be deallocated when the + term is garbage collected. See the + example of creating and + returning a resource object for more details.

Note that the only defined behaviour of using a resource term in an Erlang program is to store it and send it between processes on the same node. Other operations such as matching or term_to_binary -- cgit v1.2.3