aboutsummaryrefslogtreecommitdiffstats
path: root/erts/doc/src
diff options
context:
space:
mode:
Diffstat (limited to 'erts/doc/src')
-rw-r--r--erts/doc/src/absform.xml160
-rw-r--r--erts/doc/src/erl.xml21
-rw-r--r--erts/doc/src/erl_nif.xml230
-rw-r--r--erts/doc/src/erlang.xml368
-rw-r--r--erts/doc/src/init.xml2
5 files changed, 558 insertions, 223 deletions
diff --git a/erts/doc/src/absform.xml b/erts/doc/src/absform.xml
index 835a4fc692..e1a8c2e517 100644
--- a/erts/doc/src/absform.xml
+++ b/erts/doc/src/absform.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -80,6 +80,28 @@
<item>If F is a record declaration <c><![CDATA[-record(Name,{V_1, ..., V_k})]]></c>, then
Rep(F) =
<c><![CDATA[{attribute,LINE,record,{Name,[Rep(V_1), ..., Rep(V_k)]}}]]></c>. For Rep(V), see below.</item>
+ <item>If F is a type attribute (i.e. <c><![CDATA[opaque]]></c> or
+ <c><![CDATA[type]]></c>)
+ <c><![CDATA[-Attr Name(A_1, ..., A_k) :: T]]></c> where each
+ <c><![CDATA[A_i]]></c> is a variable, then Rep(F) =
+ <c><![CDATA[{attribute,LINE,Attr,{Name,Rep(T),[Rep(A_1), ..., Rep(A_k)]}}]]></c>.
+ For Rep(T), see below.</item>
+ <item>If F is a type spec (i.e. <c><![CDATA[callback]]></c> or
+ <c><![CDATA[spec]]></c>)
+ <c><![CDATA[-Attr F Tc_1; ...; Tc_k]]></c>,
+ where each <c><![CDATA[Tc_i]]></c> is a fun type clause with an
+ argument sequence of the same length <c><![CDATA[Arity]]></c>, then
+ Rep(F) =
+ <c><![CDATA[{Attr,LINE,{{F,Arity},[Rep(Tc_1), ..., Rep(Tc_k)]}}]]></c>.
+ For Rep(Tc_i), see below.</item>
+ <item>If F is a type spec (i.e. <c><![CDATA[callback]]></c> or
+ <c><![CDATA[spec]]></c>)
+ <c><![CDATA[-Attr Mod:F Tc_1; ...; Tc_k]]></c>,
+ where each <c><![CDATA[Tc_i]]></c> is a fun type clause with an
+ argument sequence of the same length <c><![CDATA[Arity]]></c>, then
+ Rep(F) =
+ <c><![CDATA[{Attr,LINE,{{Mod,F,Arity},[Rep(Tc_1), ..., Rep(Tc_k)]}}]]></c>.
+ For Rep(Tc_i), see below.</item>
<item>If F is a wild attribute <c><![CDATA[-A(T)]]></c>, then
Rep(F) = <c><![CDATA[{attribute,LINE,A,T}]]></c>.
<br></br></item>
@@ -90,6 +112,127 @@
</list>
<section>
+ <title>Type clauses</title>
+ <list type="bulleted">
+ <item>If T is a fun type clause
+ <c><![CDATA[(A_1, ..., A_n) -> Ret]]></c>, where each
+ <c><![CDATA[A_i]]></c> and <c><![CDATA[Ret]]></c> are types, then
+ Rep(T) =
+ <c><![CDATA[{type,LINE,'fun',[{type,LINE,product,[Rep(A_1), ..., Rep(A_n)]},Rep(Ret)]}]]></c>.
+ </item>
+ <item>If T is a bounded fun type clause <c><![CDATA[Tc when Tg]]></c>,
+ where <c><![CDATA[Tc]]></c> is an unbounded fun type clause and
+ <c><![CDATA[Tg]]></c> is a type guard sequence, then Rep(T) =
+ <c><![CDATA[{type,LINE,bounded_fun,[Rep(Tc),Rep(Tg)]}]]></c>.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Type guards</title>
+ <list type="bulleted">
+ <item>If G is a constraint <c><![CDATA[F(A_1, ..., A_k)]]></c>, where
+ <c><![CDATA[F]]></c> is an atom and each <c><![CDATA[A_i]]></c> is a
+ type, then Rep(G) =
+ <c><![CDATA[{type,LINE,constraint,[Rep(F),[Rep(A_1), ..., Rep(A_k)]]}]]></c>.
+ </item>
+ <item>If G is a type definition <c><![CDATA[Name :: Type]]></c>,
+ where <c><![CDATA[Name]]></c> is a variable and
+ <c><![CDATA[Type]]></c> is a type, then Rep(G) =
+ <c><![CDATA[{type,LINE,constraint,[{atom,LINE,is_subtype},[Rep(Name),Rep(Type)]]}]]></c>.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Types</title>
+ <list type="bulleted">
+ <item>If T is a type definition <c><![CDATA[Name :: Type]]></c>,
+ where <c><![CDATA[Name]]></c> is a variable and
+ <c><![CDATA[Type]]></c> is a type, then Rep(T) =
+ <c><![CDATA[{ann_type,LINE,[Rep(Name),Rep(Type)]}]]></c>.</item>
+ <item>If T is a type union <c><![CDATA[A_1 | ... | A_k]]></c>,
+ where each <c><![CDATA[A_i]]></c> is a type, then Rep(T) =
+ <c><![CDATA[{type,LINE,union,[Rep(A_1), ..., Rep(A_k)]}]]></c>.</item>
+ <item>If T is a type range <c><![CDATA[L .. R]]></c>,
+ where <c><![CDATA[L]]></c> and <c><![CDATA[R]]></c> are types, then
+ Rep(T) = <c><![CDATA[{type,LINE,range,[Rep(L), Rep(R)]}]]></c>.</item>
+ <item>If T is a binary operation <c><![CDATA[L Op R]]></c>,
+ where <c><![CDATA[Op]]></c> is an arithmetic or bitwise binary operator
+ and <c><![CDATA[L]]></c> and <c><![CDATA[R]]></c> are types, then
+ Rep(T) = <c><![CDATA[{op,LINE,Op,Rep(L),Rep(R)}]]></c>.</item>
+ <item>If T is <c><![CDATA[Op A]]></c>, where <c><![CDATA[Op]]></c> is an
+ arithmetic or bitwise unary operator and <c><![CDATA[A]]></c> is a
+ type, then Rep(T) = <c><![CDATA[{op,LINE,Op,Rep(A)}]]></c>.</item>
+ <item>If T is a fun type <c><![CDATA[fun()]]></c>, then Rep(T) =
+ <c><![CDATA[{type,LINE,'fun',[]}]]></c>.</item>
+ <item>If T is a variable <c><![CDATA[V]]></c>, then Rep(T) =
+ <c><![CDATA[{var,LINE,A}]]></c>, where <c><![CDATA[A]]></c> is an atom
+ with a printname consisting of the same characters as
+ <c><![CDATA[V]]></c>.</item>
+ <item>If T is an atomic literal L and L is not a string literal, then
+ Rep(T) = Rep(L).</item>
+ <item>If T is a tuple or map type <c><![CDATA[F()]]></c> (i.e.
+ <c><![CDATA[tuple]]></c> or <c><![CDATA[map]]></c>), then Rep(T) =
+ <c><![CDATA[{type,LINE,F,any}]]></c>.</item>
+ <item>If T is a type <c><![CDATA[F(A_1, ..., A_k)]]></c>, where each
+ <c><![CDATA[A_i]]></c> is a type, then Rep(T) =
+ <c><![CDATA[{user_type,LINE,F,[Rep(A_1), ..., Rep(A_k)]}]]></c>.</item>
+ <item>If T is a remote type <c><![CDATA[M:F(A_1, ..., A_k)]]></c>, where
+ each <c><![CDATA[A_i]]></c> is a type and <c><![CDATA[M]]></c> and
+ <c><![CDATA[F]]></c>, then Rep(T) =
+ <c><![CDATA[{remote_type,LINE,[Rep(M),Rep(F),[Rep(A_1), ..., Rep(A_k)]]}]]></c>.
+ </item>
+ <item>If T is the nil type <c><![CDATA[[]]]></c>, then Rep(T) =
+ <c><![CDATA[{type,LINE,nil,[]}]]></c>.</item>
+ <item>If T is a list type <c><![CDATA[[A]]]></c>, where
+ <c><![CDATA[A]]></c> is a type, then Rep(T) =
+ <c><![CDATA[{type,LINE,list,[Rep(A)]}]]></c>.</item>
+ <item>If T is a non-empty list type <c><![CDATA[[A, ...]]]></c>, where
+ <c><![CDATA[A]]></c> is a type, then Rep(T) =
+ <c><![CDATA[{type,LINE,nonempty_list,[Rep(A)]}]]></c>.</item>
+ <item>If T is a map type <c><![CDATA[#{P_1, ..., P_k}]]></c>, where each
+ <c><![CDATA[P_i]]></c> is a map pair type, then Rep(T) =
+ <c><![CDATA[{type,LINE,map,[Rep(P_1), ..., Rep(P_k)]}]]></c>.</item>
+ <item>If T is a map pair type <c><![CDATA[K => V]]></c>, where
+ <c><![CDATA[K]]></c> and <c><![CDATA[V]]></c> are types,
+ then Rep(T) =
+ <c><![CDATA[{type,LINE,map_field_assoc,[Rep(K),Rep(V)]}]]></c>.</item>
+ <item>If T is a tuple type <c><![CDATA[{A_1, ..., A_k}]]></c>, where
+ each <c><![CDATA[A_i]]></c> is a type, then Rep(T) =
+ <c><![CDATA[{type,LINE,tuple,[Rep(A_1), ..., Rep(A_k)]}]]></c>.</item>
+ <item>If T is a record type <c><![CDATA[#Name{}]]></c>, where
+ <c><![CDATA[Name]]></c> is an atom, then Rep(T) =
+ <c><![CDATA[{type,LINE,record,[Rep(Name)]}]]></c>.</item>
+ <item>If T is a record type <c><![CDATA[#Name{F_1, ..., F_k}]]></c>,
+ where <c><![CDATA[Name]]></c> is an atom, then Rep(T) =
+ <c><![CDATA[{type,LINE,record,[Rep(Name),[Rep(F_1), ..., Rep(F_k)]]}]]></c>.
+ </item>
+ <item>If T is a record field type <c><![CDATA[Name :: Type]]></c>,
+ where <c><![CDATA[Name]]></c> is an atom, then Rep(T) =
+ <c><![CDATA[{type,LINE,field_type,[Rep(Name),Rep(Type)]}]]></c>.</item>
+ <item>If T is a record field type <c><![CDATA[<<>>]]></c>, then Rep(T) =
+ <c><![CDATA[{type,LINE,binary,[{integer,LINE,0},{integer,LINE,0}]}]]></c>.
+ </item>
+ <item>If T is a binary type <c><![CDATA[<< _ : B >>]]></c>, where
+ <c><![CDATA[B]]></c> is a type, then Rep(T) =
+ <c><![CDATA[{type,LINE,binary,[Rep(B),{integer,LINE,0}]}]]></c>.</item>
+ <item>If T is a binary type <c><![CDATA[<< _ : _ * U >>]]></c>,
+ where <c><![CDATA[U]]></c> is a type, then Rep(T) =
+ <c><![CDATA[{type,LINE,binary,[{integer,LINE,0},Rep(U)]}]]></c>.</item>
+ <item>If T is a binary type <c><![CDATA[<< _ : B , _ : _ * U >>]]></c>,
+ where <c><![CDATA[B]]></c> and <c><![CDATA[U]]></c> is a type, then
+ Rep(T) =
+ <c><![CDATA[{type,LINE,binary,[Rep(B),Rep(U)]}]]></c>.</item>
+
+ <item>If T is a fun type <c><![CDATA[fun((...) -> Ret)]]></c>, then
+ Rep(T) = <c><![CDATA[{type,LINE,'fun',[{type,LINE,product,[]},Rep(Ret)]}]]></c>.
+ </item>
+ <item>If T is a fun type <c><![CDATA[fun(Tc)]]></c>, where
+ <c><![CDATA[Tc]]></c> is an unbounded fun type clause,
+ then Rep(T) = <c><![CDATA[Rep(Tc)]]></c>.</item>
+ </list>
+ </section>
+
+ <section>
<title>Record fields</title>
<p>Each field in a record declaration may have an optional
explicit default initializer expression</p>
@@ -98,6 +241,21 @@
Rep(V) = <c><![CDATA[{record_field,LINE,Rep(A)}]]></c>.</item>
<item>If V is <c><![CDATA[A = E]]></c>, then
Rep(V) = <c><![CDATA[{record_field,LINE,Rep(A),Rep(E)}]]></c>.</item>
+ <item>If V is <c><![CDATA[A :: T]]></c>, where <c><![CDATA[A]]></c> is
+ an atom and <c><![CDATA[T]]></c> is a type and it does not contain
+ <c><![CDATA[undefined]]></c> syntactically, then Rep(V) =
+ <c><![CDATA[{typed_record_field,{record_field,LINE,Rep(A)},Rep(undefined | T)}]]></c>.
+ Note that if <![CDATA[T]]> is an annotated type, it will be wrapped in
+ parentheses.</item>
+ <item>If V is <c><![CDATA[A :: T]]></c>, where <c><![CDATA[A]]></c> is
+ an atom and <c><![CDATA[T]]></c> is a type, then Rep(V) =
+ <c><![CDATA[{typed_record_field,{record_field,LINE,Rep(A)},Rep(T)}]]></c>.
+ </item>
+ <item>If V is <c><![CDATA[A = E :: T]]></c>, where <c><![CDATA[A]]></c>
+ is an atom, <c><![CDATA[E]]></c> is an expression and
+ <c><![CDATA[T]]></c> is a type, then Rep(V) =
+ <c><![CDATA[{typed_record_field,{record_field,LINE,Rep(A),Rep(E)},Rep(T)}]]></c>.
+ </item>
</list>
</section>
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index ea94a4e82b..f41b6e6149 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -1322,13 +1322,14 @@
<item>
<p>Verbose.</p>
</item>
- <tag><c><![CDATA[+W w | i]]></c></tag>
+ <tag><c><![CDATA[+W w | i | e]]></c></tag>
<item>
<p>Sets the mapping of warning messages for <c><![CDATA[error_logger]]></c>.
Messages sent to the error logger using one of the warning
- routines can be mapped either to errors (default), warnings
- (<c><![CDATA[+W w]]></c>), or info reports (<c><![CDATA[+W i]]></c>). The current
- mapping can be retrieved using
+ routines can be mapped either to errors (<c><![CDATA[+W e]]></c>),
+ warnings (<c><![CDATA[+W w]]></c>), or info reports
+ (<c><![CDATA[+W i]]></c>). The default is warnings.
+ The current mapping can be retrieved using
<c><![CDATA[error_logger:warning_map/0]]></c>. See
<seealso marker="kernel:error_logger#warning_map/0">error_logger(3)</seealso>
for further information.</p>
@@ -1350,6 +1351,18 @@
give lower latency and higher throughput at the expense
of higher memory usage.</p>
</item>
+ <tag><marker id="+zdntgc"><c>+zdntgc time</c></marker></tag>
+ <item>
+ <p>Set the delayed node table garbage collection time
+ (<seealso marker="erlang#system_info_delayed_node_table_gc">delayed_node_table_gc</seealso>)
+ in seconds. Valid values are either <c>infinity</c> or
+ an integer in the range [0-100000000]. Default is 60.</p>
+ <p>Node table entries that are not referred will linger
+ in the table for at least the amount of time that this
+ parameter determines. The lingering prevents repeated
+ deletions and insertions in the tables from occurring.
+ </p>
+ </item>
</taglist>
</item>
</taglist>
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 4bad8b253c..f64381c99d 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -461,8 +461,9 @@ ok
independent environment with all its terms is valid until you explicitly
invalidates it with <seealso marker="#enif_free_env">enif_free_env</seealso>
or <c>enif_send</c>.</p>
- <p>All elements of a list/tuple must belong to the same environment as the
- list/tuple itself. Terms can be copied between environments with
+ <p>All contained terms of a list/tuple/map must belong to the same
+ environment as the list/tuple/map itself. Terms can be copied between
+ environments with
<seealso marker="#enif_make_copy">enif_make_copy</seealso>.</p>
</item>
<tag><marker id="ErlNifFunc"/>ErlNifFunc</tag>
@@ -564,11 +565,11 @@ typedef enum {
<funcs>
<func><name><ret>void *</ret><nametext>enif_alloc(size_t size)</nametext></name>
- <fsummary>Allocate dynamic memory.</fsummary>
+ <fsummary>Allocate dynamic memory</fsummary>
<desc><p>Allocate memory of <c>size</c> bytes. Return NULL if allocation failed.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_alloc_binary(size_t size, ErlNifBinary* bin)</nametext></name>
- <fsummary>Create a new binary.</fsummary>
+ <fsummary>Create a new binary</fsummary>
<desc><p>Allocate a new binary of size <c>size</c>
bytes. Initialize the structure pointed to by <c>bin</c> to
refer to the allocated binary. The binary must either be released by
@@ -595,7 +596,7 @@ typedef enum {
<desc><p>Allocate a memory managed resource object of type <c>type</c> and size <c>size</c> bytes.</p></desc>
</func>
<func><name><ret>void</ret><nametext>enif_clear_env(ErlNifEnv* env)</nametext></name>
- <fsummary>Clear an environment for reuse.</fsummary>
+ <fsummary>Clear an environment for reuse</fsummary>
<desc><p>Free all terms in an environment and clear it for reuse. The environment must
have been allocated with <seealso marker="#enif_alloc_env">enif_alloc_env</seealso>.
</p></desc>
@@ -683,14 +684,14 @@ typedef enum {
<c>size-1</c>.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_atom_length(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len, ErlNifCharEncoding encode)</nametext></name>
- <fsummary>Get the length of atom <c>term</c>.</fsummary>
+ <fsummary>Get the length of atom <c>term</c></fsummary>
<desc><p>Set <c>*len</c> to the length (number of bytes excluding
terminating null character) of the atom <c>term</c> with encoding
<c>encode</c>. Return true on success or false if <c>term</c> is not an
atom.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_double(ErlNifEnv* env, ERL_NIF_TERM term, double* dp)</nametext></name>
- <fsummary>Read a floating-point number term.</fsummary>
+ <fsummary>Read a floating-point number term</fsummary>
<desc><p>Set <c>*dp</c> to the floating point value of
<c>term</c>. Return true on success or false if <c>term</c> is not a float.</p></desc>
</func>
@@ -719,17 +720,28 @@ typedef enum {
non-empty list.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_list_length(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len)</nametext></name>
- <fsummary>Get the length of list <c>term</c>.</fsummary>
+ <fsummary>Get the length of list <c>term</c></fsummary>
<desc><p>Set <c>*len</c> to the length of list <c>term</c> and return true,
or return false if <c>term</c> is not a list.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_long(ErlNifEnv* env, ERL_NIF_TERM term, long int* ip)</nametext></name>
- <fsummary>Read an long integer term.</fsummary>
+ <fsummary>Read an long integer term</fsummary>
<desc><p>Set <c>*ip</c> to the long integer value of <c>term</c> and
return true, or return false if <c>term</c> is not an integer or is
outside the bounds of type <c>long int</c>.</p></desc>
</func>
- <func><name><ret>int</ret><nametext>enif_get_resource(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifResourceType* type, void** objp)</nametext></name>
+ <func><name><ret>int</ret><nametext>enif_get_map_size(ErlNifEnv* env, ERL_NIF_TERM term, size_t *size)</nametext></name>
+ <fsummary>Read the size of a map term</fsummary>
+ <desc><p>Set <c>*size</c> to the number of key-value pairs in the map <c>term</c> and
+ return true, or return false if <c>term</c> is not a map.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_get_map_value(ErlNifEnv* env, ERL_NIF_TERM map, ERL_NIF_TERM key, ERL_NIF_TERM* value)</nametext></name>
+ <fsummary>Get the value of a key in a map</fsummary>
+ <desc><p>Set <c>*value</c> to the value associated with <c>key</c> in the
+ map <c>map</c> and return true. Return false if <c>map</c> is not a map
+ or if <c>map</c> does not contain <c>key</c>.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_get_resource(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifResourceType* type, void** objp)</nametext></name>
<fsummary>Get the pointer to a resource object</fsummary>
<desc><p>Set <c>*objp</c> to point to the resource object referred to by <c>term</c>.</p>
<p>Return true on success or false if <c>term</c> is not a handle to a resource object
@@ -738,7 +750,7 @@ typedef enum {
<func><name><ret>int</ret><nametext>enif_get_string(ErlNifEnv* env,
ERL_NIF_TERM list, char* buf, unsigned size,
ErlNifCharEncoding encode)</nametext></name>
- <fsummary>Get a C-string from a list.</fsummary>
+ <fsummary>Get a C-string from a list</fsummary>
<desc><p>Write a null-terminated string, in the buffer pointed to by
<c>buf</c> with size <c>size</c>, consisting of the characters
in the string <c>list</c>. The characters are written using encoding
@@ -751,7 +763,7 @@ typedef enum {
<c>size</c> is less than 1.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_tuple(ErlNifEnv* env, ERL_NIF_TERM term, int* arity, const ERL_NIF_TERM** array)</nametext></name>
- <fsummary>Inspect the elements of a tuple.</fsummary>
+ <fsummary>Inspect the elements of a tuple</fsummary>
<desc><p>If <c>term</c> is a tuple, set <c>*array</c> to point
to an array containing the elements of the tuple and set
<c>*arity</c> to the number of elements. Note that the array
@@ -761,28 +773,35 @@ typedef enum {
tuple.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_uint(ErlNifEnv* env, ERL_NIF_TERM term, unsigned int* ip)</nametext></name>
- <fsummary>Read an unsigned integer term.</fsummary>
+ <fsummary>Read an unsigned integer term</fsummary>
<desc><p>Set <c>*ip</c> to the unsigned integer value of <c>term</c> and
return true, or return false if <c>term</c> is not an unsigned integer or
is outside the bounds of type <c>unsigned int</c>.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_uint64(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifUInt64* ip)</nametext></name>
- <fsummary>Read an unsigned 64-bit integer term.</fsummary>
+ <fsummary>Read an unsigned 64-bit integer term</fsummary>
<desc><p>Set <c>*ip</c> to the unsigned integer value of <c>term</c> and
return true, or return false if <c>term</c> is not an unsigned integer or
is outside the bounds of an unsigned 64-bit integer.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_ulong(ErlNifEnv* env, ERL_NIF_TERM term, unsigned long* ip)</nametext></name>
- <fsummary>Read an unsigned integer term.</fsummary>
+ <fsummary>Read an unsigned integer term</fsummary>
<desc><p>Set <c>*ip</c> to the unsigned long integer value of <c>term</c>
and return true, or return false if <c>term</c> is not an unsigned integer or is
outside the bounds of type <c>unsigned long</c>.</p></desc>
</func>
- <func><name><ret>int</ret><nametext>enif_has_pending_exception(ErlNifEnv* env)</nametext></name>
- <fsummary>Check if an exception has been raised.</fsummary>
+ <func><name><ret>int</ret><nametext>enif_has_pending_exception(ErlNifEnv* env, ERL_NIF_TERM* reason)</nametext></name>
+ <fsummary>Check if an exception has been raised</fsummary>
<desc><p>Return true if a pending exception is associated
- with the environment <c>env</c>. The only possible exception is currently
- <c>badarg</c> (see <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>).</p></desc>
+ with the environment <c>env</c>. If <c>reason</c> is a null pointer, ignore it.
+ Otherwise, if there's a pending exception associated with <c>env</c>, set the ERL_NIF_TERM
+ to which <c>reason</c> points to the value of the exception's term. For example, if
+ <seealso marker="#enif_make_badarg">enif_make_badarg</seealso> is called to set a
+ pending <c>badarg</c> exception, a subsequent call to <c>enif_has_pending_exception(env, &amp;reason)</c>
+ will set <c>reason</c> to the atom <c>badarg</c>, then return true.</p>
+ <p>See also: <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>
+ and <seealso marker="#enif_raise_exception">enif_raise_exception</seealso>.</p>
+ </desc>
</func>
<func><name><ret>int</ret><nametext>enif_inspect_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term, ErlNifBinary* bin)</nametext></name>
<fsummary>Inspect the content of a binary</fsummary>
@@ -817,6 +836,10 @@ typedef enum {
<fsummary>Determine if a term is an exception</fsummary>
<desc><p>Return true if <c>term</c> is an exception.</p></desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_is_map(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is a map</fsummary>
+ <desc><p>Return true if <c>term</c> is a map, false otherwise.</p></desc>
+ </func>
<func><name><ret>int</ret><nametext>enif_is_number(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
<fsummary>Determine if a term is a number (integer or float)</fsummary>
<desc><p>Return true if <c>term</c> is a number.</p></desc>
@@ -890,18 +913,19 @@ typedef enum {
</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_badarg(ErlNifEnv* env)</nametext></name>
- <fsummary>Make a badarg exception.</fsummary>
+ <fsummary>Make a badarg exception</fsummary>
<desc><p>Make a badarg exception to be returned from a NIF, and associate
it with the environment <c>env</c>. Once a NIF or any function
it calls invokes <c>enif_make_badarg</c>, the runtime ensures that a
<c>badarg</c> exception is raised when the NIF returns, even if the NIF
attempts to return a non-exception term instead.
- The return value from <c>enif_make_badarg</c> may only be used as
- return value from the NIF that invoked it (direct or indirectly)
+ The return value from <c>enif_make_badarg</c> may be used only as the
+ return value from the NIF that invoked it (directly or indirectly)
or be passed to
<seealso marker="#enif_is_exception">enif_is_exception</seealso>, but
not to any other NIF API function.</p>
- <p>See also: <seealso marker="#enif_has_pending_exception">enif_has_pending_exception</seealso>.
+ <p>See also: <seealso marker="#enif_has_pending_exception">enif_has_pending_exception</seealso>
+ and <seealso marker="#enif_raise_exception">enif_raise_exception</seealso>
</p>
<note><p>In earlier versions (older than erts-7.0, OTP 18) the return value
from <c>enif_make_badarg</c> had to be returned from the NIF. This
@@ -909,14 +933,14 @@ typedef enum {
if <c>enif_make_badarg</c> has been invoked.</p></note></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)</nametext></name>
- <fsummary>Make a binary term.</fsummary>
+ <fsummary>Make a binary term</fsummary>
<desc><p>Make a binary term from <c>bin</c>. Any ownership of
the binary data will be transferred to the created term and
<c>bin</c> should be considered read-only for the rest of the NIF
call and then as released.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_copy(ErlNifEnv* dst_env, ERL_NIF_TERM src_term)</nametext></name>
- <fsummary>Make a copy of a term.</fsummary>
+ <fsummary>Make a copy of a term</fsummary>
<desc><p>Make a copy of term <c>src_term</c>. The copy will be created in
environment <c>dst_env</c>. The source term may be located in any
environment.</p></desc>
@@ -957,7 +981,7 @@ typedef enum {
<desc><p>Create an integer term from a signed 64-bit integer.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list(ErlNifEnv* env, unsigned cnt, ...)</nametext></name>
- <fsummary>Create a list term.</fsummary>
+ <fsummary>Create a list term</fsummary>
<desc><p>Create an ordinary list term of length <c>cnt</c>. Expects
<c>cnt</c> number of arguments (after <c>cnt</c>) of type ERL_NIF_TERM as the
elements of the list. An empty list is returned if <c>cnt</c> is 0.</p></desc>
@@ -971,28 +995,21 @@ typedef enum {
<name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list7(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7)</nametext></name>
<name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list8(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8)</nametext></name>
<name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list9(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9)</nametext></name>
- <fsummary>Create a list term.</fsummary>
+ <fsummary>Create a list term</fsummary>
<desc><p>Create an ordinary list term with length indicated by the
function name. Prefer these functions (macros) over the variadic
<c>enif_make_list</c> to get a compile time error if the number of
arguments does not match.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list_cell(ErlNifEnv* env, ERL_NIF_TERM head, ERL_NIF_TERM tail)</nametext></name>
- <fsummary>Create a list cell.</fsummary>
+ <fsummary>Create a list cell</fsummary>
<desc><p>Create a list cell <c>[head | tail]</c>.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt)</nametext></name>
- <fsummary>Create a list term from an array.</fsummary>
+ <fsummary>Create a list term from an array</fsummary>
<desc><p>Create an ordinary list containing the elements of array <c>arr</c>
of length <c>cnt</c>. An empty list is returned if <c>cnt</c> is 0.</p></desc>
</func>
- <func><name><ret>int</ret><nametext>enif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list)</nametext></name>
- <fsummary>Create the reverse list of the list <c>term</c>.</fsummary>
- <desc><p>Set <c>*list</c> to the reverse list of the list <c>term</c> and return true,
- or return false if <c>term</c> is not a list. This function should only be used on
- short lists as a copy will be created of the list which will not be released until after the
- nif returns.</p></desc>
- </func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_long(ErlNifEnv* env, long int i)</nametext></name>
<fsummary>Create an integer term from a long int</fsummary>
<desc><p>Create an integer term from a <c>long int</c>.</p></desc>
@@ -1007,12 +1024,42 @@ typedef enum {
reallocated.</p><p>Return a pointer to the raw binary data and set
<c>*termp</c> to the binary term.</p></desc>
</func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_new_map(ErlNifEnv* env)</nametext></name>
+ <fsummary>Make an empty map term</fsummary>
+ <desc><p>Make an empty map term.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_make_map_put(ErlNifEnv* env, ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM value, ERL_NIF_TERM* map_out)</nametext></name>
+ <fsummary>Insert key-value pair in map</fsummary>
+ <desc><p>Make a copy of map <c>map_in</c> and insert <c>key</c> with
+ <c>value</c>. If <c>key</c> already exists in <c>map_in</c>, the old
+ associated value is replaced by <c>value</c>. If successful set
+ <c>*map_out</c> to the new map and return true. Return false if
+ <c>map_in</c> is not a map.</p>
+ <p>The <c>map_in</c> term must belong to the environment <c>env</c>.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_make_map_update(ErlNifEnv* env, ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM new_value, ERL_NIF_TERM* map_out)</nametext></name>
+ <fsummary>Replace value for key in map</fsummary>
+ <desc><p>Make a copy of map <c>map_in</c> and replace the old associated
+ value for <c>key</c> with <c>new_value</c>. If successful set
+ <c>*map_out</c> to the new map and return true. Return false if
+ <c>map_in</c> is not a map or if it does no contain <c>key</c>.</p>
+ <p>The <c>map_in</c> term must belong to the environment <c>env</c>.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_make_map_remove(ErlNifEnv* env, ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM* map_out)</nametext></name>
+ <fsummary>Remove key from map</fsummary>
+ <desc><p>If map <c>map_in</c> contains <c>key</c>, make a copy of
+ <c>map_in</c> in <c>*map_out</c> and remove <c>key</c> and associated
+ value. If map <c>map_in</c> does not contain <c>key</c>, set
+ <c>*map_out</c> to <c>map_in</c>. Return true for success or false if
+ <c>map_in</c> is not a map.</p>
+ <p>The <c>map_in</c> term must belong to the environment <c>env</c>.</p></desc>
+ </func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_pid(ErlNifEnv* env, const ErlNifPid* pid)</nametext></name>
<fsummary>Make a pid term</fsummary>
<desc><p>Make a pid term from <c>*pid</c>.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_ref(ErlNifEnv* env)</nametext></name>
- <fsummary>Create a reference.</fsummary>
+ <fsummary>Create a reference</fsummary>
<desc><p>Create a reference like <seealso marker="erlang#make_ref-0">erlang:make_ref/0</seealso>.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_resource(ErlNifEnv* env, void* obj)</nametext></name>
@@ -1050,20 +1097,28 @@ typedef enum {
<seealso marker="#enif_release_resource">enif_release_resource</seealso>.</p>
</desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM list_in, ERL_NIF_TERM *list_out)</nametext></name>
+ <fsummary>Create the reverse of a list</fsummary>
+ <desc><p>Set <c>*list_out</c> to the reverse list of the list <c>list_in</c> and return true,
+ or return false if <c>list_in</c> is not a list. This function should only be used on
+ short lists as a copy will be created of the list which will not be released until after the
+ nif returns.</p>
+ <p>The <c>list_in</c> term must belong to the environment <c>env</c>.</p></desc>
+ </func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_string(ErlNifEnv* env, const char* string, ErlNifCharEncoding encoding)</nametext></name>
- <fsummary>Create a string.</fsummary>
+ <fsummary>Create a string</fsummary>
<desc><p>Create a list containing the characters of the
null-terminated string <c>string</c> with encoding <seealso marker="#ErlNifCharEncoding">encoding</seealso>.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_string_len(ErlNifEnv* env, const char* string, size_t len, ErlNifCharEncoding encoding)</nametext></name>
- <fsummary>Create a string.</fsummary>
+ <fsummary>Create a string</fsummary>
<desc><p>Create a list containing the characters of the string <c>string</c> with
length <c>len</c> and encoding <seealso marker="#ErlNifCharEncoding">encoding</seealso>.
Null-characters are treated as any other characters.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_sub_binary(ErlNifEnv*
env, ERL_NIF_TERM bin_term, size_t pos, size_t size)</nametext></name>
- <fsummary>Make a subbinary term.</fsummary>
+ <fsummary>Make a subbinary term</fsummary>
<desc><p>Make a subbinary of binary <c>bin_term</c>, starting at
zero-based position <c>pos</c> with a length of <c>size</c> bytes.
<c>bin_term</c> must be a binary or bitstring and
@@ -1071,7 +1126,7 @@ typedef enum {
bytes in <c>bin_term</c>.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)</nametext></name>
- <fsummary>Create a tuple term.</fsummary>
+ <fsummary>Create a tuple term</fsummary>
<desc><p>Create a tuple term of arity <c>cnt</c>. Expects
<c>cnt</c> number of arguments (after <c>cnt</c>) of type ERL_NIF_TERM as the
elements of the tuple.</p></desc>
@@ -1085,14 +1140,14 @@ typedef enum {
<name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple7(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7)</nametext></name>
<name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple8(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8)</nametext></name>
<name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple9(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9)</nametext></name>
- <fsummary>Create a tuple term.</fsummary>
+ <fsummary>Create a tuple term</fsummary>
<desc><p>Create a tuple term with length indicated by the
function name. Prefer these functions (macros) over the variadic
<c>enif_make_tuple</c> to get a compile time error if the number of
arguments does not match.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt)</nametext></name>
- <fsummary>Create a tuple term from an array.</fsummary>
+ <fsummary>Create a tuple term from an array</fsummary>
<desc><p>Create a tuple containing the elements of array <c>arr</c>
of length <c>cnt</c>.</p></desc>
</func>
@@ -1108,6 +1163,72 @@ typedef enum {
<fsummary>Create an integer term from an unsigned long int</fsummary>
<desc><p>Create an integer term from an <c>unsigned long int</c>.</p></desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_map_iterator_create(ErlNifEnv *env, ERL_NIF_TERM map, ErlNifMapIterator *iter, ErlNifMapIteratorEntry entry)</nametext></name>
+ <fsummary>Create a map iterator</fsummary>
+ <desc><p>Create an iterator for the map <c>map</c> by initializing the
+ structure pointed to by <c>iter</c>. The <c>entry</c> argument determines
+ the start position of the iterator: <c>ERL_NIF_MAP_ITERATOR_FIRST</c> or
+ <c>ERL_NIF_MAP_ITERATOR_LAST</c>. Return true on success or false if
+ <c>map</c> is not a map.</p>
+ <p>A map iterator is only useful during the lifetime of the environment
+ <c>env</c> that the <c>map</c> belongs to. The iterator must be destroyed by
+ calling <seealso marker="#enif_map_iterator_destroy">
+ enif_map_iterator_destroy</seealso>.</p>
+ <code type="none">
+ERL_NIF_TERM key, value;
+ErlNifMapIterator iter;
+enif_map_iterator_create(env, my_map, ERL_NIF_MAP_ITERATOR_FIRST);
+
+while (enif_map_iterator_get_pair(env, &amp;iter, &amp;key, &amp;value)) {
+ do_something(key,value);
+ enif_map_iterator_next(env, &amp;iter);
+}
+enif_map_iterator_destroy(env, &amp;iter);
+ </code>
+ <note><p>The key-value pairs of a map have no defined iteration
+ order. The only guarantee is that the iteration order of a single map
+ instance is preserved during the lifetime of the environment that the map
+ belongs to.</p>
+ </note>
+ </desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_map_iterator_destroy(ErlNifEnv *env, ErlNifMapIterator *iter)</nametext></name>
+ <fsummary>Destroy a map iterator</fsummary>
+ <desc><p>Destroy a map iterator created by
+ <seealso marker="#enif_map_iterator_create">enif_map_iterator_create</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_map_iterator_get_pair(ErlNifEnv *env, ErlNifMapIterator *iter, ERL_NIF_TERM *key, ERL_NIF_TERM *value)</nametext></name>
+ <fsummary>Get key and value at current map iterator position</fsummary>
+ <desc><p>Get key and value terms at current map iterator position.
+ On success set <c>*key</c> and <c>*value</c> and return true.
+ Return false if the iterator is positioned at head (before first entry)
+ or tail (beyond last entry).</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_map_iterator_is_head(ErlNifEnv *env, ErlNifMapIterator *iter)</nametext></name>
+ <fsummary>Check if map iterator is positioned before first</fsummary>
+ <desc><p>Return true if map iterator <c>iter</c> is positioned
+ before first entry.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_map_iterator_is_tail(ErlNifEnv *env, ErlNifMapIterator *iter)</nametext></name>
+ <fsummary>Check if map iterator is positioned after last</fsummary>
+ <desc><p>Return true if map iterator <c>iter</c> is positioned
+ after last entry.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_map_iterator_next(ErlNifEnv *env, ErlNifMapIterator *iter)</nametext></name>
+ <fsummary>Increment map iterator to point to next entry</fsummary>
+ <desc><p>Increment map iterator to point to next key-value entry.
+ Return true if the iterator is now positioned at a valid key-value entry,
+ or false if the iterator is positioned at the tail (beyond the last
+ entry).</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_map_iterator_prev(ErlNifEnv *env, ErlNifMapIterator *iter)</nametext></name>
+ <fsummary>Decrement map iterator to point to previous entry</fsummary>
+ <desc><p>Decrement map iterator to point to previous key-value entry.
+ Return true if the iterator is now positioned at a valid key-value entry,
+ or false if the iterator is positioned at the head (before the first
+ entry).</p></desc>
+ </func>
<func><name><ret>ErlNifMutex *</ret><nametext>enif_mutex_create(char *name)</nametext></name>
<fsummary></fsummary>
<desc><p>Same as <seealso marker="erl_driver#erl_drv_mutex_create">erl_drv_mutex_create</seealso>.
@@ -1168,19 +1289,32 @@ typedef enum {
<c>reload</c> or <c>upgrade</c>.</p>
<p>Was previously named <c>enif_get_data</c>.</p></desc>
</func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_raise_exception(ErlNifEnv* env, ERL_NIF_TERM reason)</nametext></name>
+ <fsummary>Raise a NIF error exception</fsummary>
+ <desc><p>Create an error exception with the term <c>reason</c> to be returned from a NIF,
+ and associate it with the environment <c>env</c>. Once a NIF or any function it calls
+ invokes <c>enif_raise_exception</c>, the runtime ensures that the exception it creates
+ is raised when the NIF returns, even if the NIF attempts to return a non-exception
+ term instead. The return value from <c>enif_raise_exception</c> may be used only as
+ the return value from the NIF that invoked it (directly or indirectly) or be passed
+ to <seealso marker="#enif_is_exception">enif_is_exception</seealso>, but
+ not to any other NIF API function.</p>
+ <p>See also: <seealso marker="#enif_has_pending_exception">enif_has_pending_exception</seealso>
+ and <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>.</p></desc>
+ </func>
<func><name><ret>int</ret><nametext>enif_realloc_binary(ErlNifBinary* bin, size_t size)</nametext></name>
- <fsummary>Change the size of a binary.</fsummary>
+ <fsummary>Change the size of a binary</fsummary>
<desc><p>Change the size of a binary <c>bin</c>. The source binary
may be read-only, in which case it will be left untouched and
a mutable copy is allocated and assigned to <c>*bin</c>. Return true on success,
false if memory allocation failed.</p></desc>
</func>
<func><name><ret>void</ret><nametext>enif_release_binary(ErlNifBinary* bin)</nametext></name>
- <fsummary>Release a binary.</fsummary>
+ <fsummary>Release a binary</fsummary>
<desc><p>Release a binary obtained from <c>enif_alloc_binary</c>.</p></desc>
</func>
<func><name><ret>void</ret><nametext>enif_release_resource(void* obj)</nametext></name>
- <fsummary>Release a resource object.</fsummary>
+ <fsummary>Release a resource object</fsummary>
<desc><p>Remove a reference to resource object <c>obj</c>obtained from
<seealso marker="#enif_alloc_resource">enif_alloc_resource</seealso>.
The resource object will be destructed when the last reference is removed.
@@ -1256,12 +1390,12 @@ typedef enum {
</desc>
</func>
<func><name><ret>ErlNifPid *</ret><nametext>enif_self(ErlNifEnv* caller_env, ErlNifPid* pid)</nametext></name>
- <fsummary>Get the pid of the calling process.</fsummary>
+ <fsummary>Get the pid of the calling process</fsummary>
<desc><p>Initialize the pid variable <c>*pid</c> to represent the
calling process. Return <c>pid</c>.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_send(ErlNifEnv* env, ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg)</nametext></name>
- <fsummary>Send a message to a process.</fsummary>
+ <fsummary>Send a message to a process</fsummary>
<desc><p>Send a message to a process.</p>
<taglist>
<tag><c>env</c></tag>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 6ca57566aa..50a26781c4 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -539,55 +539,94 @@
<name name="cancel_timer" arity="2"/>
<fsummary>Cancel a timer</fsummary>
<desc>
- <p>Cancels a timer. <c><anno>TimerRef</anno></c> needs to refer to
- a timer that was created by either
- <seealso marker="#send_after/4"><c>erlang:send_after()</c></seealso>,
- or <seealso marker="#start_timer/4"><c>erlang:start_timer()</c></seealso>.</p>
- <p>Currently available <c><anno>Option</anno>s</c>:</p>
+ <p>
+ Cancels a timer that has been created by either
+ <seealso marker="#start_timer/4"><c>erlang:start_timer()</c></seealso>,
+ or <seealso marker="#send_after/4"><c>erlang:send_after()</c></seealso>.
+ <c><anno>TimerRef</anno></c> identifies the timer, and
+ was returned by the BIF that created the timer.
+ </p>
+ <p>Currently available <c><anno>Option</anno></c>s:</p>
<taglist>
<tag><c>{async, Async}</c></tag>
<item>
- <p>Asynchronous request for cancellation. <c>Async</c>
- defaults to <c>false</c>. That is the operation will be
- performed synchronously. When <c>Async</c> is set to
- <c>true</c> the cancel operation will be performed
- asynchronously. That is, <c>cancel_timer()</c> will send
- a request for cancellation to the timer service that
- manages the timer, and then return <c>ok</c>.</p></item>
+ <p>
+ Asynchronous request for cancellation. <c>Async</c>
+ defaults to <c>false</c> which will cause the
+ cancellation to be performed synchronously. When
+ <c>Async</c> is set to <c>true</c>, the cancel
+ operation will be performed asynchronously. That is,
+ <c>erlang:cancel_timer()</c> will send an asynchronous
+ request for cancellation to the timer service that
+ manages the timer, and then return <c>ok</c>.
+ </p>
+ </item>
<tag><c>{info, Info}</c></tag>
<item>
- <p>Request information about the <c>Result</c> of the
- cancellation. <c>Info</c> defaults to <c>true</c>. That
- is information will be given. When <c>Info</c> is set to
- <c>false</c> no information about the result of the cancel
- operation will be given. When the operation is performed
- synchronously the <c>Result</c> will returned from
- <c>cancel_timer()</c>. When the operation is performed
- asynchronously, a message on the form
- <c>{cancel_timer, <anno>TimerRef</anno>, <anno>Result</anno>}</c>
- will be sent to the caller of <c>cancel_timer()</c> when
- the operation has been performed.</p></item>
+ <p>
+ Request information about the <c><anno>Result</anno></c>
+ of the cancellation. <c>Info</c> defaults to <c>true</c>
+ which means that the <c><anno>Result</anno></c> will
+ be given. When <c>Info</c> is set to <c>false</c>, no
+ information about the result of the cancellation
+ will be given. When the operation is performed</p>
+ <taglist>
+ <tag>synchronously</tag>
+ <item>
+ <p>
+ If <c>Info</c> is <c>true</c>, the <c>Result</c> will
+ returned by <c>erlang:cancel_timer()</c>; otherwise,
+ <c>ok</c> will be returned.
+ </p>
+ </item>
+ <tag>asynchronously</tag>
+ <item>
+ <p>
+ If <c>Info</c> is <c>true</c>, a message on the form
+ <c>{cancel_timer, <anno>TimerRef</anno>,
+ <anno>Result</anno>}</c> will be sent to the
+ caller of <c>erlang:cancel_timer()</c> when the
+ cancellation operation has been performed; otherwise,
+ no message will be sent.
+ </p>
+ </item>
+ </taglist>
+ </item>
</taglist>
- <p>When the <c><anno>Result</anno></c> equals <c>false</c> a timer
- corresponding to <c><anno>TimerRef</anno></c> could not be found. This
- can be either because the timer had expired, been canceled, or because
- <c><anno>TimerRef</anno></c> do not correspond to a timer. When the
- <c><anno>Result</anno></c> is an integer, it represents
- the time in milli seconds left before the timer will expire.</p>
- <note><p>The timer service that manages the timer may be co-located
- with another scheduler than the scheduler that the calling process
- is executing on. In this case communication with the timer
- service will be performed using asynchronous signals. If the calling
- process is in critical path and can do other things while waiting
- for the result of this operation, you want to use the <c>{async, true}</c>
- option.</p></note>
+ <p>
+ More <c><anno>Option</anno></c>s may be added in the future.
+ </p>
+ <p>
+ When the <c><anno>Result</anno></c> equals <c>false</c>, a
+ timer corresponding to <c><anno>TimerRef</anno></c> could not
+ be found. This can be either because the timer had expired,
+ already had been canceled, or because <c><anno>TimerRef</anno></c>
+ never has corresponded to a timer. If the timer has expired,
+ the timeout message has been sent, but it does not tell you
+ whether or not it has arrived at its destination yet. When the
+ <c><anno>Result</anno></c> is an integer, it represents the
+ time in milli-seconds left until the timer will expire.
+ </p>
+ <note>
+ <p>
+ The timer service that manages the timer may be co-located
+ with another scheduler than the scheduler that the calling
+ process is executing on. If this is the case, communication
+ with the timer service will take much longer time than if it
+ is located locally. If the calling process is in critical
+ path, and can do other things while waiting for the result
+ of this operation, or is not interested in the result of
+ the operation, you want to use the <c>{async, true}</c>
+ option. If using the <c>{async, false}</c> option, the calling
+ process will be blocked until the operation has been
+ performed.
+ </p>
+ </note>
<p>See also
<seealso marker="#send_after/4"><c>erlang:send_after/4</c></seealso>,
<seealso marker="#start_timer/4"><c>erlang:start_timer/4</c></seealso>,
and
<seealso marker="#read_timer/2"><c>erlang:read_timer/2</c></seealso>.</p>
- <p>Note: Cancelling a timer does not guarantee that the message
- has not already been delivered to the message queue.</p>
</desc>
</func>
<func>
@@ -596,7 +635,7 @@
<desc>
<p>Cancels a timer. The same as calling
<seealso marker="#cancel_timer/2"><c>erlang:cancel_timer(TimerRef,
- [{async, false}, {info, true}])</c></seealso>.</p>
+ [])</c></seealso>.</p>
</desc>
</func>
<func>
@@ -4548,37 +4587,60 @@ os_prompt% </pre>
<name name="read_timer" arity="2"/>
<fsummary>Read the state of a timer</fsummary>
<desc>
- <p>Read the state of a timer. <c><anno>TimerRef</anno></c>
- needs to refer to a timer that was created by either
- <seealso marker="#send_after/4"><c>erlang:send_after()</c></seealso>,
- or <seealso marker="#start_timer/4"><c>erlang:start_timer()</c></seealso>.</p>
+ <p>
+ Read the state of a timer that has been created by either
+ <seealso marker="#start_timer/4"><c>erlang:start_timer()</c></seealso>,
+ or <seealso marker="#send_after/4"><c>erlang:send_after()</c></seealso>.
+ <c><anno>TimerRef</anno></c> identifies the timer, and
+ was returned by the BIF that created the timer.
+ </p>
<p>Currently available <c><anno>Option</anno>s</c>:</p>
<taglist>
<tag><c>{async, Async}</c></tag>
<item>
- <p>Asynchronous request. <c>Async</c> defaults to <c>false</c>. That
- is the operation will be performed synchronously, and the <c>Result</c>
- will returned from <c>read_timer()</c>. When <c>Async</c> is set to
- <c>true</c>, <c>read_timer()</c> will send a request for the
- <c>Result</c> to a timer service that manages the timer and then
- return <c>ok</c>. A message on the format
- <c>{read_timer, <anno>TimerRef</anno>, <anno>Result</anno>}</c>
- will be sent to the caller of <c>read_timer()</c> when
- the operation has been processed.</p></item>
+ <p>
+ Asynchronous request for state information. <c>Async</c>
+ defaults to <c>false</c> which will cause the operation
+ to be performed synchronously. In this case, the <c>Result</c>
+ will be returned by <c>erlang:read_timer()</c>. When
+ <c>Async</c> is set to <c>true</c>, <c>erlang:read_timer()</c>
+ will send an asynchronous request for the state information
+ to the timer service that manages the timer, and then return
+ <c>ok</c>. A message on the format <c>{read_timer,
+ <anno>TimerRef</anno>, <anno>Result</anno>}</c> will be
+ sent to the caller of <c>erlang:read_timer()</c> when the
+ operation has been processed.
+ </p>
+ </item>
</taglist>
- <p>When the <c><anno>Result</anno></c> equals <c>false</c> a timer
- corresponding to <c><anno>TimerRef</anno></c> could not be found. This
- can be either because the timer had expired, been canceled, or because
- <c><anno>TimerRef</anno></c> do not correspond to a timer. When the
- <c><anno>Result</anno></c> is an integer, it represents
- the time in milli seconds left before the timer will expire.</p>
- <note><p>The timer service that manages the timer may be co-located
- with another scheduler than the scheduler that the calling process
- is executing on. In this case communication with the timer
- service will be performed using asynchronous signals. If the calling
- process is in critical path and can do other things while waiting
- for the result of this operation, you want to use the <c>{async, true}</c>
- option.</p></note>
+ <p>
+ More <c><anno>Option</anno></c>s may be added in the future.
+ </p>
+ <p>
+ When the <c><anno>Result</anno></c> equals <c>false</c>, a
+ timer corresponding to <c><anno>TimerRef</anno></c> could not
+ be found. This can be either because the timer had expired,
+ had been canceled, or because <c><anno>TimerRef</anno></c>
+ never has corresponded to a timer. If the timer has expired,
+ the timeout message has been sent, but it does not tell you
+ whether or not it has arrived at its destination yet. When the
+ <c><anno>Result</anno></c> is an integer, it represents the
+ time in milli-seconds left until the timer will expire.
+ </p>
+ <note>
+ <p>
+ The timer service that manages the timer may be co-located
+ with another scheduler than the scheduler that the calling
+ process is executing on. If this is the case, communication
+ with the timer service will take much longer time than if it
+ is located locally. If the calling process is in critical
+ path, and can do other things while waiting for the result
+ of this operation you want to use the <c>{async, true}</c>
+ option. If using the <c>{async, false}</c> option, the calling
+ process will be blocked until the operation has been
+ performed.
+ </p>
+ </note>
<p>See also
<seealso marker="#send_after/4"><c>erlang:send_after/4</c></seealso>,
<seealso marker="#start_timer/4"><c>erlang:start_timer/4</c></seealso>,
@@ -4592,7 +4654,7 @@ os_prompt% </pre>
<desc>
<p>Read the state of a timer. The same as calling
<seealso marker="#read_timer/2"><c>erlang:read_timer(TimerRef,
- [{async, false}])</c></seealso>.</p>
+ [])</c></seealso>.</p>
</desc>
</func>
<func>
@@ -4744,48 +4806,14 @@ true</pre>
<name name="send_after" arity="4"/>
<fsummary>Start a timer</fsummary>
<desc>
- <p>Starts a timer. When the timer expires, the message
- <c><anno>Msg</anno></c> will be sent to
- <c><anno>Dest</anno></c>.</p>
- <p>If <c><anno>Dest</anno></c> is a <c>pid()</c> it has to
- be a <c>pid()</c> of a local process, dead or alive.</p>
- <p>Currently available <c><anno>Option</anno>s</c>:</p>
- <taglist>
- <tag><c>{abs, Abs}</c></tag>
- <item>
- <p>Absolute timeout. When <c>Abs</c> is <c>false</c>
- the <c><anno>Time</anno></c> value will be interpreted
- as a time in milli-seconds relative current
- <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
- monotonic time</seealso>. When <c>Abs</c> is <c>true</c> the
- <c><anno>Time</anno></c> value will be interpreted as an absolute
- Erlang monotonic time of milli second time unit. <c>Abs</c>
- defaults to <c>false</c>.</p>
- </item>
- </taglist>
- <p>The absolute time when the timer is set to expire needs
- to be in the range between
- <seealso marker="#system_info_start_time"><c>erlang:system_info(start_time)</c></seealso>
- and
- <seealso marker="#system_info_end_time"><c>erlang:system_info(end_time)</c></seealso>.
- If a negative relative time is specified the time is not
- allowed to be negative.</p>
- <p>If <c><anno>Dest</anno></c> is an <c>atom()</c>, it is supposed to be the name of
- a registered process. The process referred to by the name is
- looked up at the time of delivery. No error is given if
- the name does not refer to a process.</p>
- <p>If <c><anno>Dest</anno></c> is a <c>pid()</c>, the timer will be automatically
- canceled if the process referred to by the <c>pid()</c> is not alive,
- or when the process exits. This feature was introduced in
- erts version 5.4.11. Note that timers will not be
- automatically canceled when <c><anno>Dest</anno></c> is an <c>atom()</c>.</p>
- <p>See also
- <seealso marker="#start_timer/4"><c>erlang:send_timer/4</c></seealso>,
- <seealso marker="#cancel_timer/2"><c>erlang:cancel_timer/2</c></seealso>,
- and
- <seealso marker="#read_timer/2"><c>erlang:read_timer/2</c></seealso>.</p>
- <p>Failure: <c>badarg</c> if the arguments does not satisfy
- the requirements specified above.</p>
+ <p>
+ Starts a timer. When the timer expires, the message
+ <c><anno>Msg</anno></c> will be sent to the process
+ identified by <c><anno>Dest</anno></c>. Appart from
+ the format of the message sent to
+ <c><anno>Dest</anno></c> when the timer expires
+ <c>erlang:send_after/4</c> works exactly as
+ <seealso marker="#start_timer/4"><c>erlang:start_timer/4</c></seealso>.</p>
</desc>
</func>
<func>
@@ -4793,36 +4821,8 @@ true</pre>
<fsummary>Start a timer</fsummary>
<desc>
<p>Starts a timer. The same as calling
- <seealso marker="#send_timer/4"><c>erlang:send_after(<anno>Time</anno>,
- <anno>Dest</anno>, <anno>Msg</anno>, [{abs, false}])</c></seealso>.</p>
- </desc>
- </func>
- <func>
- <name name="send_after" arity="3"/>
- <type_desc variable="Time">0 &lt;= Time &lt;= 4294967295</type_desc>
- <fsummary>Start a timer</fsummary>
- <desc>
- <p>Starts a timer which will send the message <c>Msg</c>
- to <c><anno>Dest</anno></c> after <c><anno>Time</anno></c> milliseconds.</p>
- <p>If <c><anno>Dest</anno></c> is a <c>pid()</c> it has to be a <c>pid()</c> of a local process, dead or alive.</p>
- <p>The <c><anno>Time</anno></c> value can, in the current implementation, not be greater than 4294967295.</p>
- <p>If <c><anno>Dest</anno></c> is an <c>atom()</c>, it is supposed to be the name of
- a registered process. The process referred to by the name is
- looked up at the time of delivery. No error is given if
- the name does not refer to a process.</p>
-
- <p>If <c><anno>Dest</anno></c> is a <c>pid()</c>, the timer will be automatically
- canceled if the process referred to by the <c>pid()</c> is not alive,
- or when the process exits. This feature was introduced in
- erts version 5.4.11. Note that timers will not be
- automatically canceled when <c><anno>Dest</anno></c> is an <c>atom</c>.</p>
- <p>See also
- <seealso marker="#start_timer/3">erlang:start_timer/3</seealso>,
- <seealso marker="#cancel_timer/2">erlang:cancel_timer/2</seealso>,
- and
- <seealso marker="#read_timer/2">erlang:read_timer/2</seealso>.</p>
- <p>Failure: <c>badarg</c> if the arguments does not satisfy
- the requirements specified above.</p>
+ <seealso marker="#send_after/4"><c>erlang:send_after(<anno>Time</anno>,
+ <anno>Dest</anno>, <anno>Msg</anno>, [])</c></seealso>.</p>
</desc>
</func>
<func>
@@ -5231,41 +5231,59 @@ true</pre>
<name name="start_timer" arity="4"/>
<fsummary>Start a timer</fsummary>
<desc>
- <p>Starts a timer. When the timer expires, the message
+ <p>
+ Starts a timer. When the timer expires, the message
<c>{timeout, <anno>TimerRef</anno>, <anno>Msg</anno>}</c>
- will be sent to <c><anno>Dest</anno></c>.</p>
- <p>If <c><anno>Dest</anno></c> is a <c>pid()</c> it has to
- be a <c>pid()</c> of a local process, dead or alive.</p>
- <p>Currently available <c><anno>Option</anno>s</c>:</p>
+ will be sent to the process identified by
+ <c><anno>Dest</anno></c>.
+ </p>
+ <p>Currently available <c><anno>Option</anno></c>s:</p>
<taglist>
<tag><c>{abs, Abs}</c></tag>
<item>
- <p>Absolute timeout. When <c>Abs</c> is <c>false</c>
- the <c><anno>Time</anno></c> value will be interpreted
- as a time in milli-seconds relative current
- <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
- monotonic time</seealso>. When <c>Abs</c> is <c>true</c> the
- <c><anno>Time</anno></c> value will be interpreted as an absolute
- Erlang monotonic time of milli second time unit. <c>Abs</c>
- defaults to <c>false</c>.</p>
+ <p>
+ Absolute <c><anno>Time</anno></c> value. <c>Abs</c>
+ defaults to <c>false</c> which means that the
+ <c><anno>Time</anno></c> value will be interpreted
+ as a time in milli-seconds relative current
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso>. When <c>Abs</c> is set to
+ <c>true</c>, the <c><anno>Time</anno></c> value will
+ be interpreted as an absolute Erlang monotonic time of
+ milli-seconds
+ <seealso marker="#type_time_unit">time unit</seealso>.
+ </p>
</item>
</taglist>
- <p>The absolute time when the timer is set to expire needs
- to be in the range between
- <seealso marker="#system_info_start_time"><c>erlang:system_info(start_time)</c></seealso>
- and
- <seealso marker="#system_info_end_time"><c>erlang:system_info(end_time)</c></seealso>.
- If a negative relative time is specified the time is not
- allowed to be negative.</p>
- <p>If <c><anno>Dest</anno></c> is an <c>atom()</c>, it is supposed to be the name of
- a registered process. The process referred to by the name is
- looked up at the time of delivery. No error is given if
- the name does not refer to a process.</p>
- <p>If <c><anno>Dest</anno></c> is a <c>pid()</c>, the timer will be automatically
- canceled if the process referred to by the <c>pid()</c> is not alive,
- or when the process exits. This feature was introduced in
- erts version 5.4.11. Note that timers will not be
- automatically canceled when <c><anno>Dest</anno></c> is an <c>atom()</c>.</p>
+ <p>
+ More <c><anno>Option</anno></c>s may be added in the future.
+ </p>
+ <p>
+ The absolute point in time that the timer is set to expire on
+ has to be in the interval
+ <c>[</c><seealso marker="#system_info_start_time"><c>erlang:system_info(start_time)</c></seealso><c>,
+ </c><seealso marker="#system_info_end_time"><c>erlang:system_info(end_time)</c></seealso><c>]</c>.
+ Further, if a relative time is specified, the <c><anno>Time</anno></c> value
+ is not allowed to be negative.
+ </p>
+ <p>
+ If <c><anno>Dest</anno></c> is a <c>pid()</c>, it has to
+ be a <c>pid()</c> of a process created on the current
+ runtime system instance. This process may or may not
+ have terminated. If <c><anno>Dest</anno></c> is an
+ <c>atom()</c>, it will be interpreted as the name of a
+ locally registered process. The process referred to by the
+ name is looked up at the time of timer expiration. No error
+ is given if the name does not refer to a process.
+ </p>
+ <p>
+ If <c><anno>Dest</anno></c> is a <c>pid()</c>, the timer will
+ be automatically canceled if the process referred to by the
+ <c>pid()</c> is not alive, or when the process exits. This
+ feature was introduced in erts version 5.4.11. Note that
+ timers will not be automatically canceled when
+ <c><anno>Dest</anno></c> is an <c>atom()</c>.
+ </p>
<p>See also
<seealso marker="#send_after/4"><c>erlang:send_after/4</c></seealso>,
<seealso marker="#cancel_timer/2"><c>erlang:cancel_timer/2</c></seealso>,
@@ -5281,7 +5299,7 @@ true</pre>
<desc>
<p>Starts a timer. The same as calling
<seealso marker="#start_timer/4"><c>erlang:start_timer(<anno>Time</anno>,
- <anno>Dest</anno>, <anno>Msg</anno>, [{abs, false}])</c></seealso>.</p>
+ <anno>Dest</anno>, <anno>Msg</anno>, [])</c></seealso>.</p>
</desc>
</func>
<func>
@@ -6204,6 +6222,7 @@ ok
<name name="system_info" arity="1" clause_i="64"/>
<name name="system_info" arity="1" clause_i="65"/>
<name name="system_info" arity="1" clause_i="66"/>
+ <name name="system_info" arity="1" clause_i="67"/>
<fsummary>Information about the system</fsummary>
<desc>
<p>Returns various information about the current system
@@ -6273,6 +6292,15 @@ ok
compiled; otherwise, <c>false</c>.
</p>
</item>
+ <tag><marker id="system_info_delayed_node_table_gc"><c>delayed_node_table_gc</c></marker></tag>
+ <item>
+ <p>Returns the amount of time in seconds that garbage collection
+ of an entry in a node table will be delayed. This limit can be set
+ on startup by passing the
+ <seealso marker="erts:erl#+zdntgc">+zdntgc</seealso> command line
+ flag to <c>erl</c>. For more information see the documentation of the
+ command line flag.</p>
+ </item>
<tag><marker id="system_info_dirty_cpu_schedulers"><c>dirty_cpu_schedulers</c></marker></tag>
<item>
<p>Returns the number of dirty CPU scheduler threads used by
@@ -6845,7 +6873,9 @@ ok
<item><p>The <seealso marker="#monotonic_time/0">Erlang monotonic
time</seealso> in <c>native</c>
<seealso marker="#type_time_unit">time unit</seealso> at the
- time when current Erlang runtime system instance started.</p></item>
+ time when current Erlang runtime system instance started. See also
+ <seealso marker="#system_info_end_time"><c>erlang:system_info(end_time)</c></seealso>.
+ </p></item>
<tag><c>system_version</c></tag>
<item>
<p>Returns a string containing version number and
diff --git a/erts/doc/src/init.xml b/erts/doc/src/init.xml
index 09b5493341..c5a1a92b92 100644
--- a/erts/doc/src/init.xml
+++ b/erts/doc/src/init.xml
@@ -248,7 +248,7 @@
evaluation), Erlang stops with an error message. Here is an
example that seeds the random number generator:</p>
<pre>
-% <input>erl -eval '{X,Y,Z}' = now(), random:seed(X,Y,Z).'</input></pre>
+% <input>erl -eval '{X,Y,Z} = now(), random:seed(X,Y,Z).'</input></pre>
<p>This example uses Erlang as a hexadecimal calculator:</p>
<pre>
% <input>erl -noshell -eval 'R = 16#1F+16#A0, io:format("~.16B~n", [R])' \\</input>