[erlang-questions] erl_nif environment in the load() function

Sverker Eriksson sverker@REDACTED
Mon Dec 19 15:03:47 CET 2011

Michael Uvarov wrote:
> Hello,
> There is code as example:
> https://github.com/beerriot/icu4e/blob/master/c_src/ustring.c
> I have few questions:
> 1. How long is env's lifetime in the load(...)? Will the env be erased
> after the call or after module unloading?
All environments passed as argument from VM are only valid until the 
call returns.

> 2. Is this code valid?
> ERL_NIF_TERM ustring_endian(ErlNifEnv* env, int argc,
>                             const ERL_NIF_TERM argv[]) {
>     return ATOM_ENDIAN;
> }
> Is the next construction better?
> return enif_make_copy(env, ATOM_ENDIAN);
Normally the lifetime of a term is determined by its environment. 
However, atoms are an exception to this rule, which allows you to 
prefabricate atoms in static variables.

This exceptions is undocumented but widely used (by myself included in 
crypto). There is a small risk that an introduction of atom garbage 
collection in some non predictable future release will have to break 
this feature.

The "super correct" way to return atoms is to either

* call enif_make_atom() every time you want to return an atom
* prefabricate atoms with enif_alloc_env() and enif_make_atom() in 
load() and then copy them with enif_make_copy() to the right environments.

Both of these will cost performance, I don't know which one is worse.

The best solution would be to come up with an addition to the erl_nif 
interface that would both give good performance and be future proof.

/Sverker, Erlang/OTP

More information about the erlang-questions mailing list