diff options
Diffstat (limited to 'erts/doc')
34 files changed, 6879 insertions, 1170 deletions
diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile index 3cc29e14b1..bc01919da1 100644 --- a/erts/doc/src/Makefile +++ b/erts/doc/src/Makefile @@ -52,21 +52,37 @@ XML_REF3_EFILES = \ erlang.xml \ erl_tracer.xml \ init.xml \ - zlib.xml + persistent_term.xml \ + atomics.xml \ + counters.xml \ + zlib.xml \ + socket.xml \ + net.xml XML_REF3_FILES = \ + $(XML_REF3_EFILES) \ driver_entry.xml \ erl_nif.xml \ - erl_tracer.xml \ erl_driver.xml \ - erl_prim_loader.xml \ - erlang.xml \ - erts_alloc.xml \ - init.xml \ - zlib.xml + erts_alloc.xml XML_PART_FILES = \ - part.xml + part.xml internal.xml + +XML_INTERNAL_FILES = \ + CarrierMigration.xml \ + ThreadProgress.xml \ + CodeLoading.xml \ + Tracing.xml \ + DelayedDealloc.xml \ + beam_makeops.xml \ + GarbageCollection.xml \ + PTables.xml \ + PortSignals.xml \ + ProcessManagementOptimizations.xml \ + SuperCarrier.xml \ + CountingInstructions.xml + XML_CHAPTER_FILES = \ introduction.xml \ @@ -78,6 +94,7 @@ XML_CHAPTER_FILES = \ driver.xml \ absform.xml \ inet_cfg.xml \ + socket_usage.xml \ erl_ext_dist.xml \ erl_dist_protocol.xml \ communication.xml \ @@ -95,6 +112,8 @@ XML_FILES = \ $(BOOK_FILES) $(XML_CHAPTER_FILES) \ $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_REF1_FILES) $(XML_APPLICATION_FILES) +XML_GEN_FILES = $(XML_INTERNAL_FILES:%=$(XMLDIR)/%) + # ---------------------------------------------------- HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \ @@ -114,6 +133,12 @@ SPECS_FILES = $(XML_REF3_EFILES:%.xml=$(SPECDIR)/specs_%.xml) TOP_SPECS_FILE = specs.xml +XML_FIGURE_DIR = $(XMLDIR)/figures + +INTERNAL_DOC_PNG_FILES = $(wildcard ../../emulator/internal_doc/figures/*.png) +PNG_FILES = $(notdir $(INTERNAL_DOC_PNG_FILES)) +XMLDIR_PNG_FILES = $(PNG_FILES:%=$(XML_FIGURE_DIR)/%) + # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- @@ -126,10 +151,15 @@ SPECS_FLAGS = -I$(KERNEL_SRC) -I$(KERNEL_INCLUDE) # ---------------------------------------------------- # Targets # ---------------------------------------------------- +_create_dirs := $(shell mkdir -p $(XML_FIGURE_DIR)) + $(HTMLDIR)/%.gif: %.gif $(INSTALL_DATA) $< $@ -docs: man pdf html $(INFO_FILE) +$(XML_FIGURE_DIR)/%.png: ../../emulator/internal_doc/figures/%.png + $(INSTALL_DATA) $< $@ + +docs: figures man pdf html $(INFO_FILE) $(TOP_PDF_FILE): $(XML_FILES) @@ -144,11 +174,15 @@ gifs: $(GIF_FILES:%=$(HTMLDIR)/%) $(INFO_FILE): $(INFO_FILE_SRC) $(ERL_TOP)/make/$(TARGET)/otp.mk sed -e 's;%RELEASE%;$(SYSTEM_VSN);' $(INFO_FILE_SRC) > $(INFO_FILE) +figures: $(XMLDIR_PNG_FILES) debug opt: +ldocs: xmllint local_docs + clean: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN1DIR)/* rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) @@ -159,6 +193,9 @@ $(SPECDIR)/specs_%.xml: $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ -o$(dir $@) -module $(patsubst $(SPECDIR)/specs_%.xml,%,$@) +$(XMLDIR)/%.xml: ../../emulator/internal_doc/%.md $(ERL_TOP)/make/emd2exml + $(ERL_TOP)/make/emd2exml $< $@ + # ---------------------------------------------------- # Release Target # ---------------------------------------------------- @@ -168,8 +205,11 @@ release_docs_spec: docs $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html/figures" $(INSTALL_DATA) $(HTMLDIR)/* \ "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(XMLDIR)/figures/* \ + "$(RELSYSDIR)/doc/html/figures" $(INSTALL_DATA) $(ERL_TOP)/erts/example/time_compat.erl \ "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(ERL_TOP)/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl \ diff --git a/erts/doc/src/absform.xml b/erts/doc/src/absform.xml index 158f4dc4e8..d77d989057 100644 --- a/erts/doc/src/absform.xml +++ b/erts/doc/src/absform.xml @@ -801,7 +801,8 @@ <c>{ann_type,LINE,[Rep(A),Rep(T_0)]}</c>.</p> </item> <item> - <p>If T is an atom or integer literal L, then Rep(T) = Rep(L).</p> + <p>If T is an atom, a character, or an integer literal L, + then Rep(T) = Rep(L).</p> </item> <item> <p>If T is a bitstring type <c><<_:M,_:_*N>></c>, @@ -810,7 +811,9 @@ </item> <item> <p>If T is the empty list type <c>[]</c>, then Rep(T) = - <c>{type,Line,nil,[]}</c>.</p> + <c>{type,Line,nil,[]}</c>, that is, the empty list type + <c>[]</c> cannot be distinguished from the predefined type + <c>nil()</c>.</p> </item> <item> <p>If T is a fun type <c>fun()</c>, then Rep(T) = diff --git a/erts/doc/src/alt_disco.xml b/erts/doc/src/alt_disco.xml index d04221b9b3..148d6f549e 100644 --- a/erts/doc/src/alt_disco.xml +++ b/erts/doc/src/alt_disco.xml @@ -63,7 +63,7 @@ <seealso marker="kernel:erl_epmd">EPMD module</seealso>. However, instead of communicating with EPMD you can connect to any service to find out connection details of other nodes. A discovery module is enabled - by setting <seealso marker="erts:erl#epmd_module">-epmd_module</seealso> + by setting <seealso marker="erts:erl">-epmd_module</seealso> when starting erlang. The discovery module must implement the following callbacks:</p> diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml index e6245130fc..f72e8acd2c 100644 --- a/erts/doc/src/alt_dist.xml +++ b/erts/doc/src/alt_dist.xml @@ -60,7 +60,7 @@ parts of the logic in Erlang code, and you perhaps do not even need a new driver for the protocol. One example could be Erlang distribution over UDP using <c>gen_udp</c> (your - Erlang code will of course have to take care of retranspissions, + Erlang code will of course have to take care of retransmissions, etc in this example). That is, depending on what you want to do you perhaps do not need to implement a driver at all and can then skip the driver related sections below. @@ -680,7 +680,10 @@ of the distribution controller, <c>Received</c> is received packets, <c>Sent</c> is sent packets, and <c>PendSend</c> is - amount of packets in queue to be sent + amount of data in queue to be sent + (typically in bytes, but <c>dist_util</c> + only checks whether the value is non-zero + to know there is data in queue) or a <c>boolean()</c> indicating whether there are packets in queue to be sent. </p> diff --git a/erts/doc/src/atomics.xml b/erts/doc/src/atomics.xml new file mode 100644 index 0000000000..455973f011 --- /dev/null +++ b/erts/doc/src/atomics.xml @@ -0,0 +1,185 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2018</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + </legalnotice> + + <title>atomics</title> + </header> + <module since="OTP 21.2">atomics</module> + <modulesummary>Atomic Functions</modulesummary> + <description> + <p>This module provides a set of functions to do atomic operations towards + mutable atomic variables. The implementation utilizes only + atomic hardware instructions without any software level locking, which makes + it very efficient for concurrent access. The atomics are organized into + arrays with the following semantics:</p> + <list type="bulleted"> + <item> + <p>Atomics are 64 bit integers.</p> + </item> + <item> + <p>Atomics can be represented as either signed or unsigned.</p> + </item> + <item> + <p>Atomics wrap around at overflow and underflow operations.</p> + </item> + <item> + <p>All operations guarantee atomicity. No intermediate results can be + seen. The result of one mutation can only be the input to one + following mutation.</p> + </item> + <item> + <p>All atomic operations are mutually ordered. If atomic B is updated + <em>after</em> atomic A, then that is how it will appear to any + concurrent readers. No one can read the new value of B and then read the + old value of A.</p> + </item> + <item> + <p>Indexes into atomic arrays are one-based. An atomic array of + arity N contains N atomics with index from 1 to N.</p> + </item> + </list> + </description> + + <datatypes> + <datatype> + <name name="atomics_ref"/> + <desc><p>Identifies an atomic array returned from + <seealso marker="#new/2"><c>new/2</c></seealso>.</p> + </desc> + </datatype> + </datatypes> + + <funcs> + <func> + <name name="new" arity="2" since="OTP 21.2"/> + <fsummary>Create atomic array</fsummary> + <desc> + <p>Create a new atomic array of <c><anno>Arity</anno></c> atomics.</p> + <p>Argument <c><anno>Opts</anno></c> is a list of the following possible + options:</p> + <taglist> + <tag><c>{signed, boolean()}</c></tag> + <item><p>Indicate if the elements of the array will be treated + as signed or unsigned integers. Default is <c>true</c> (signed).</p> + <p>The integer interval for signed atomics are from <c>-(1 bsl 63)</c> + to <c>(1 bsl 63)-1</c> and for unsigned atomics from <c>0</c> to <c>(1 + bsl 64)-1</c>.</p> + </item> + </taglist> + <p>Atomics are not tied to the current process and are automatically + garbage collected when they are no longer referenced.</p> + </desc> + </func> + + <func> + <name name="put" arity="3" since="OTP 21.2"/> + <fsummary>Set atomic value</fsummary> + <desc> + <p>Set atomic to <c><anno>Value</anno></c>.</p> + </desc> + </func> + + <func> + <name name="get" arity="2" since="OTP 21.2"/> + <fsummary>Read atomic value</fsummary> + <desc> + <p>Read atomic value.</p> + </desc> + </func> + + <func> + <name name="add" arity="3" since="OTP 21.2"/> + <fsummary>Add to atomic</fsummary> + <desc> + <p>Add <c><anno>Incr</anno></c> to atomic.</p> + </desc> + </func> + + <func> + <name name="add_get" arity="3" since="OTP 21.2"/> + <fsummary>Atomic add and get</fsummary> + <desc> + <p>Atomic addition and return of the result.</p> + </desc> + </func> + + <func> + <name name="sub" arity="3" since="OTP 21.2"/> + <fsummary>Subtract from atomic</fsummary> + <desc> + <p>Subtract <c><anno>Decr</anno></c> from atomic.</p> + </desc> + </func> + + <func> + <name name="sub_get" arity="3" since="OTP 21.2"/> + <fsummary>Atomic sub and get</fsummary> + <desc> + <p>Atomic subtraction and return of the result.</p> + </desc> + </func> + + <func> + <name name="exchange" arity="3" since="OTP 21.2"/> + <fsummary>Atomic exchange.</fsummary> + <desc> + <p>Atomically replaces the value of the atomic with + <c><anno>Desired</anno></c> and returns the value it held + previously.</p> + </desc> + </func> + + <func> + <name name="compare_exchange" arity="4" since="OTP 21.2"/> + <fsummary>Atomic compare and exchange.</fsummary> + <desc> + <p>Atomically compares the atomic with <c><anno>Expected</anno></c>, + and if those are equal, set atomic to <c><anno>Desired</anno></c>. + Returns <c>ok</c> if <c><anno>Desired</anno></c> was written. Returns + the actual atomic value if not equal to <c><anno>Expected</anno></c>.</p> + </desc> + </func> + + <func> + <name name="info" arity="1" since="OTP 21.2"/> + <fsummary>Get information about atomic array.</fsummary> + <desc> + <p>Return information about an atomic array in a map. The map + has the following keys:</p> + <taglist> + <tag><c>size</c></tag> + <item><p>The number of atomics in the array.</p></item> + <tag><c>max</c></tag> + <item><p>The highest possible value an atomic in this array can + hold.</p></item> + <tag><c>min</c></tag> + <item><p>The lowest possible value an atomic in this array can + hold.</p></item> + <tag><c>memory</c></tag> + <item><p>Approximate memory consumption for the array in + bytes.</p></item> + </taglist> + </desc> + </func> + + </funcs> +</erlref> diff --git a/erts/doc/src/book.xml b/erts/doc/src/book.xml index a0780c91d9..d79da1e4f7 100644 --- a/erts/doc/src/book.xml +++ b/erts/doc/src/book.xml @@ -41,6 +41,9 @@ <applications> <xi:include href="ref_man.xml"/> </applications> + <internals> + <xi:include href="internal.xml"/> + </internals> <releasenotes> <xi:include href="notes.xml"/> </releasenotes> diff --git a/erts/doc/src/communication.xml b/erts/doc/src/communication.xml index 7e18a73aa8..251b52dc65 100644 --- a/erts/doc/src/communication.xml +++ b/erts/doc/src/communication.xml @@ -64,7 +64,7 @@ a synchronous communication operation consists of two asynchronous signals; one request signal and one reply signal. An example of such a synchronous communication is a call to - <seealso marker="erlang:process_info/2"> + <seealso marker="erlang#process_info/2"> <c>erlang:process_info/2</c></seealso> when the first argument is not <c>self()</c>. The caller sends an asynchronous signal requesting information, and then diff --git a/erts/doc/src/counters.xml b/erts/doc/src/counters.xml new file mode 100644 index 0000000000..36816bd68d --- /dev/null +++ b/erts/doc/src/counters.xml @@ -0,0 +1,172 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2018</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + </legalnotice> + + <title>counters</title> + </header> + <module since="OTP 21.2">counters</module> + <modulesummary>Counter Functions</modulesummary> + <description> + <p>This module provides a set of functions to do operations towards + shared mutable counter variables. The implementation does not utilize any + software level locking, which makes it very efficient for concurrent + access. The counters are organized into arrays with the following + semantics:</p> + <list type="bulleted"> + <item> + <p>Counters are 64 bit signed integers.</p> + </item> + <item> + <p>Counters wrap around at overflow and underflow operations.</p> + </item> + <item><p>Counters are initialized to zero and can then only be written to + by adding or subtracting.</p> + </item> + <item> + <p>Write operations guarantee atomicity. No intermediate results can be + seen from a single write operation.</p> + </item> + <item> + <p>Two types of counter arrays can be created with options <c>atomics</c> or + <c>write_concurrency</c>. The <c>atomics</c> counters have good allround + performance with nice consistent semantics while + <c>write_concurrency</c> counters offers even better concurrent + write performance at the expense of some potential read + inconsistencies. See <seealso marker="#new/2"><c>new/2</c></seealso>.</p> + </item> + <item> + <p>Indexes into counter arrays are one-based. A counter array of + size N contains N counters with index from 1 to N.</p> + </item> + </list> + </description> + + <datatypes> + <datatype> + <name name="counters_ref"/> + <desc><p>Identifies a counter array returned from + <seealso marker="#new/2"><c>new/2</c></seealso>.</p> + </desc> + </datatype> + </datatypes> + + <funcs> + <func> + <name name="new" arity="2" since="OTP 21.2"/> + <fsummary>Create counter array</fsummary> + <desc> + <p>Create a new counter array of <c><anno>Size</anno></c> counters.</p> + <p>Argument <c><anno>Opts</anno></c> is a list of the following possible + options:</p> + <taglist> + <tag><c>atomics</c> (Default)</tag> + <item><p>Counters will be sequentially consistent. If write + operation A is done sequentially before write operation B, then a concurrent reader + may see none of them, only A, or both A and B. It cannot see only B.</p> + </item> + <tag><c>write_concurrency</c></tag> + <item><p>This is an optimization to achieve very efficient concurrent + <seealso marker="#add/3"><c>add</c></seealso> and <seealso + marker="#sub/3"><c>sub</c></seealso> operations at the expense of potential read + inconsistency and memory consumption per counter.</p> + <p>Read operations may see sequentially inconsistent results with + regard to concurrent write operations. Even if write operation A is done + sequentially before write operation B, a concurrent reader may see any + combination of A and B, including only B. A read operation is only + guaranteed to see all writes done sequentially before the read. No writes + are ever lost, but will eventually all be seen.</p> + <p>The typical use case for <c>write_concurrency</c> is when + concurrent calls to <seealso marker="#add/3"><c>add</c></seealso> and + <seealso marker="#sub/3"><c>sub</c></seealso> toward the same counters + are very frequent, while calls to <seealso marker="#get/2"><c>get</c> + </seealso> and <seealso marker="#put/3"><c>put</c></seealso> are much + less frequent. The lack of absolute read consistency must also be + acceptable.</p> + </item> + </taglist> + <p>Counters are not tied to the current process and are automatically + garbage collected when they are no longer referenced.</p> + </desc> + </func> + + <func> + <name name="get" arity="2" since="OTP 21.2"/> + <fsummary>Read counter value</fsummary> + <desc> + <p>Read counter value.</p> + </desc> + </func> + + <func> + <name name="add" arity="3" since="OTP 21.2"/> + <fsummary>Add to counter</fsummary> + <desc> + <p>Add <c><anno>Incr</anno></c> to counter at index + <c><anno>Ix</anno></c>.</p> + </desc> + </func> + + <func> + <name name="sub" arity="3" since="OTP 21.2"/> + <fsummary>Subtract from counter</fsummary> + <desc> + <p>Subtract <c><anno>Decr</anno></c> from counter at index + <c><anno>Ix</anno></c>.</p> + </desc> + </func> + + <func> + <name name="put" arity="3" since="OTP 21.2"/> + <fsummary>Set counter to value</fsummary> + <desc> + <p>Write <c><anno>Value</anno></c> to counter at index + <c><anno>Ix</anno></c>.</p> + <note> + <p>Despite its name, the <c>write_concurrency</c> optimization does not + improve <c>put</c>. A call to <c>put</c> is a relatively heavy + operation compared to the very lightweight and scalable <seealso + marker="#add/3"><c>add</c></seealso> and <seealso marker="#sub/3"> + <c>sub</c></seealso>. The cost for a <c>put</c> with + <c>write_concurrency</c> is like a <seealso marker="#get/2"><c>get</c> + </seealso> plus a <c>put</c> without <c>write_concurrency</c>.</p> + </note> + </desc> + </func> + + <func> + <name name="info" arity="1" since="OTP 21.2"/> + <fsummary>Get information about counter array.</fsummary> + <desc> + <p>Return information about a counter array in a map. The map + has the following keys (at least):</p> + <taglist> + <tag><c>size</c></tag> + <item><p>The number of counters in the array.</p></item> + <tag><c>memory</c></tag> + <item><p>Approximate memory consumption for the array in + bytes.</p></item> + </taglist> + </desc> + </func> + + </funcs> +</erlref> diff --git a/erts/doc/src/crash_dump.xml b/erts/doc/src/crash_dump.xml index a9aeb1888c..876834307a 100644 --- a/erts/doc/src/crash_dump.xml +++ b/erts/doc/src/crash_dump.xml @@ -289,8 +289,8 @@ Slogan: <reason></pre> <marker id="memory"></marker> <title>Memory Information</title> <p>Under the tag <em>=memory</em> is shown information similar - to what can be obtainted on a living node with - <seealso marker="erts:erlang#erlang:memory/0"> + to what can be obtained on a living node with + <seealso marker="erts:erlang#memory/0"> <c>erlang:memory()</c></seealso>.</p> </section> diff --git a/erts/doc/src/driver.xml b/erts/doc/src/driver.xml index 8f31df4cad..a873bf9931 100644 --- a/erts/doc/src/driver.xml +++ b/erts/doc/src/driver.xml @@ -391,7 +391,7 @@ void encode_result(ei_x_buff* x, PGresult* res, PGconn* conn) <p>Before a driver can be called from Erlang, it must be loaded and opened. Loading is done using the <c><![CDATA[erl_ddll]]></c> module (the <c><![CDATA[erl_ddll]]></c> driver that loads dynamic - driver is actually a driver itself). If loading is successfull, + driver is actually a driver itself). If loading is successful, the port can be opened with <c><![CDATA[open_port/2]]></c>. The port name must match the name of the shared library and the name in the driver entry structure.</p> diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index 05a9895687..ed1b0880b4 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -460,11 +460,14 @@ <tag><c><![CDATA[-remsh Node]]></c></tag> <item> <p>Starts Erlang with a remote shell connected to - <c><![CDATA[Node]]></c>.</p> + <c><![CDATA[Node]]></c>. Requires either <c><![CDATA[-name]]></c> + or <c><![CDATA[-sname]]></c> to be given. If <c><![CDATA[Node]]></c> + does not contain a hostname, one is automatically taken from + <c><![CDATA[-name]]></c> or <c><![CDATA[-sname]]></c></p> </item> <tag><c><![CDATA[-rsh Program]]></c></tag> <item> - <p>Specifies an alternative to <c><![CDATA[rsh]]></c> for starting a + <p>Specifies an alternative to <c><![CDATA[ssh]]></c> for starting a slave node on a remote host; see <seealso marker="stdlib:slave"><c>slave(3)</c></seealso>.</p> </item> @@ -636,6 +639,29 @@ produces a crash dump. On Unix systems, sending an emulator process a <c>SIGUSR1</c> signal also forces a crash dump.</p> </item> + <tag><marker id="+dcg"/><c><![CDATA[+rg DecentralizedCounterGroupsLimit]]></c></tag> + <item> + <p>Limits the number of decentralized counter groups used by + decentralized counters optimized for update operations in the + Erlang runtime system. By default, the limit is 256.</p> + <p>When the number of schedulers is less than or equal to the + limit, each scheduler has its own group. When the + number of schedulers is larger than the groups limit, + schedulers share groups. Shared groups degrade + the performance for updating counters while many reader groups + degrade the performance for reading counters. So, the limit is a tradeoff + between performance for update operations and performance for + read operations. Each group consumes 64 bytes in each + counter.</p> + <p>Notice that a runtime system using decentralized + counter groups benefits from <seealso marker="#+sbt">binding + schedulers to logical processors</seealso>, as the groups are + distributed better between schedulers with this option.</p> + <p>This option only affects decentralized counters used for + the counters that are keeping track of the memory consumption + and the number of terms in ETS tables of type ordered_set with + the write_concurrency option activated.</p> + </item> <tag><marker id="+e"/><c><![CDATA[+e Number]]></c></tag> <item> <p>Sets the maximum number of ETS tables. This limit is diff --git a/erts/doc/src/erl_dist_protocol.xml b/erts/doc/src/erl_dist_protocol.xml index c90c8f9521..f924c8a70b 100644 --- a/erts/doc/src/erl_dist_protocol.xml +++ b/erts/doc/src/erl_dist_protocol.xml @@ -532,11 +532,7 @@ io:format("old/unused name ~ts at port ~p, fd = ~p ~n", <marker id="distribution_handshake"/> <title>Distribution Handshake</title> <p>This section describes the distribution handshake protocol introduced - in Erlang/OTP R6. This description was previously located in - <c>$ERL_TOP/lib/kernel/internal_doc/distribution_handshake.txt</c> and - has more or less been copied and "formatted" here. It has been almost - unchanged since 1999, but the handshake has not changed much since then - either.</p> + in Erlang/OTP R6. The handshake has remained almost the same since then.</p> <section> <title>General</title> @@ -847,6 +843,23 @@ DiB == gen_digest(ChA, ICA)? of the <c>SEND_TT</c> control message. </p> </item> + <tag><c>-define(DFLAG_BIG_SEQTRACE_LABELS, 16#100000).</c></tag> + <item> + <p>The node understands any term as the seqtrace label.</p> + </item> + <tag><c>-define(DFLAG_EXIT_PAYLOAD, 16#400000).</c></tag> + <item> + <p>Use the <c>PAYLOAD_EXIT</c>, <c>PAYLOAD_EXIT_TT</c>, + <c>PAYLOAD_EXIT2</c>, <c>PAYLOAD_EXIT2_TT</c> + and <c>PAYLOAD_MONITOR_P_EXIT</c> + <seealso marker="#control_message">control message</seealso>s + instead of the non-PAYLOAD variants.</p> + </item> + <tag><c>-define(DFLAG_FRAGMENTS, 16#800000).</c></tag> + <item> + <p>Use <seealso marker="erl_ext_dist#fragments">fragmented</seealso> + distribution messages to send large messages.</p> + </item> </taglist> <p> There is also function <c>dist_util:strict_order_flags/0</c> @@ -859,7 +872,7 @@ DiB == gen_digest(ChA, ICA)? <section> <marker id="connected_nodes"/> <title>Protocol between Connected Nodes</title> - <p>As from ERTS 5.7.2 the runtime system passes a distribution flag + <p>Since ERTS 5.7.2 (OTP R13B) the runtime system passes a distribution flag in the handshake stage that enables the use of a <seealso marker="erl_ext_dist#distribution_header">distribution header </seealso> on all messages passed. Messages passed between nodes have in @@ -878,7 +891,7 @@ DiB == gen_digest(ChA, ICA)? <cell align="center"><c>ControlMessage</c></cell> <cell align="center"><c>Message</c></cell> </row> - <tcaption>Format of Messages Passed between Nodes (as from ERTS 5.7.2) + <tcaption>Format of Messages Passed between Nodes (as from ERTS 5.7.2 (OTP R13B)) </tcaption> </table> @@ -887,15 +900,23 @@ DiB == gen_digest(ChA, ICA)? <item> <p>Equal to d + n + m.</p> </item> + <tag><c>DistributionHeader</c></tag> + <item> + <p> + <seealso marker="erl_ext_dist#distribution_header">Distribution header + describing the atom cache and fragmented distribution messages. + </seealso> + </p> + </item> <tag><c>ControlMessage</c></tag> <item> <p>A tuple passed using the external format of Erlang.</p> </item> <tag><c>Message</c></tag> <item> - <p>The message sent to another node using the '!' (in external format). - Notice that <c>Message</c> is only passed in combination with a - <c>ControlMessage</c> encoding a send ('!').</p> + <p>The message sent to another node using the '!' + or the reason for a EXIT, EXIT2 or DOWN signal using + the external term format.</p> </item> </taglist> @@ -903,7 +924,7 @@ DiB == gen_digest(ChA, ICA)? number is omitted from the terms that follow a distribution header </seealso>.</p> - <p>Nodes with an ERTS version earlier than 5.7.2 does not pass the + <p>Nodes with an ERTS version earlier than 5.7.2 (OTP R13B) does not pass the distribution flag that enables the distribution header. Messages passed between nodes have in this case the following format:</p> @@ -920,7 +941,7 @@ DiB == gen_digest(ChA, ICA)? <cell align="center"><c>ControlMessage</c></cell> <cell align="center"><c>Message</c></cell> </row> - <tcaption>Format of Messages Passed between Nodes (before ERTS 5.7.2) + <tcaption>Format of Messages Passed between Nodes (before ERTS 5.7.2 (OTP R13B)) </tcaption> </table> @@ -963,6 +984,7 @@ DiB == gen_digest(ChA, ICA)? <tag><c>EXIT</c></tag> <item> <p><c>{3, FromPid, ToPid, Reason}</c></p> + <p>This signal is sent when a link has been broken</p> </item> <tag><c>UNLINK</c></tag> <item> @@ -985,6 +1007,7 @@ DiB == gen_digest(ChA, ICA)? <tag><c>EXIT2</c></tag> <item> <p><c>{8, FromPid, ToPid, Reason}</c></p> + <p>This signal is sent by a call to the erlang:exit/2 bif</p> </item> </taglist> </section> @@ -1007,7 +1030,7 @@ DiB == gen_digest(ChA, ICA)? <p><c>{16, FromPid, Unused, ToName, TraceToken}</c></p> <p>Followed by <c>Message</c>.</p> <p><c>Unused</c> is kept for backward compatibility.</p> - </item> + </item> <tag><c>EXIT2_TT</c></tag> <item> <p><c>{18, FromPid, ToPid, TraceToken, Reason}</c></p> @@ -1061,7 +1084,7 @@ DiB == gen_digest(ChA, ICA)? <p><c>{22, FromPid, ToPid}</c></p> <p>Followed by <c>Message</c>.</p> <p> - This control messages replace the <c>SEND</c> control + This control message replaces the <c>SEND</c> control message and will be sent when the distribution flag <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_SEND_SENDER</c></seealso> has been negotiated in the connection setup handshake. @@ -1080,7 +1103,7 @@ DiB == gen_digest(ChA, ICA)? <p><c>{23, FromPid, ToPid, TraceToken}</c></p> <p>Followed by <c>Message</c>.</p> <p> - This control messages replace the <c>SEND_TT</c> control + This control message replaces the <c>SEND_TT</c> control message and will be sent when the distribution flag <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_SEND_SENDER</c></seealso> has been negotiated in the connection setup handshake. @@ -1097,4 +1120,72 @@ DiB == gen_digest(ChA, ICA)? </taglist> </section> + <section> + <title>New Ctrlmessages for Erlang/OTP 22</title> + <note><p> + Messages encoded before the connection has + been set up may still use the non-PAYLOAD variant. + However, once a PAYLOAD control message has been sent, + no more non-PAYLOAD control messages will be sent in + the same direction on the connection. + </p></note> + <taglist> + <tag><c>PAYLOAD_EXIT</c></tag> + <item> + <p><c>{24, FromPid, ToPid}</c></p> + <p>Followed by <c>Reason</c>.</p> + <p> + This control message replaces the <c>EXIT</c> control + message and will be sent when the distribution flag + <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_EXIT_PAYLOAD</c></seealso> + has been negotiated in the connection setup handshake. + </p> + </item> + <tag><c>PAYLOAD_EXIT_TT</c></tag> + <item> + <p><c>{25, FromPid, ToPid}</c></p> + <p>Followed by <c>Reason</c>.</p> + <p> + This control message replaces the <c>EXIT_TT</c> control + message and will be sent when the distribution flag + <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_EXIT_PAYLOAD</c></seealso> + has been negotiated in the connection setup handshake. + </p> + </item> + <tag><c>PAYLOAD_EXIT2</c></tag> + <item> + <p><c>{26, FromPid, ToPid}</c></p> + <p>Followed by <c>Reason</c>.</p> + <p> + This control message replaces the <c>EXIT2</c> control + message and will be sent when the distribution flag + <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_EXIT_PAYLOAD</c></seealso> + has been negotiated in the connection setup handshake. + </p> + </item> + <tag><c>PAYLOAD_EXIT2_TT</c></tag> + <item> + <p><c>{27, FromPid, ToPid}</c></p> + <p>Followed by <c>Reason</c>.</p> + <p> + This control message replaces the <c>EXIT2_TT</c> control + message and will be sent when the distribution flag + <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_EXIT_PAYLOAD</c></seealso> + has been negotiated in the connection setup handshake. + </p> + </item> + <tag><c>PAYLOAD_MONITOR_P_EXIT</c></tag> + <item> + <p><c>{28, FromPid, ToPid, Ref}</c></p> + <p>Followed by <c>Reason</c>.</p> + <p> + This control message replaces the <c>MONITOR_P_EXIT</c> control + message and will be sent when the distribution flag + <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_EXIT_PAYLOAD</c></seealso> + has been negotiated in the connection setup handshake. + </p> + </item> + </taglist> + </section> + </chapter> diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml index 7055889e4a..3e2d3bb447 100644 --- a/erts/doc/src/erl_driver.xml +++ b/erts/doc/src/erl_driver.xml @@ -230,7 +230,7 @@ <item> <p>With these functions, the driver sends data back to the emulator. The data is received as messages by the port owner process, see - <seealso marker="erlang:open_port/2"> + <seealso marker="erlang#open_port/2"> <c>erlang:open_port/2</c></seealso>. The vector function and the function taking a driver binary are faster, as they avoid copying the data buffer. There is also a fast way of sending @@ -944,7 +944,7 @@ int suggested_stack_size;</code> <funcs> <func> - <name><ret>void</ret><nametext>add_driver_entry(ErlDrvEntry + <name since=""><ret>void</ret><nametext>add_driver_entry(ErlDrvEntry *de)</nametext></name> <fsummary>Add a driver entry.</fsummary> <desc> @@ -968,7 +968,7 @@ int suggested_stack_size;</code> </func> <func> - <name><ret>void *</ret> + <name since=""><ret>void *</ret> <nametext>driver_alloc(ErlDrvSizeT size)</nametext></name> <fsummary>Allocate memory.</fsummary> <desc> @@ -985,7 +985,7 @@ int suggested_stack_size;</code> </func> <func> - <name><ret>ErlDrvBinary *</ret> + <name since=""><ret>ErlDrvBinary *</ret> <nametext>driver_alloc_binary(ErlDrvSizeT size)</nametext></name> <fsummary>Allocate a driver binary.</fsummary> <desc> @@ -1008,7 +1008,7 @@ int suggested_stack_size;</code> </func> <func> - <name><ret>long</ret><nametext>driver_async(ErlDrvPort port, unsigned + <name since=""><ret>long</ret><nametext>driver_async(ErlDrvPort port, unsigned int* key, void (*async_invoke)(void*), void* async_data, void (*async_free)(void*))</nametext></name> <fsummary>Perform an asynchronous call within a driver.</fsummary> @@ -1076,7 +1076,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>unsigned int</ret><nametext>driver_async_port_key(ErlDrvPort + <name since="OTP R16B02"><ret>unsigned int</ret><nametext>driver_async_port_key(ErlDrvPort port)</nametext></name> <fsummary>Calculate an async key from an ErlDrvPort.</fsummary> <desc> @@ -1096,7 +1096,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>long</ret> + <name since=""><ret>long</ret> <nametext>driver_binary_dec_refc(ErlDrvBinary *bin)</nametext></name> <fsummary>Decrement the reference count of a driver binary.</fsummary> <desc> @@ -1117,7 +1117,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>long</ret> + <name since=""><ret>long</ret> <nametext>driver_binary_get_refc(ErlDrvBinary *bin)</nametext></name> <fsummary>Get the reference count of a driver binary.</fsummary> <desc> @@ -1128,7 +1128,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>long</ret> + <name since=""><ret>long</ret> <nametext>driver_binary_inc_refc(ErlDrvBinary *bin)</nametext></name> <fsummary>Increment the reference count of a driver binary.</fsummary> <desc> @@ -1140,7 +1140,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvTermData</ret><nametext>driver_caller(ErlDrvPort + <name since=""><ret>ErlDrvTermData</ret><nametext>driver_caller(ErlDrvPort port)</nametext></name> <fsummary>Return the process making the driver call.</fsummary> <desc> @@ -1154,27 +1154,27 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> <taglist> <tag><seealso marker="driver_entry#start"> <c>start</c></seealso></tag> - <item>Called from <seealso marker="erlang:open_port/2"> + <item>Called from <seealso marker="erlang#open_port/2"> <c>erlang:open_port/2</c></seealso>.</item> <tag><seealso marker="driver_entry#output"> <c>output</c></seealso></tag> - <item>Called from <seealso marker="erlang:send/2"> + <item>Called from <seealso marker="erlang#send/2"> <c>erlang:send/2</c></seealso> and - <seealso marker="erlang:port_command/2"> + <seealso marker="erlang#port_command/2"> <c>erlang:port_command/2</c></seealso>.</item> <tag><seealso marker="driver_entry#outputv"> <c>outputv</c></seealso></tag> - <item>Called from <seealso marker="erlang:send/2"> + <item>Called from <seealso marker="erlang#send/2"> <c>erlang:send/2</c></seealso> and - <seealso marker="erlang:port_command/2"> + <seealso marker="erlang#port_command/2"> <c>erlang:port_command/2</c></seealso>.</item> <tag><seealso marker="driver_entry#control"> <c>control</c></seealso></tag> - <item>Called from <seealso marker="erlang:port_control/3"> + <item>Called from <seealso marker="erlang#port_control/3"> <c>erlang:port_control/3</c></seealso>.</item> <tag><seealso marker="driver_entry#call"> <c>call</c></seealso></tag> - <item>Called from <seealso marker="erlang:port_call/3"> + <item>Called from <seealso marker="erlang#port_call/3"> <c>erlang:port_call/3</c></seealso>.</item> </taglist> <p>Notice that this function is <em>not</em> thread-safe, not @@ -1183,7 +1183,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret> + <name since=""><ret>int</ret> <nametext>driver_cancel_timer(ErlDrvPort port)</nametext></name> <fsummary>Cancel a previously set timer.</fsummary> <desc> @@ -1196,7 +1196,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_compare_monitors(const ErlDrvMonitor + <name since=""><ret>int</ret><nametext>driver_compare_monitors(const ErlDrvMonitor *monitor1, const ErlDrvMonitor *monitor2)</nametext></name> <fsummary>Compare two monitors.</fsummary> <desc> @@ -1211,7 +1211,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvTermData</ret><nametext>driver_connected(ErlDrvPort + <name since=""><ret>ErlDrvTermData</ret><nametext>driver_connected(ErlDrvPort port)</nametext></name> <fsummary>Return the port owner process.</fsummary> <desc> @@ -1223,7 +1223,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvPort</ret><nametext>driver_create_port(ErlDrvPort port, + <name since=""><ret>ErlDrvPort</ret><nametext>driver_create_port(ErlDrvPort port, ErlDrvTermData owner_pid, char* name, ErlDrvData drv_data)</nametext></name> <fsummary>Create a new port (driver instance).</fsummary> @@ -1269,7 +1269,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_demonitor_process(ErlDrvPort port, + <name since=""><ret>int</ret><nametext>driver_demonitor_process(ErlDrvPort port, const ErlDrvMonitor *monitor)</nametext></name> <fsummary>Stop monitoring a process from a driver.</fsummary> <desc> @@ -1281,7 +1281,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvSizeT</ret><nametext>driver_deq(ErlDrvPort port, + <name since=""><ret>ErlDrvSizeT</ret><nametext>driver_deq(ErlDrvPort port, ErlDrvSizeT size)</nametext></name> <fsummary>Dequeue data from the head of the driver queue.</fsummary> <desc> @@ -1299,7 +1299,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_enq(ErlDrvPort port, char* buf, + <name since=""><ret>int</ret><nametext>driver_enq(ErlDrvPort port, char* buf, ErlDrvSizeT len)</nametext></name> <fsummary>Enqueue data in the driver queue.</fsummary> <desc> @@ -1325,7 +1325,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_enq_bin(ErlDrvPort port, + <name since=""><ret>int</ret><nametext>driver_enq_bin(ErlDrvPort port, ErlDrvBinary *bin, ErlDrvSizeT offset, ErlDrvSizeT len)</nametext> </name> <fsummary>Enqueue binary in the driver queue.</fsummary> @@ -1346,7 +1346,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_enqv(ErlDrvPort port, ErlIOVec *ev, + <name since=""><ret>int</ret><nametext>driver_enqv(ErlDrvPort port, ErlIOVec *ev, ErlDrvSizeT skip)</nametext></name> <fsummary>Enqueue vector in the driver queue.</fsummary> <desc> @@ -1365,11 +1365,11 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_failure(ErlDrvPort port, int + <name since=""><ret>int</ret><nametext>driver_failure(ErlDrvPort port, int error)</nametext></name> - <name><ret>int</ret><nametext>driver_failure_atom(ErlDrvPort port, char + <name since=""><ret>int</ret><nametext>driver_failure_atom(ErlDrvPort port, char *string)</nametext></name> - <name><ret>int</ret><nametext>driver_failure_posix(ErlDrvPort port, int + <name since=""><ret>int</ret><nametext>driver_failure_posix(ErlDrvPort port, int error)</nametext></name> <fsummary>Fail with error.</fsummary> <desc> @@ -1393,7 +1393,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_failure_eof(ErlDrvPort + <name since=""><ret>int</ret><nametext>driver_failure_eof(ErlDrvPort port)</nametext></name> <fsummary>Fail with EOF.</fsummary> <desc> @@ -1408,7 +1408,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret><nametext>driver_free(void *ptr)</nametext></name> + <name since=""><ret>void</ret><nametext>driver_free(void *ptr)</nametext></name> <fsummary>Free an allocated memory block.</fsummary> <desc> <marker id="driver_free"></marker> @@ -1422,7 +1422,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret> + <name since=""><ret>void</ret> <nametext>driver_free_binary(ErlDrvBinary *bin)</nametext></name> <fsummary>Free a driver binary.</fsummary> <desc> @@ -1436,7 +1436,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvTermData</ret> + <name since=""><ret>ErlDrvTermData</ret> <nametext>driver_get_monitored_process(ErlDrvPort port, const ErlDrvMonitor *monitor)</nametext></name> <fsummary>Retrieve the process ID from a monitor.</fsummary> @@ -1452,7 +1452,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret> + <name since=""><ret>int</ret> <nametext>driver_get_now(ErlDrvNowData *now)</nametext></name> <fsummary>Read a system time stamp.</fsummary> <desc> @@ -1473,7 +1473,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_lock_driver(ErlDrvPort + <name since=""><ret>int</ret><nametext>driver_lock_driver(ErlDrvPort port)</nametext></name> <fsummary>Ensure the driver is never unloaded.</fsummary> <desc> @@ -1486,7 +1486,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvTermData</ret><nametext>driver_mk_atom(char* + <name since=""><ret>ErlDrvTermData</ret><nametext>driver_mk_atom(char* string)</nametext></name> <fsummary>Make an atom from a name.</fsummary> <desc> @@ -1501,7 +1501,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvTermData</ret><nametext>driver_mk_port(ErlDrvPort + <name since=""><ret>ErlDrvTermData</ret><nametext>driver_mk_port(ErlDrvPort port)</nametext></name> <fsummary>Make an Erlang term port from a port.</fsummary> <desc> @@ -1517,7 +1517,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_monitor_process(ErlDrvPort port, + <name since=""><ret>int</ret><nametext>driver_monitor_process(ErlDrvPort port, ErlDrvTermData process, ErlDrvMonitor *monitor)</nametext></name> <fsummary>Monitor a process from a driver.</fsummary> <desc> @@ -1540,7 +1540,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_output(ErlDrvPort port, char *buf, + <name since=""><ret>int</ret><nametext>driver_output(ErlDrvPort port, char *buf, ErlDrvSizeT len)</nametext></name> <fsummary>Send data from driver to port owner.</fsummary> <desc> @@ -1560,7 +1560,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_output_binary(ErlDrvPort port, char + <name since=""><ret>int</ret><nametext>driver_output_binary(ErlDrvPort port, char *hbuf, ErlDrvSizeT hlen, ErlDrvBinary* bin, ErlDrvSizeT offset, ErlDrvSizeT len)</nametext></name> <fsummary>Send data from a driver binary to port owner.</fsummary> @@ -1589,7 +1589,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_output_term(ErlDrvPort port, + <name since=""><ret>int</ret><nametext>driver_output_term(ErlDrvPort port, ErlDrvTermData* term, int n)</nametext></name> <fsummary>Send term data from driver to port owner.</fsummary> <desc> @@ -1608,7 +1608,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_output2(ErlDrvPort port, char *hbuf, + <name since=""><ret>int</ret><nametext>driver_output2(ErlDrvPort port, char *hbuf, ErlDrvSizeT hlen, char *buf, ErlDrvSizeT len)</nametext></name> <fsummary>Send data and binary data to port owner.</fsummary> <desc> @@ -1625,7 +1625,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_outputv(ErlDrvPort port, char* hbuf, + <name since=""><ret>int</ret><nametext>driver_outputv(ErlDrvPort port, char* hbuf, ErlDrvSizeT hlen, ErlIOVec *ev, ErlDrvSizeT skip)</nametext></name> <fsummary>Send vectorized data to port owner.</fsummary> <desc> @@ -1654,7 +1654,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvPDL</ret> + <name since=""><ret>ErlDrvPDL</ret> <nametext>driver_pdl_create(ErlDrvPort port)</nametext></name> <fsummary>Create a port data lock.</fsummary> <desc> @@ -1672,7 +1672,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>long</ret><nametext>driver_pdl_dec_refc(ErlDrvPDL + <name since=""><ret>long</ret><nametext>driver_pdl_dec_refc(ErlDrvPDL pdl)</nametext></name> <fsummary></fsummary> <desc> @@ -1686,7 +1686,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>long</ret> + <name since=""><ret>long</ret> <nametext>driver_pdl_get_refc(ErlDrvPDL pdl)</nametext></name> <fsummary></fsummary> <desc> @@ -1698,7 +1698,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>long</ret> + <name since=""><ret>long</ret> <nametext>driver_pdl_inc_refc(ErlDrvPDL pdl)</nametext></name> <fsummary></fsummary> <desc> @@ -1712,7 +1712,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret> + <name since=""><ret>void</ret> <nametext>driver_pdl_lock(ErlDrvPDL pdl)</nametext></name> <fsummary>Lock port data lock.</fsummary> <desc> @@ -1723,7 +1723,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret> + <name since=""><ret>void</ret> <nametext>driver_pdl_unlock(ErlDrvPDL pdl)</nametext></name> <fsummary>Unlock port data lock.</fsummary> <desc> @@ -1734,7 +1734,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>SysIOVec *</ret><nametext>driver_peekq(ErlDrvPort port, int + <name since=""><ret>SysIOVec *</ret><nametext>driver_peekq(ErlDrvPort port, int *vlen)</nametext></name> <fsummary>Get the driver queue as a vector.</fsummary> <desc> @@ -1755,7 +1755,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvSizeT</ret><nametext>driver_peekqv(ErlDrvPort port, + <name since="OTP R15B"><ret>ErlDrvSizeT</ret><nametext>driver_peekqv(ErlDrvPort port, ErlIOVec *ev)</nametext></name> <fsummary>Get the driver queue as an I/O vector.</fsummary> <desc> @@ -1775,7 +1775,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_pushq(ErlDrvPort port, char* buf, + <name since=""><ret>int</ret><nametext>driver_pushq(ErlDrvPort port, char* buf, ErlDrvSizeT len)</nametext></name> <fsummary>Push data at the head of the driver queue.</fsummary> <desc> @@ -1792,7 +1792,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_pushq_bin(ErlDrvPort port, + <name since=""><ret>int</ret><nametext>driver_pushq_bin(ErlDrvPort port, ErlDrvBinary *bin, ErlDrvSizeT offset, ErlDrvSizeT len)</nametext> </name> <fsummary>Push binary at the head of the driver queue.</fsummary> @@ -1812,7 +1812,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_pushqv(ErlDrvPort port, ErlIOVec + <name since=""><ret>int</ret><nametext>driver_pushqv(ErlDrvPort port, ErlIOVec *ev, ErlDrvSizeT skip)</nametext></name> <fsummary>Push vector at the head of the driver queue.</fsummary> <desc> @@ -1831,7 +1831,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_read_timer(ErlDrvPort port, unsigned + <name since=""><ret>int</ret><nametext>driver_read_timer(ErlDrvPort port, unsigned long *time_left)</nametext></name> <fsummary>Read the time left before time-out.</fsummary> <desc> @@ -1844,7 +1844,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void *</ret> + <name since=""><ret>void *</ret> <nametext>driver_realloc(void *ptr, ErlDrvSizeT size)</nametext></name> <fsummary>Resize an allocated memory block.</fsummary> <desc> @@ -1859,7 +1859,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvBinary *</ret> + <name since=""><ret>ErlDrvBinary *</ret> <nametext>driver_realloc_binary(ErlDrvBinary *bin, ErlDrvSizeT size) </nametext></name> <fsummary>Resize a driver binary.</fsummary> @@ -1873,7 +1873,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_select(ErlDrvPort port, ErlDrvEvent + <name since=""><ret>int</ret><nametext>driver_select(ErlDrvPort port, ErlDrvEvent event, int mode, int on)</nametext></name> <fsummary>Provides an event for having the emulator call the driver. </fsummary> @@ -1932,7 +1932,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_send_term(ErlDrvPort port, + <name since=""><ret>int</ret><nametext>driver_send_term(ErlDrvPort port, ErlDrvTermData receiver, ErlDrvTermData* term, int n)</nametext></name> <fsummary>Send term data to other process than port owner process. </fsummary> @@ -1958,7 +1958,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>driver_set_timer(ErlDrvPort port, unsigned + <name since=""><ret>int</ret><nametext>driver_set_timer(ErlDrvPort port, unsigned long time)</nametext></name> <fsummary>Set a timer to call the driver.</fsummary> <desc> @@ -1977,7 +1977,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvSizeT</ret> + <name since=""><ret>ErlDrvSizeT</ret> <nametext>driver_sizeq(ErlDrvPort port)</nametext></name> <fsummary>Return the size of the driver queue.</fsummary> <desc> @@ -1991,7 +1991,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret><nametext>driver_system_info(ErlDrvSysInfo + <name since=""><ret>void</ret><nametext>driver_system_info(ErlDrvSysInfo *sys_info_ptr, size_t size)</nametext></name> <fsummary>Get information about the Erlang runtime system.</fsummary> <desc> @@ -2008,7 +2008,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvSizeT</ret><nametext>driver_vec_to_buf(ErlIOVec *ev, + <name since=""><ret>ErlDrvSizeT</ret><nametext>driver_vec_to_buf(ErlIOVec *ev, char *buf, ErlDrvSizeT len)</nametext></name> <fsummary>Collect data segments into a buffer.</fsummary> <desc> @@ -2029,7 +2029,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret><nametext>erl_drv_busy_msgq_limits(ErlDrvPort port, + <name since="OTP R16B"><ret>void</ret><nametext>erl_drv_busy_msgq_limits(ErlDrvPort port, ErlDrvSizeT *low, ErlDrvSizeT *high)</nametext></name> <fsummary>Set and get limits for busy port message queue.</fsummary> <desc> @@ -2083,7 +2083,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret><nametext>erl_drv_cond_broadcast(ErlDrvCond + <name since=""><ret>void</ret><nametext>erl_drv_cond_broadcast(ErlDrvCond *cnd)</nametext></name> <fsummary>Broadcast on a condition variable.</fsummary> <desc> @@ -2097,7 +2097,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvCond *</ret><nametext>erl_drv_cond_create(char + <name since=""><ret>ErlDrvCond *</ret><nametext>erl_drv_cond_create(char *name)</nametext></name> <fsummary>Create a condition variable.</fsummary> <desc> @@ -2114,7 +2114,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret><nametext>erl_drv_cond_destroy(ErlDrvCond + <name since=""><ret>void</ret><nametext>erl_drv_cond_destroy(ErlDrvCond *cnd)</nametext></name> <fsummary>Destroy a condition variable.</fsummary> <desc> @@ -2128,7 +2128,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>char *</ret><nametext>erl_drv_cond_name(ErlDrvCond + <name since="OTP R16B02"><ret>char *</ret><nametext>erl_drv_cond_name(ErlDrvCond *cnd)</nametext></name> <fsummary>Get name of driver mutex.</fsummary> <desc> @@ -2142,7 +2142,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret><nametext>erl_drv_cond_signal(ErlDrvCond + <name since=""><ret>void</ret><nametext>erl_drv_cond_signal(ErlDrvCond *cnd)</nametext></name> <fsummary>Signal on a condition variable.</fsummary> <desc> @@ -2156,7 +2156,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret><nametext>erl_drv_cond_wait(ErlDrvCond *cnd, + <name since=""><ret>void</ret><nametext>erl_drv_cond_wait(ErlDrvCond *cnd, ErlDrvMutex *mtx)</nametext></name> <fsummary>Wait on a condition variable.</fsummary> <desc> @@ -2185,7 +2185,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>erl_drv_consume_timeslice(ErlDrvPort port, + <name since="OTP R16B"><ret>int</ret><nametext>erl_drv_consume_timeslice(ErlDrvPort port, int percent)</nametext></name> <fsummary>Give the runtime system a hint about how much CPU time the current driver callback call has consumed.</fsummary> @@ -2228,7 +2228,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvTime</ret><nametext>erl_drv_convert_time_unit(ErlDrvTime + <name since="OTP 18.3"><ret>ErlDrvTime</ret><nametext>erl_drv_convert_time_unit(ErlDrvTime val, ErlDrvTimeUnit from, ErlDrvTimeUnit to)</nametext></name> <fsummary>Convert time unit of a time value.</fsummary> <desc> @@ -2254,7 +2254,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>erl_drv_equal_tids(ErlDrvTid tid1, + <name since=""><ret>int</ret><nametext>erl_drv_equal_tids(ErlDrvTid tid1, ErlDrvTid tid2)</nametext></name> <fsummary>Compare thread identifiers for equality.</fsummary> <desc> @@ -2276,7 +2276,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>erl_drv_getenv(const char *key, char + <name since=""><ret>int</ret><nametext>erl_drv_getenv(const char *key, char *value, size_t *value_size)</nametext></name> <fsummary>Get the value of an environment variable.</fsummary> <desc> @@ -2305,7 +2305,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> <c>*value_size</c> has been set to the buffer size needed.</p> <warning> <p>This function reads the emulated environment used by - <seealso marker="os:getenv/1"><c>os:getenv/1</c></seealso> and not + <seealso marker="kernel:os#getenv/1"><c>os:getenv/1</c></seealso> and not the environment used by libc's <c>getenv(3)</c> or similar. Drivers that <em>require</em> that these are in sync will need to do so themselves, but keep in mind that they are segregated for a reason; @@ -2317,7 +2317,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret><nametext>erl_drv_init_ack(ErlDrvPort port, + <name since="OTP 19.0"><ret>void</ret><nametext>erl_drv_init_ack(ErlDrvPort port, ErlDrvData res)</nametext></name> <fsummary>Acknowledge the start of the port.</fsummary> <desc> @@ -2345,7 +2345,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvTime</ret> + <name since="OTP 18.3"><ret>ErlDrvTime</ret> <nametext>erl_drv_monotonic_time(ErlDrvTimeUnit time_unit)</nametext> </name> <fsummary>Get Erlang monotonic time.</fsummary> @@ -2365,7 +2365,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>ErlDrvMutex *</ret><nametext>erl_drv_mutex_create(char + <name since=""><ret>ErlDrvMutex *</ret><nametext>erl_drv_mutex_create(char *name)</nametext></name> <fsummary>Create a mutex.</fsummary> <desc> @@ -2380,7 +2380,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret><nametext>erl_drv_mutex_destroy(ErlDrvMutex + <name since=""><ret>void</ret><nametext>erl_drv_mutex_destroy(ErlDrvMutex *mtx)</nametext></name> <fsummary>Destroy a mutex.</fsummary> <desc> @@ -2395,7 +2395,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret><nametext>erl_drv_mutex_lock(ErlDrvMutex + <name since=""><ret>void</ret><nametext>erl_drv_mutex_lock(ErlDrvMutex *mtx)</nametext></name> <fsummary>Lock a mutex.</fsummary> <desc> @@ -2414,7 +2414,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>char *</ret><nametext>erl_drv_mutex_name(ErlDrvMutex + <name since="OTP R16B02"><ret>char *</ret><nametext>erl_drv_mutex_name(ErlDrvMutex *mtx)</nametext></name> <fsummary>Get name of driver mutex.</fsummary> <desc> @@ -2428,7 +2428,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>erl_drv_mutex_trylock(ErlDrvMutex + <name since=""><ret>int</ret><nametext>erl_drv_mutex_trylock(ErlDrvMutex *mtx)</nametext></name> <fsummary>Try lock a mutex.</fsummary> <desc> @@ -2447,7 +2447,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>void</ret><nametext>erl_drv_mutex_unlock(ErlDrvMutex + <name since=""><ret>void</ret><nametext>erl_drv_mutex_unlock(ErlDrvMutex *mtx)</nametext></name> <fsummary>Unlock a mutex.</fsummary> <desc> @@ -2460,7 +2460,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> </func> <func> - <name><ret>int</ret><nametext>erl_drv_output_term(ErlDrvTermData port, + <name since="OTP R16B"><ret>int</ret><nametext>erl_drv_output_term(ErlDrvTermData port, ErlDrvTermData* term, int n)</nametext></name> <fsummary>Send term data from driver to port owner.</fsummary> <desc> @@ -2637,7 +2637,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>int</ret><nametext>erl_drv_putenv(const char *key, char + <name since=""><ret>int</ret><nametext>erl_drv_putenv(const char *key, char *value)</nametext></name> <fsummary>Set the value of an environment variable.</fsummary> <desc> @@ -2656,7 +2656,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </note> <warning> <p>This function modifies the emulated environment used by - <seealso marker="os:putenv/2"><c>os:putenv/2</c></seealso> and not + <seealso marker="kernel:os#putenv/2"><c>os:putenv/2</c></seealso> and not the environment used by libc's <c>putenv(3)</c> or similar. Drivers that <em>require</em> that these are in sync will need to do so themselves, but keep in mind that they are segregated for a reason; @@ -2668,7 +2668,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>ErlDrvRWLock *</ret><nametext>erl_drv_rwlock_create(char + <name since=""><ret>ErlDrvRWLock *</ret><nametext>erl_drv_rwlock_create(char *name)</nametext></name> <fsummary>Create an rwlock.</fsummary> <desc> @@ -2684,7 +2684,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void</ret><nametext>erl_drv_rwlock_destroy(ErlDrvRWLock + <name since=""><ret>void</ret><nametext>erl_drv_rwlock_destroy(ErlDrvRWLock *rwlck)</nametext></name> <fsummary>Destroy an rwlock.</fsummary> <desc> @@ -2699,7 +2699,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>char *</ret><nametext>erl_drv_rwlock_name(ErlDrvRWLock + <name since="OTP R16B02"><ret>char *</ret><nametext>erl_drv_rwlock_name(ErlDrvRWLock *rwlck)</nametext></name> <fsummary>Get name of driver mutex.</fsummary> <desc> @@ -2713,7 +2713,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void</ret><nametext>erl_drv_rwlock_rlock(ErlDrvRWLock + <name since=""><ret>void</ret><nametext>erl_drv_rwlock_rlock(ErlDrvRWLock *rwlck)</nametext></name> <fsummary>Read lock an rwlock.</fsummary> <desc> @@ -2733,7 +2733,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void</ret><nametext>erl_drv_rwlock_runlock(ErlDrvRWLock + <name since=""><ret>void</ret><nametext>erl_drv_rwlock_runlock(ErlDrvRWLock *rwlck)</nametext></name> <fsummary>Read unlock an rwlock.</fsummary> <desc> @@ -2746,7 +2746,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void</ret><nametext>erl_drv_rwlock_rwlock(ErlDrvRWLock + <name since=""><ret>void</ret><nametext>erl_drv_rwlock_rwlock(ErlDrvRWLock *rwlck)</nametext></name> <fsummary>Read/write lock an rwlock.</fsummary> <desc> @@ -2766,7 +2766,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void</ret><nametext>erl_drv_rwlock_rwunlock(ErlDrvRWLock + <name since=""><ret>void</ret><nametext>erl_drv_rwlock_rwunlock(ErlDrvRWLock *rwlck)</nametext></name> <fsummary>Read/write unlock an rwlock.</fsummary> <desc> @@ -2779,7 +2779,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>int</ret><nametext>erl_drv_rwlock_tryrlock(ErlDrvRWLock + <name since=""><ret>int</ret><nametext>erl_drv_rwlock_tryrlock(ErlDrvRWLock *rwlck)</nametext></name> <fsummary>Try to read lock an rwlock.</fsummary> <desc> @@ -2799,7 +2799,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>int</ret><nametext>erl_drv_rwlock_tryrwlock(ErlDrvRWLock + <name since=""><ret>int</ret><nametext>erl_drv_rwlock_tryrwlock(ErlDrvRWLock *rwlck)</nametext></name> <fsummary>Try to read/write lock an rwlock.</fsummary> <desc> @@ -2819,7 +2819,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>int</ret><nametext>erl_drv_send_term(ErlDrvTermData port, + <name since="OTP R16B"><ret>int</ret><nametext>erl_drv_send_term(ErlDrvTermData port, ErlDrvTermData receiver, ErlDrvTermData* term, int n)</nametext></name> <fsummary>Send term data to other process than port owner process. </fsummary> @@ -2843,13 +2843,13 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void</ret><nametext>erl_drv_set_os_pid(ErlDrvPort port, + <name since="OTP 19.0"><ret>void</ret><nametext>erl_drv_set_os_pid(ErlDrvPort port, ErlDrvSInt pid)</nametext></name> <fsummary>Set the os_pid for the port.</fsummary> <desc> <marker id="erl_drv_set_os_pid"></marker> <p>Sets the <c>os_pid</c> seen when doing - <seealso marker="erlang:port_info/2"> + <seealso marker="erlang#port_info/2"> <c>erlang:port_info/2</c></seealso> on this port.</p> <p><c>port</c> is the port handle of the port (driver instance) to set the pid on. <c>pid</c>is the pid to set.</p> @@ -2857,7 +2857,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>int</ret><nametext>erl_drv_thread_create(char *name, ErlDrvTid + <name since=""><ret>int</ret><nametext>erl_drv_thread_create(char *name, ErlDrvTid *tid, void * (*func)(void *), void *arg, ErlDrvThreadOpts *opts)</nametext></name> <fsummary>Create a thread.</fsummary> @@ -2920,7 +2920,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void</ret><nametext>erl_drv_thread_exit(void + <name since=""><ret>void</ret><nametext>erl_drv_thread_exit(void *exit_value)</nametext></name> <fsummary>Terminate calling thread.</fsummary> <desc> @@ -2939,7 +2939,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>int</ret><nametext>erl_drv_thread_join(ErlDrvTid tid, void + <name since=""><ret>int</ret><nametext>erl_drv_thread_join(ErlDrvTid tid, void **exit_value)</nametext></name> <fsummary>Join with another thread.</fsummary> <desc> @@ -2962,7 +2962,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>char *</ret><nametext>erl_drv_thread_name(ErlDrvTid + <name since="OTP R16B02"><ret>char *</ret><nametext>erl_drv_thread_name(ErlDrvTid tid)</nametext></name> <fsummary>Get name of driver mutex.</fsummary> <desc> @@ -2976,7 +2976,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>ErlDrvThreadOpts *</ret> + <name since=""><ret>ErlDrvThreadOpts *</ret> <nametext>erl_drv_thread_opts_create(char *name)</nametext></name> <fsummary>Create thread options.</fsummary> <desc> @@ -3005,7 +3005,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void</ret> + <name since=""><ret>void</ret> <nametext>erl_drv_thread_opts_destroy(ErlDrvThreadOpts *opts)</nametext> </name> <fsummary>Destroy thread options.</fsummary> @@ -3020,7 +3020,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>ErlDrvTid</ret> + <name since=""><ret>ErlDrvTid</ret> <nametext>erl_drv_thread_self(void)</nametext></name> <fsummary>Get the thread identifier of the current thread.</fsummary> <desc> @@ -3031,7 +3031,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>ErlDrvTime</ret><nametext>erl_drv_time_offset(ErlDrvTimeUnit + <name since="OTP 18.3"><ret>ErlDrvTime</ret><nametext>erl_drv_time_offset(ErlDrvTimeUnit time_unit)</nametext></name> <fsummary>Get current time offset.</fsummary> <desc> @@ -3054,7 +3054,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void *</ret><nametext>erl_drv_tsd_get(ErlDrvTSDKey + <name since=""><ret>void *</ret><nametext>erl_drv_tsd_get(ErlDrvTSDKey key)</nametext></name> <fsummary>Get thread-specific data.</fsummary> <desc> @@ -3069,7 +3069,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>int</ret><nametext>erl_drv_tsd_key_create(char *name, + <name since=""><ret>int</ret><nametext>erl_drv_tsd_key_create(char *name, ErlDrvTSDKey *key)</nametext></name> <fsummary>Create a thread-specific data key.</fsummary> <desc> @@ -3086,7 +3086,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void</ret><nametext>erl_drv_tsd_key_destroy(ErlDrvTSDKey + <name since=""><ret>void</ret><nametext>erl_drv_tsd_key_destroy(ErlDrvTSDKey key)</nametext></name> <fsummary>Destroy a thread-specific data key.</fsummary> <desc> @@ -3111,7 +3111,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void</ret><nametext>erl_drv_tsd_set(ErlDrvTSDKey key, void + <name since=""><ret>void</ret><nametext>erl_drv_tsd_set(ErlDrvTSDKey key, void *data)</nametext></name> <fsummary>Set thread-specific data.</fsummary> <desc> @@ -3138,7 +3138,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>char *</ret><nametext>erl_errno_id(int error)</nametext></name> + <name since=""><ret>char *</ret><nametext>erl_errno_id(int error)</nametext></name> <fsummary>Get Erlang error atom name from error number.</fsummary> <desc> <marker id="erl_errno_id"></marker> @@ -3150,7 +3150,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>int</ret><nametext>remove_driver_entry(ErlDrvEntry + <name since=""><ret>int</ret><nametext>remove_driver_entry(ErlDrvEntry *de)</nametext></name> <fsummary>Remove a driver entry.</fsummary> <desc> @@ -3164,7 +3164,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void</ret><nametext>set_busy_port(ErlDrvPort port, int + <name since=""><ret>void</ret><nametext>set_busy_port(ErlDrvPort port, int on)</nametext></name> <fsummary>Signal or unsignal port as busy.</fsummary> <desc> @@ -3195,7 +3195,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] </func> <func> - <name><ret>void</ret><nametext>set_port_control_flags(ErlDrvPort port, + <name since=""><ret>void</ret><nametext>set_port_control_flags(ErlDrvPort port, int flags)</nametext></name> <fsummary>Set flags on how to handle control entry function.</fsummary> <desc> @@ -3204,7 +3204,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] <c>control</c></seealso> driver entry function will return data to the port owner process. (The <c>control</c> function is called from - <seealso marker="erlang:port_control/3"> + <seealso marker="erlang#port_control/3"> <c>erlang:port_control/3</c></seealso>.)</p> <p>Currently there are only two meaningful values for <c>flags</c>: <c>0</c> means that data is returned in a list, diff --git a/erts/doc/src/erl_ext_dist.xml b/erts/doc/src/erl_ext_dist.xml index b7090d0472..2ba5994557 100644 --- a/erts/doc/src/erl_ext_dist.xml +++ b/erts/doc/src/erl_ext_dist.xml @@ -128,7 +128,7 @@ are deprecated and are only kept for backward compatibility when decoding terms encoded by older nodes.</p> <p>Support for UTF-8 encoded atoms in the external format has been - available since ERTS 5.10 (OTP R16). This abillity allows such old nodes + available since ERTS 5.10 (OTP R16). This ability allows such old nodes to decode, store and encode any Unicode atoms received from a new OTP 20 node.</p> <p>The maximum number of allowed characters in an atom is 255. In the @@ -136,172 +136,370 @@ </note> </section> - <section> + <section> + <marker id="distribution_header"/> <title>Distribution Header</title> <p> - <marker id="distribution_header"/> - As from ERTS 5.7.2 the old atom cache protocol was - dropped and a new one was introduced. This protocol - introduced the distribution header. Nodes with an ERTS version - earlier than 5.7.2 can still communicate with new nodes, - but no distribution header and no atom cache are used.</p> - <p> - The distribution header only contains an atom cache - reference section, but can in the future contain more - information. The distribution header precedes one or more Erlang - terms on the external format. For more information, see the - documentation of the + The distribution header is sent by the erlang distribution to + carry metadata about the coming + <seealso marker="erl_dist_protocol#control_message">control message</seealso> + and potential payload. It is primarily used to handle the atom cache + in the Erlang distribution. Since OTP-22 it is also used to fragment + large distribution messages into multiple smaller fragments. + For more information about how the distribution uses the distribution header, + see the documentation of the <seealso marker="erl_dist_protocol#connected_nodes">protocol between connected nodes</seealso> in the <seealso marker="erl_dist_protocol">distribution protocol</seealso> documentation. </p> <p> - <seealso marker="#ATOM_CACHE_REF">ATOM_CACHE_REF</seealso> + Any <seealso marker="#ATOM_CACHE_REF">ATOM_CACHE_REF</seealso> entries with corresponding <c>AtomCacheReferenceIndex</c> in terms encoded on the external format following a distribution header refer to the atom cache references made in the distribution header. The range is 0 <= <c>AtomCacheReferenceIndex</c> < 255, that is, at most 255 different atom cache references from the following terms can be made. </p> - <p> - The distribution header format is as follows: - </p> - <table align="left"> - <row> - <cell align="center">1</cell> - <cell align="center">1</cell> - <cell align="center">1</cell> - <cell align="center">NumberOfAtomCacheRefs/2+1 | 0</cell> - <cell align="center">N | 0</cell> - </row> - <row> - <cell align="center"><c>131</c></cell> - <cell align="center"><c>68</c></cell> - <cell align="center"><c>NumberOfAtomCacheRefs</c></cell> - <cell align="center"><c>Flags</c></cell> - <cell align="center"><c>AtomCacheRefs</c></cell> - </row> - <tcaption>Distribution Header Format</tcaption></table> - <p> - <c>Flags</c> consist of <c>NumberOfAtomCacheRefs/2+1</c> bytes, - unless <c>NumberOfAtomCacheRefs</c> is <c>0</c>. If - <c>NumberOfAtomCacheRefs</c> is <c>0</c>, <c>Flags</c> and - <c>AtomCacheRefs</c> are omitted. Each atom cache reference has - a half byte flag field. Flags corresponding to a specific - <c>AtomCacheReferenceIndex</c> are located in flag byte number - <c>AtomCacheReferenceIndex/2</c>. Flag byte 0 is the first byte - after the <c>NumberOfAtomCacheRefs</c> byte. Flags for an even - <c>AtomCacheReferenceIndex</c> are located in the least significant - half byte and flags for an odd <c>AtomCacheReferenceIndex</c> are - located in the most significant half byte. - </p> - <p> - The flag field of an atom cache reference has the following - format: - </p> - <table align="left"> - <row> - <cell align="center">1 bit</cell> - <cell align="center">3 bits</cell> - </row> - <row> - <cell align="center"><c>NewCacheEntryFlag</c></cell> - <cell align="center"><c>SegmentIndex</c></cell> - </row> - <tcaption></tcaption></table> - <p> - The most significant bit is the <c>NewCacheEntryFlag</c>. If set, - the corresponding cache reference is new. The three least - significant bits are the <c>SegmentIndex</c> of the corresponding - atom cache entry. An atom cache consists of 8 segments, each of size - 256, that is, an atom cache can contain 2048 entries. - </p> - <p> - After flag fields for atom cache references, another half byte flag - field is located with the following format: - </p> - <table align="left"> - <row> - <cell align="center">3 bits</cell> - <cell align="center">1 bit</cell> - </row> - <row> - <cell align="center"><c>CurrentlyUnused</c></cell> - <cell align="center"><c>LongAtoms</c></cell> - </row> - <tcaption></tcaption></table> - <p> - The least significant bit in that half byte is flag <c>LongAtoms</c>. - If it is set, 2 bytes are used for atom lengths instead of - 1 byte in the distribution header. - </p> - <p> - After the <c>Flags</c> field follow the <c>AtomCacheRefs</c>. The - first <c>AtomCacheRef</c> is the one corresponding to - <c>AtomCacheReferenceIndex</c> 0. Higher indices follow - in sequence up to index <c>NumberOfAtomCacheRefs - 1</c>. - </p> - <p> - If the <c>NewCacheEntryFlag</c> for the next <c>AtomCacheRef</c> has - been set, a <c>NewAtomCacheRef</c> on the following format follows: - </p> - <table align="left"> - <row> - <cell align="center">1</cell> - <cell align="center">1 | 2</cell> - <cell align="center">Length</cell> - </row> - <row> - <cell align="center"><c>InternalSegmentIndex</c></cell> - <cell align="center"><c>Length</c></cell> - <cell align="center"><c>AtomText</c></cell> - </row> - <tcaption></tcaption></table> - <p> - <c>InternalSegmentIndex</c> together with the <c>SegmentIndex</c> - completely identify the location of an atom cache entry in the - atom cache. <c>Length</c> is the number of bytes that <c>AtomText</c> - consists of. Length is a 2 byte big-endian integer - if flag <c>LongAtoms</c> has been set, otherwise a 1 byte - integer. When distribution flag - <seealso marker="erl_dist_protocol#dflags"> - <c>DFLAG_UTF8_ATOMS</c></seealso> - has been exchanged between both nodes in the - <seealso marker="erl_dist_protocol#distribution_handshake"> - distribution handshake</seealso>, - characters in <c>AtomText</c> are encoded in UTF-8, otherwise - in Latin-1. The following <c>CachedAtomRef</c>s with the same - <c>SegmentIndex</c> and <c>InternalSegmentIndex</c> as this - <c>NewAtomCacheRef</c> refer to this atom until a new - <c>NewAtomCacheRef</c> with the same <c>SegmentIndex</c> - and <c>InternalSegmentIndex</c> appear. - </p> - <p> - For more information on encoding of atoms, see the - <seealso marker="#utf8_atoms">note on UTF-8 encoded atoms</seealso> - in the beginning of this section. - </p> - <p> - If the <c>NewCacheEntryFlag</c> for the next <c>AtomCacheRef</c> - has not been set, a <c>CachedAtomRef</c> on the following format - follows: - </p> - <table align="left"> - <row> - <cell align="center">1</cell> - </row> - <row> - <cell align="center"><c>InternalSegmentIndex</c></cell> - </row> - <tcaption></tcaption></table> - <p> - <c>InternalSegmentIndex</c> together with the <c>SegmentIndex</c> - identify the location of the atom cache entry in the atom cache. - The atom corresponding to this <c>CachedAtomRef</c> is the - latest <c>NewAtomCacheRef</c> preceding this <c>CachedAtomRef</c> - in another previously passed distribution header. - </p> + <section> + <title>Normal Distribution Header</title> + <p> + The non-fragmented distribution header format is as follows: + </p> + <table align="left"> + <row> + <cell align="center">1</cell> + <cell align="center">1</cell> + <cell align="center">1</cell> + <cell align="center">NumberOfAtomCacheRefs/2+1 | 0</cell> + <cell align="center">N | 0</cell> + </row> + <row> + <cell align="center"><c>131</c></cell> + <cell align="center"><c>68</c></cell> + <cell align="center"><c>NumberOfAtomCacheRefs</c></cell> + <cell align="center"><c>Flags</c></cell> + <cell align="center"><c>AtomCacheRefs</c></cell> + </row> + <tcaption>Normal Distribution Header Format</tcaption></table> + <p> + <c>Flags</c> consist of <c>NumberOfAtomCacheRefs/2+1</c> bytes, + unless <c>NumberOfAtomCacheRefs</c> is <c>0</c>. If + <c>NumberOfAtomCacheRefs</c> is <c>0</c>, <c>Flags</c> and + <c>AtomCacheRefs</c> are omitted. Each atom cache reference has + a half byte flag field. Flags corresponding to a specific + <c>AtomCacheReferenceIndex</c> are located in flag byte number + <c>AtomCacheReferenceIndex/2</c>. Flag byte 0 is the first byte + after the <c>NumberOfAtomCacheRefs</c> byte. Flags for an even + <c>AtomCacheReferenceIndex</c> are located in the least significant + half byte and flags for an odd <c>AtomCacheReferenceIndex</c> are + located in the most significant half byte. + </p> + <p> + The flag field of an atom cache reference has the following + format: + </p> + <table align="left"> + <row> + <cell align="center">1 bit</cell> + <cell align="center">3 bits</cell> + </row> + <row> + <cell align="center"><c>NewCacheEntryFlag</c></cell> + <cell align="center"><c>SegmentIndex</c></cell> + </row> + <tcaption></tcaption></table> + <p> + The most significant bit is the <c>NewCacheEntryFlag</c>. If set, + the corresponding cache reference is new. The three least + significant bits are the <c>SegmentIndex</c> of the corresponding + atom cache entry. An atom cache consists of 8 segments, each of size + 256, that is, an atom cache can contain 2048 entries. + </p> + <p> + After flag fields for atom cache references, another half byte flag + field is located with the following format: + </p> + <table align="left"> + <row> + <cell align="center">3 bits</cell> + <cell align="center">1 bit</cell> + </row> + <row> + <cell align="center"><c>CurrentlyUnused</c></cell> + <cell align="center"><c>LongAtoms</c></cell> + </row> + <tcaption></tcaption></table> + <p> + The least significant bit in that half byte is flag <c>LongAtoms</c>. + If it is set, 2 bytes are used for atom lengths instead of + 1 byte in the distribution header. + </p> + <p> + After the <c>Flags</c> field follow the <c>AtomCacheRefs</c>. The + first <c>AtomCacheRef</c> is the one corresponding to + <c>AtomCacheReferenceIndex</c> 0. Higher indices follow + in sequence up to index <c>NumberOfAtomCacheRefs - 1</c>. + </p> + <p> + If the <c>NewCacheEntryFlag</c> for the next <c>AtomCacheRef</c> has + been set, a <c>NewAtomCacheRef</c> on the following format follows: + </p> + <table align="left"> + <row> + <cell align="center">1</cell> + <cell align="center">1 | 2</cell> + <cell align="center">Length</cell> + </row> + <row> + <cell align="center"><c>InternalSegmentIndex</c></cell> + <cell align="center"><c>Length</c></cell> + <cell align="center"><c>AtomText</c></cell> + </row> + <tcaption></tcaption></table> + <p> + <c>InternalSegmentIndex</c> together with the <c>SegmentIndex</c> + completely identify the location of an atom cache entry in the + atom cache. <c>Length</c> is the number of bytes that <c>AtomText</c> + consists of. Length is a 2 byte big-endian integer + if flag <c>LongAtoms</c> has been set, otherwise a 1 byte + integer. When distribution flag + <seealso marker="erl_dist_protocol#dflags"> + <c>DFLAG_UTF8_ATOMS</c></seealso> + has been exchanged between both nodes in the + <seealso marker="erl_dist_protocol#distribution_handshake"> + distribution handshake</seealso>, + characters in <c>AtomText</c> are encoded in UTF-8, otherwise + in Latin-1. The following <c>CachedAtomRef</c>s with the same + <c>SegmentIndex</c> and <c>InternalSegmentIndex</c> as this + <c>NewAtomCacheRef</c> refer to this atom until a new + <c>NewAtomCacheRef</c> with the same <c>SegmentIndex</c> + and <c>InternalSegmentIndex</c> appear. + </p> + <p> + For more information on encoding of atoms, see the + <seealso marker="#utf8_atoms">note on UTF-8 encoded atoms</seealso> + in the beginning of this section. + </p> + <p> + If the <c>NewCacheEntryFlag</c> for the next <c>AtomCacheRef</c> + has not been set, a <c>CachedAtomRef</c> on the following format + follows: + </p> + <table align="left"> + <row> + <cell align="center">1</cell> + </row> + <row> + <cell align="center"><c>InternalSegmentIndex</c></cell> + </row> + <tcaption></tcaption></table> + <p> + <c>InternalSegmentIndex</c> together with the <c>SegmentIndex</c> + identify the location of the atom cache entry in the atom cache. + The atom corresponding to this <c>CachedAtomRef</c> is the + latest <c>NewAtomCacheRef</c> preceding this <c>CachedAtomRef</c> + in another previously passed distribution header. + </p> + </section> + <section> + <marker id="fragments"/> + <title>Distribution Header for fragmented messages</title> + <p>Messages sent between Erlang nodes can sometimes be + quite large. Since OTP-22 it is possible to split large messages + into smaller fragments in order to allow smaller messages to be interleaved + between larges messages. It is only the <c>message</c> part of each + <seealso marker="erl_dist_protocol#connected_nodes">distributed message</seealso> + that may be split using fragmentation. Therefore it is recommended to use the + <seealso marker="erl_dist_protocol#new-ctrlmessages-for-erlang-otp-22"> + PAYLOAD control messages</seealso> introduced in OTP-22. + </p> + <p>Fragmented distribution messages are only used if the receiving node + signals that it supports them via the + <seealso marker="erl_dist_protocol#dflags">DFLAG_FRAGMENTS</seealso> distribution + flag.</p> + <p>A process must complete the sending of a fragmented message before it + can start sending any other message on the same distribution channel.</p> + + <p>The start of a sequence of fragmented messages looks like this:</p> + <table align="left"> + <row> + <cell align="center">1</cell> + <cell align="center">1</cell> + <cell align="center">8</cell> + <cell align="center">8</cell> + <cell align="center">1</cell> + <cell align="center">NumberOfAtomCacheRefs/2+1 | 0</cell> + <cell align="center">N | 0</cell> + </row> + <row> + <cell align="center"><c>131</c></cell> + <cell align="center"><c>69</c></cell> + <cell align="center"><c>SequenceId</c></cell> + <cell align="center"><c>FragmentId</c></cell> + <cell align="center"><c>NumberOfAtomCacheRefs</c></cell> + <cell align="center"><c>Flags</c></cell> + <cell align="center"><c>AtomCacheRefs</c></cell> + </row> + <tcaption>Starting Fragmented Distribution Header Format</tcaption> + </table> + + <p>The continuation of a sequence of fragmented messages looks like this:</p> + <table align="left"> + <row> + <cell align="center">1</cell> + <cell align="center">1</cell> + <cell align="center">8</cell> + <cell align="center">8</cell> + </row> + <row> + <cell align="center"><c>131</c></cell> + <cell align="center"><c>70</c></cell> + <cell align="center"><c>SequenceId</c></cell> + <cell align="center"><c>FragmentId</c></cell> + </row> + <tcaption>Continuing Fragmented Distribution Header Format</tcaption> + </table> + + <p> + The starting distribution header is very similar to a non-fragmented distribution + header. The atom cache works the same as for normal distribution header and + is the same for the entire sequence. The additional fields added are the + sequence id and fragment id. + </p> + + <taglist> + <tag>Sequence ID</tag> + <item> + <p> + The sequence id is used to uniquely identify a fragmented message sent + from one process to another on the same distributed connection. This is used + to identify which sequence a fragment is a part of as the same process can + be in the process of receiving multiple sequences at the same time. + </p> + <p> + As one process can only be sending one fragmented message at once, + it can be convenient to use the local PID as the sequence id. + </p> + </item> + <tag>Fragments ID</tag> + <item> + <p> + The Fragment ID is used to number the fragments in a sequence. + The id starts at the total number of fragments and then decrements to 1 + (which is the final fragment). So if a sequence consists of 3 fragments + the fragment id in the starting header will be 3, and then fragments 2 and 1 + are sent. + </p> + <p> + The fragments must be delivered in the correct order, so if an unordered + distribution carrier is used, they must be ordered before delivered to the + Erlang run-time. + </p> + </item> + </taglist> + + <section> + <title>Example:</title> + <p> + As an example, let say that we want to send + <c>{call, <0.245.2>, {set_get_state, <<0:1024>>}}</c> to + registered process <c>reg</c> using a fragment size of 128. To send + this message we need a distribution header, atom cache updates, + the control message (which would be <c>{6, <0.245.2>, [], reg}</c> in this case) + and finally the actual message. This would all be encoded into: + </p> + + <code> +131,69,0,0,2,168,0,0,5,83,0,0,0,0,0,0,0,2, %% Header with seq and frag id +5,4,137,9,10,5,236,3,114,101,103,9,4,99,97,108,108, %% Atom cache updates +238,13,115,101,116,95,103,101,116,95,115,116,97,116,101, +104,4,97,6,103,82,0,0,0,0,85,0,0,0,0,2,82,1,82,2, %% Control message +104,3,82,3,103,82,0,0,0,0,245,0,0,0,2,2, %% Actual message using cached atoms +104,2,82,4,109,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + +131,70,0,0,2,168,0,0,5,83,0,0,0,0,0,0,0,1, %% Cont Header with seq and frag id +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, %% Rest of payload +0,0,0,0</code> + + <p> + Let us break that apart into its components. First we have the + distribution header tags together with the sequence id and + a fragment id of 2. + </p> + <code> +131,69, %% Start fragment header +0,0,2,168,0,0,5,83, %% The sequence ID +0,0,0,0,0,0,0,2, %% The fragment ID +</code> + <p>Then we have the updates to the atom cache:</p> + <code> +5,4,137,9, %% 5 atoms and their flags +10,5, %% The already cached atom ids +236,3,114,101,103, %% The atom 'reg' +9,4,99,97,108,108, %% The atom 'call' +238,13,115,101,116,95,103,101,116,95,115,116,97,116,101, %% The atom 'set_get_state' + </code> + <p> + The first byte says that we have 5 atoms that are part + of the cache. Then follows three bytes that are the + atom cache ref flags. Each of the flags uses 4 bits so + they are a bit hard to read in decimal byte form. In + binary half-byte form they look like this: + </p> + <code>0000, 0100, 1000, 1001, 1001</code> + <p> + As the high bit of the first two atoms in the + cache are not set we know that they are already in the cache, + so they do not have to be sent again (this is the node name of the + receiving and sending node). Then follows the atoms that have to be sent, + together with their segment ids. + </p> + <p> + Then the listing of the atoms comes, starting with 10 and 5 + which are the atom refs of the already cached atoms. Then the + new atoms are sent. + </p> + <p> + When the atom cache is setup correctly the control message is sent. + </p> + <code>104,4,97,6,103,82,0,0,0,0,85,0,0,0,0,2,82,1,82,2,</code> + <p> + Note that up until here it is not allowed to fragments the message. + The entire atom cache and control message has to be part of the + starting fragment. After the control message the payload of the message + is sent using 128 bytes: + </p> + <code> +104,3,82,3,103,82,0,0,0,0,245,0,0,0,2,2, +104,2,82,4,109,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + </code> + <p> + Since the payload is larger than 128-bytes it is split into two + fragments. The second fragment does not have any atom cache update + instructions so it is a lot simpler: + </p> + <code> +131,70,0,0,2,168,0,0,5,83,0,0,0,0,0,0,0,1, %% Continuation dist header 70 with seq and frag id +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, %% remaining payload +0,0,0,0 + </code> + <note> + <p> + The fragment size of 128 is only used as an example. + Any fragments size may be used when sending fragmented messages. + </p> + </note> + </section> + </section> </section> <section> @@ -373,8 +571,9 @@ </row> <tcaption>FLOAT_EXT</tcaption></table> <p> - A float is stored in string format. The format used in sprintf to - format the float is "%.20e" + A finite float (i.e. not inf, -inf or NaN) is stored in + string format. The format used in sprintf to format the + float is "%.20e" (there are more bytes allocated than necessary). To unpack the float, use sscanf with format "%lf". </p> @@ -386,44 +585,6 @@ </section> <section> - <marker id="REFERENCE_EXT"/> - <title>REFERENCE_EXT</title> - <table align="left"> - <row> - <cell align="center">1</cell> - <cell align="center">N</cell> - <cell align="center">4</cell> - <cell align="center">1</cell> - </row> - <row> - <cell align="center"><c>101</c></cell> - <cell align="center"><c>Node</c></cell> - <cell align="center"><c>ID</c></cell> - <cell align="center"><c>Creation</c></cell> - </row> - <tcaption>REFERENCE_EXT</tcaption></table> - <p> - Encodes a reference object (an object generated with - <seealso marker="erlang:make_ref/0">erlang:make_ref/0</seealso>). - The <c>Node</c> term is an encoded atom, that is, - <seealso marker="#ATOM_UTF8_EXT"><c>ATOM_UTF8_EXT</c></seealso>, - <seealso marker="#SMALL_ATOM_UTF8_EXT"><c>SMALL_ATOM_UTF8_EXT</c></seealso>, or - <seealso marker="#ATOM_CACHE_REF"><c>ATOM_CACHE_REF</c></seealso>. - The <c>ID</c> field contains a big-endian unsigned integer, - but <em>is to be regarded as uninterpreted data</em>, - as this field is node-specific. - <c>Creation</c> is a byte containing a node serial number, which - makes it possible to separate old (crashed) nodes from a new one. - </p> - <p> - In <c>ID</c>, only 18 bits are significant; the rest are to be 0. - In <c>Creation</c>, only two bits are significant; the rest are to be 0. - See <seealso marker="#NEW_REFERENCE_EXT"> - <c>NEW_REFERENCE_EXT</c></seealso>. - </p> - </section> - - <section> <marker id="PORT_EXT"/> <title>PORT_EXT</title> <table align="left"> @@ -441,13 +602,46 @@ </row> <tcaption>PORT_EXT</tcaption></table> <p> - Encodes a port object (obtained from - <seealso marker="erlang:open_port/2"> - <c>erlang:open_port/2</c></seealso>). - The <c>ID</c> is a node-specific identifier for a local port. + Same as <seealso marker="#NEW_PORT_EXT"><c>NEW_PORT_EXT</c></seealso> + except the <c>Creation</c> field is only one byte and only two + bits are significant, the rest are to be 0. + </p> + </section> + + <section> + <marker id="NEW_PORT_EXT"/> + <title>NEW_PORT_EXT</title> + <table align="left"> + <row> + <cell align="center">1</cell> + <cell align="center">N</cell> + <cell align="center">4</cell> + <cell align="center">4</cell> + </row> + <row> + <cell align="center"><c>89</c></cell> + <cell align="center"><c>Node</c></cell> + <cell align="center"><c>ID</c></cell> + <cell align="center"><c>Creation</c></cell> + </row> + <tcaption>NEW_PORT_EXT</tcaption></table> + <p> + Encodes a port identifier (obtained from + <seealso marker="erlang#open_port/2"><c>erlang:open_port/2</c></seealso>). + <c>Node</c> is an encoded atom, that is, + <seealso marker="#ATOM_UTF8_EXT"><c>ATOM_UTF8_EXT</c></seealso>, + <seealso marker="#SMALL_ATOM_UTF8_EXT"><c>SMALL_ATOM_UTF8_EXT</c></seealso> + or <seealso marker="#ATOM_CACHE_REF"><c>ATOM_CACHE_REF</c></seealso>. + <c>ID</c> is a 32-bit big endian unsigned integer. Only 28 bits are + significant; the rest are to be 0. The <c>Creation</c> works just like in + <seealso marker="#NEW_PID_EXT"><c>NEW_PID_EXT</c></seealso>. Port operations are not allowed across node boundaries. - The <c>Creation</c> works just like in - <seealso marker="#REFERENCE_EXT"><c>REFERENCE_EXT</c></seealso>. + </p> + <p>Introduced in OTP 19, but only to be decoded and echoed back. Not + encoded for local ports. Planned to supersede <seealso marker="#PORT_EXT"> + <c>PORT_EXT</c></seealso> in OTP 23 when + <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_BIG_CREATON</c></seealso> + becomes mandatory. </p> </section> @@ -471,12 +665,65 @@ </row> <tcaption>PID_EXT</tcaption></table> <p> - Encodes a process identifier object (obtained from - <seealso marker="erlang:spawn/3"><c>erlang:spawn/3</c></seealso> or - friends). The <c>ID</c> and <c>Creation</c> fields works just like in - <seealso marker="#REFERENCE_EXT"><c>REFERENCE_EXT</c></seealso>, while - the <c>Serial</c> field is used to improve safety. - In <c>ID</c>, only 15 bits are significant; the rest are to be 0. + Same as <seealso marker="#NEW_PID_EXT"><c>NEW_PID_EXT</c></seealso> + except the <c>Creation</c> field is only one byte and only two + bits are significant, the rest are to be 0. + </p> + </section> + + <section> + <marker id="NEW_PID_EXT"/> + <title>NEW_PID_EXT</title> + <table align="left"> + <row> + <cell align="center">1</cell> + <cell align="center">N</cell> + <cell align="center">4</cell> + <cell align="center">4</cell> + <cell align="center">4</cell> + </row> + <row> + <cell align="center"><c>88</c></cell> + <cell align="center"><c>Node</c></cell> + <cell align="center"><c>ID</c></cell> + <cell align="center"><c>Serial</c></cell> + <cell align="center"><c>Creation</c></cell> + </row> + <tcaption>NEW_PID_EXT</tcaption></table> + <p> + Encodes an Erlang process identifier object. + </p> + <taglist> + <tag><c>Node</c></tag> + <item><p>The name of the originating node, encoded using + <seealso marker="#ATOM_UTF8_EXT"><c>ATOM_UTF8_EXT</c></seealso>, + <seealso marker="#SMALL_ATOM_UTF8_EXT"><c>SMALL_ATOM_UTF8_EXT</c></seealso> + or <seealso + marker="#ATOM_CACHE_REF"><c>ATOM_CACHE_REF</c></seealso>.</p> + </item> + <tag><c>ID</c></tag> + <item><p>A 32-bit big endian unsigned integer. Only 15 bits are + significant; the rest are to be 0.</p> + </item> + <tag><c>Serial</c></tag> + <item><p>A 32-bit big endian unsigned integer. Only 13 bits are + significant; the rest are to be 0.</p> + </item> + <tag><c>Creation</c></tag> + <item><p>A 32-bit big endian unsigned integer. All identifiers + originating from the same node incarnation must have identical <c>Creation</c> + values. This makes it possible to separate identifiers from old + (crashed) nodes from a new one. The value zero should be avoided for + normal operations as it is used as a wild card for debug purpose + (like a pid returned by <seealso marker="erts:erlang#list_to_pid/1"> + erlang:list_to_pid/1</seealso>).</p> + </item> + </taglist> + <p>Introduced in OTP 19, but only to be decoded and echoed back. Not + encoded for local processes. Planned to supersede <seealso marker="#PID_EXT"> + <c>PID_EXT</c></seealso> in OTP 23 when + <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_BIG_CREATON</c></seealso> + becomes mandatory. </p> </section> @@ -666,7 +913,7 @@ <tcaption>SMALL_BIG_EXT</tcaption></table> <p> Bignums are stored in unary form with a <c>Sign</c> byte, - that is, 0 if the binum is positive and 1 if it is negative. The + that is, 0 if the bignum is positive and 1 if it is negative. The digits are stored with the least significant byte stored first. To calculate the integer, the following formula can be used: </p> @@ -700,6 +947,30 @@ </section> <section> + <marker id="REFERENCE_EXT"/> + <title>REFERENCE_EXT (deprecated)</title> + <table align="left"> + <row> + <cell align="center">1</cell> + <cell align="center">N</cell> + <cell align="center">4</cell> + <cell align="center">1</cell> + </row> + <row> + <cell align="center"><c>101</c></cell> + <cell align="center"><c>Node</c></cell> + <cell align="center"><c>ID</c></cell> + <cell align="center"><c>Creation</c></cell> + </row> + <tcaption>REFERENCE_EXT</tcaption></table> + <p> + The same as <seealso marker="#NEW_REFERENCE_EXT"> + <c>NEW_REFERENCE_EXT</c></seealso> except <c>ID</c> is only one word + (<c>Len</c> = 1). + </p> + </section> + + <section> <marker id="NEW_REFERENCE_EXT"/> <title>NEW_REFERENCE_EXT</title> <table align="left"> @@ -719,29 +990,68 @@ </row> <tcaption>NEW_REFERENCE_EXT</tcaption></table> <p> - <c>Node</c> and <c>Creation</c> are as in - <seealso marker="#REFERENCE_EXT"><c>REFERENCE_EXT</c></seealso>. - </p> - <p> - <c>ID</c> contains a sequence of big-endian unsigned integers - (4 bytes each, so <c>N'</c> is a multiple of 4), - but is to be regarded as uninterpreted data. - </p> - <p> - <c>N'</c> = 4 * <c>Len</c>. - </p> - <p> - In the first word (4 bytes) of <c>ID</c>, only 18 bits are - significant, the rest are to be 0. - In <c>Creation</c>, only two bits are significant, - the rest are to be 0. + The same as <seealso marker="#NEWER_REFERENCE_EXT"> + <c>NEWER_REFERENCE_EXT</c></seealso> <em>except</em>: </p> + <taglist> + <tag><c>ID</c></tag> + <item><p>In the first word (4 bytes) of <c>ID</c>, only 18 bits are + significant, the rest must be 0.</p> + </item> + <tag><c>Creation</c></tag> + <item><p>Only one byte long and only two bits are significant, the rest must be 0.</p> + </item> + </taglist> + </section> + + <section> + <marker id="NEWER_REFERENCE_EXT"/> + <title>NEWER_REFERENCE_EXT</title> + <table align="left"> + <row> + <cell align="center">1</cell> + <cell align="center">2</cell> + <cell align="center">N</cell> + <cell align="center">4</cell> + <cell align="center">N'</cell> + </row> + <row> + <cell align="center"><c>90</c></cell> + <cell align="center"><c>Len</c></cell> + <cell align="center"><c>Node</c></cell> + <cell align="center"><c>Creation</c></cell> + <cell align="center"><c>ID ...</c></cell> + </row> + <tcaption>NEWER_REFERENCE_EXT</tcaption></table> <p> - <c>NEW_REFERENCE_EXT</c> was introduced with distribution version 4. - In version 4, <c>N'</c> is to be at most 12. + Encodes a reference term generated with + <seealso marker="erts:erlang#make_ref/0">erlang:make_ref/0</seealso>. </p> - <p> - See <seealso marker="#REFERENCE_EXT"><c>REFERENCE_EXT</c></seealso>. + <taglist> + <tag><c>Node</c></tag> + <item><p>The name of the originating node, encoded using + <seealso marker="#ATOM_UTF8_EXT"><c>ATOM_UTF8_EXT</c></seealso>, + <seealso marker="#SMALL_ATOM_UTF8_EXT"><c>SMALL_ATOM_UTF8_EXT</c></seealso> + or <seealso marker="#ATOM_CACHE_REF"><c>ATOM_CACHE_REF</c></seealso>.</p> + </item> + <tag><c>Len</c></tag> + <item><p>A 16-bit big endian unsigned integer not larger than 3.</p> + </item> + <tag><c>ID</c></tag> + <item><p>A sequence of <c>Len</c> big-endian unsigned integers + (4 bytes each, so <c>N'</c> = 4 * <c>Len</c>), + but is to be regarded as uninterpreted data.</p> + </item> + <tag><c>Creation</c></tag> + <item><p>Works just like in + <seealso marker="#NEW_PID_EXT"><c>NEW_PID_EXT</c></seealso>.</p> + </item> + </taglist> + <p>Introduced in OTP 19, but only to be decoded and echoed back. Not + encoded for local references. Planned to supersede <seealso marker="#NEW_REFERENCE_EXT"> + <c>NEW_REFERENCE_EXT</c></seealso> in OTP 23 when + <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_BIG_CREATON</c></seealso> + becomes mandatory. </p> </section> @@ -989,7 +1299,8 @@ </row> <tcaption>NEW_FLOAT_EXT</tcaption></table> <p> - A float is stored as 8 bytes in big-endian IEEE format. + A finite float (i.e. not inf, -inf or NaN) is stored as 8 bytes + in big-endian IEEE format. </p> <p> This term is used in minor version 1 of the external format. diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index a8eff43623..d74ae23a93 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -194,7 +194,7 @@ ok <p>Binaries are sequences of whole bytes. Bitstrings with an arbitrary bit length have no support yet.</p> </item> - <tag>Resource objects</tag> + <tag><marker id="resource_objects"/>Resource objects</tag> <item> <p>The use of resource objects is a safe way to return pointers to native data structures from a NIF. A resource object is @@ -293,7 +293,7 @@ return term;</code> arguments. When you write to a shared state either through static variables or <seealso marker="#enif_priv_data"> <c>enif_priv_data</c></seealso>, you need to supply your own explicit - synchronization. This includes terms in process-independent + synchronization. This includes terms in process independent environments that are shared between threads. Resource objects also require synchronization if you treat them as mutable.</p> <p>The library initialization callbacks <c>load</c> and @@ -546,8 +546,8 @@ int writeiovec(ErlNifEnv *env, ERL_NIF_TERM term, ERL_NIF_TERM *tail, <p>Many operations communicating with a process executing a dirty NIF can, however, complete while it executes the dirty NIF. For example, retrieving information about it through - <seealso marker="erlang:process_info/1"> - <c>erlang:process_info</c></seealso>, setting its group leader, + <seealso marker="erlang#process_info/1"> + <c>process_info</c></seealso>, setting its group leader, register/unregister its name, and so on.</p> <p>Termination of a process executing a dirty NIF can only be completed up to a certain point while it executes the dirty NIF. @@ -596,7 +596,7 @@ int writeiovec(ErlNifEnv *env, ERL_NIF_TERM term, ERL_NIF_TERM *tail, <c>--enable-static-nifs</c>, you must define <c>STATIC_ERLANG_NIF</c> before the <c>ERL_NIF_INIT</c> declaration.</p> </item> - <tag><marker id="load"/><c>int (*load)(ErlNifEnv* env, void** priv_data, + <tag><marker id="load"/><c>int (*load)(ErlNifEnv* caller_env, void** priv_data, ERL_NIF_TERM load_info)</c></tag> <item> <p><c>load</c> is called when the NIF library is loaded @@ -612,7 +612,7 @@ int writeiovec(ErlNifEnv *env, ERL_NIF_TERM term, ERL_NIF_TERM *tail, anything other than <c>0</c>. <c>load</c> can be <c>NULL</c> if initialization is not needed.</p> </item> - <tag><marker id="upgrade"/><c>int (*upgrade)(ErlNifEnv* env, void** + <tag><marker id="upgrade"/><c>int (*upgrade)(ErlNifEnv* caller_env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info)</c></tag> <item> <p><c>upgrade</c> is called when the NIF library is loaded @@ -626,7 +626,7 @@ int writeiovec(ErlNifEnv *env, ERL_NIF_TERM term, ERL_NIF_TERM *tail, <p>The library fails to load if <c>upgrade</c> returns anything other than <c>0</c> or if <c>upgrade</c> is <c>NULL</c>.</p> </item> - <tag><marker id="unload"/><c>void (*unload)(ErlNifEnv* env, void* + <tag><marker id="unload"/><c>void (*unload)(ErlNifEnv* caller_env, void* priv_data)</c></tag> <item> <p><c>unload</c> is called when the module code that @@ -654,27 +654,41 @@ int writeiovec(ErlNifEnv *env, ERL_NIF_TERM term, ERL_NIF_TERM *tail, <p><c>ErlNifEnv</c> represents an environment that can host Erlang terms. All terms in an environment are valid as long as the environment is valid. <c>ErlNifEnv</c> is an opaque type; pointers to - it can only be passed on to API functions. Two types of environments + it can only be passed on to API functions. Three types of environments exist:</p> <taglist> - <tag>Process-bound environment</tag> + <tag>Process bound environment</tag> <item> <p>Passed as the first argument to all NIFs. All function arguments passed to a NIF belong to that environment. The return value from a NIF must also be a term belonging to the same environment.</p> - <p>A process-bound environment contains transient information + <p>A process bound environment contains transient information about the calling Erlang process. The environment is only valid in the thread where it was supplied as argument until the NIF returns. It is thus useless and dangerous to store pointers to - process-bound environments between NIF calls.</p> + process bound environments between NIF calls.</p> </item> - <tag>Process-independent environment</tag> + <tag>Callback environment</tag> + <item> + <p>Passed as the first argument to all the non-NIF callback functions + (<seealso marker="#load"><c>load</c></seealso>, + <seealso marker="#upgrade"><c>upgrade</c></seealso>, + <seealso marker="#unload"><c>unload</c></seealso>, + <seealso marker="#ErlNifResourceDtor"><c>dtor</c></seealso>, + <seealso marker="#ErlNifResourceDown"><c>down</c></seealso> and + <seealso marker="#ErlNifResourceStop"><c>stop</c></seealso>). + Works like a process bound environment but with a temporary + pseudo process that "terminates" when the callback has + returned. Terms may be created in this environment but they will + only be accessible during the callback.</p> + </item> + <tag>Process independent environment</tag> <item> <p>Created by calling <seealso marker="#enif_alloc_env"> <c>enif_alloc_env</c></seealso>. This environment can be used to store terms between NIF calls and to send terms with <seealso marker="#enif_send"><c>enif_send</c></seealso>. A - process-independent environment with all its terms is valid until + process independent environment with all its terms is valid until you explicitly invalidate it with <seealso marker="#enif_free_env"><c>enif_free_env</c></seealso> or <c>enif_send</c>.</p> @@ -769,14 +783,16 @@ typedef struct { <p>A process identifier (pid). In contrast to pid terms (instances of <c>ERL_NIF_TERM</c>), <c>ErlNifPid</c>s are self-contained and not bound to any <seealso marker="#ErlNifEnv">environment</seealso>. - <c>ErlNifPid</c> is an opaque type.</p> + <c>ErlNifPid</c> is an opaque type. It can be copied, moved + in memory, forgotten, and so on.</p> </item> <tag><marker id="ErlNifPort"/><c>ErlNifPort</c></tag> <item> <p>A port identifier. In contrast to port ID terms (instances of <c>ERL_NIF_TERM</c>), <c>ErlNifPort</c>s are self-contained and not bound to any <seealso marker="#ErlNifEnv">environment</seealso>. - <c>ErlNifPort</c> is an opaque type.</p> + <c>ErlNifPort</c> is an opaque type. It can be copied, moved + in memory, forgotten, and so on.</p> </item> <tag><marker id="ErlNifResourceType"/><c>ErlNifResourceType</c></tag> <item> @@ -799,7 +815,7 @@ typedef struct { <tag><marker id="ErlNifResourceDtor"/><c>ErlNifResourceDtor</c></tag> <item> <code type="none"> -typedef void ErlNifResourceDtor(ErlNifEnv* env, void* obj);</code> +typedef void ErlNifResourceDtor(ErlNifEnv* caller_env, void* obj);</code> <p>The function prototype of a resource destructor function.</p> <p>The <c>obj</c> argument is a pointer to the resource. The only allowed use for the resource in the destructor is to access its @@ -809,7 +825,7 @@ typedef void ErlNifResourceDtor(ErlNifEnv* env, void* obj);</code> <tag><marker id="ErlNifResourceDown"/><c>ErlNifResourceDown</c></tag> <item> <code type="none"> -typedef void ErlNifResourceDown(ErlNifEnv* env, void* obj, ErlNifPid* pid, ErlNifMonitor* mon);</code> +typedef void ErlNifResourceDown(ErlNifEnv* caller_env, void* obj, ErlNifPid* pid, ErlNifMonitor* mon);</code> <p>The function prototype of a resource down function, called on the behalf of <seealso marker="#enif_monitor_process"> enif_monitor_process</seealso>. <c>obj</c> is the resource, <c>pid</c> @@ -820,7 +836,7 @@ typedef void ErlNifResourceDown(ErlNifEnv* env, void* obj, ErlNifPid* pid, ErlNi <tag><marker id="ErlNifResourceStop"/><c>ErlNifResourceStop</c></tag> <item> <code type="none"> -typedef void ErlNifResourceStop(ErlNifEnv* env, void* obj, ErlNifEvent event, int is_direct_call);</code> +typedef void ErlNifResourceStop(ErlNifEnv* caller_env, void* obj, ErlNifEvent event, int is_direct_call);</code> <p>The function prototype of a resource stop function, called on the behalf of <seealso marker="#enif_select"> enif_select</seealso>. <c>obj</c> is the resource, <c>event</c> is OS event, @@ -949,7 +965,7 @@ typedef struct { <funcs> <func> - <name><ret>void *</ret><nametext>enif_alloc(size_t size)</nametext></name> + <name since=""><ret>void *</ret><nametext>enif_alloc(size_t size)</nametext></name> <fsummary>Allocate dynamic memory.</fsummary> <desc> <p>Allocates memory of <c>size</c> bytes.</p> @@ -960,7 +976,7 @@ typedef struct { </func> <func> - <name><ret>int</ret> + <name since=""><ret>int</ret> <nametext>enif_alloc_binary(size_t size, ErlNifBinary* bin)</nametext> </name> <fsummary>Create a new binary.</fsummary> @@ -984,10 +1000,10 @@ typedef struct { </func> <func> - <name><ret>ErlNifEnv *</ret><nametext>enif_alloc_env()</nametext></name> + <name since="OTP R14B"><ret>ErlNifEnv *</ret><nametext>enif_alloc_env()</nametext></name> <fsummary>Create a new environment.</fsummary> <desc> - <p>Allocates a new process-independent environment. The environment can + <p>Allocates a new process independent environment. The environment can be used to hold terms that are not bound to any process. Such terms can later be copied to a process environment with <seealso marker="#enif_make_copy"><c>enif_make_copy</c></seealso> or @@ -998,7 +1014,7 @@ typedef struct { </func> <func> - <name><ret>void *</ret><nametext>enif_alloc_resource(ErlNifResourceType* + <name since="OTP R13B04"><ret>void *</ret><nametext>enif_alloc_resource(ErlNifResourceType* type, unsigned size)</nametext></name> <fsummary>Allocate a memory-managed resource object.</fsummary> <desc> @@ -1008,7 +1024,7 @@ typedef struct { </func> <func> - <name><ret>size_t</ret><nametext>enif_binary_to_term(ErlNifEnv *env, + <name since="OTP 19.0"><ret>size_t</ret><nametext>enif_binary_to_term(ErlNifEnv *env, const unsigned char* data, size_t size, ERL_NIF_TERM *term, ErlNifBinaryToTerm opts)</nametext></name> <fsummary>Create a term from the external format.</fsummary> @@ -1033,7 +1049,7 @@ typedef struct { </func> <func> - <name><ret>void</ret><nametext>enif_clear_env(ErlNifEnv* env)</nametext> + <name since="OTP R14B"><ret>void</ret><nametext>enif_clear_env(ErlNifEnv* env)</nametext> </name> <fsummary>Clear an environment for reuse.</fsummary> <desc> @@ -1044,7 +1060,7 @@ typedef struct { </func> <func> - <name><ret>int</ret> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_compare(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs)</nametext> </name> <fsummary>Compare two terms.</fsummary> @@ -1059,7 +1075,7 @@ typedef struct { </func> <func> - <name><ret>int</ret><nametext>enif_compare_monitors(const ErlNifMonitor + <name since="OTP 20.0"><ret>int</ret><nametext>enif_compare_monitors(const ErlNifMonitor *monitor1, const ErlNifMonitor *monitor2)</nametext></name> <fsummary>Compare two monitors.</fsummary> <desc> @@ -1074,7 +1090,21 @@ typedef struct { </func> <func> - <name><ret>void</ret> + <name since="OTP 22.0"><ret>int</ret> + <nametext>enif_compare_pids(const ErlNifPid *pid1, const ErlNifPid *pid2) + </nametext></name> + <fsummary>Compare two pids.</fsummary> + <desc> + <p>Compares two <seealso marker="#ErlNifPid"><c>ErlNifPid</c> + </seealso>s according to term order.</p> + <p>Returns <c>0</c> if <c>pid1</c> and <c>pid2</c> are equal, + < <c>0</c> if <c>pid1</c> < <c>pid2</c>, and + > <c>0</c> if <c>pid1</c> > <c>pid2</c>.</p> + </desc> + </func> + + <func> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_cond_broadcast(ErlNifCond *cnd)</nametext></name> <fsummary></fsummary> <desc> @@ -1084,7 +1114,7 @@ typedef struct { </func> <func> - <name><ret>ErlNifCond *</ret> + <name since="OTP R13B04"><ret>ErlNifCond *</ret> <nametext>enif_cond_create(char *name)</nametext></name> <fsummary></fsummary> <desc> @@ -1094,7 +1124,7 @@ typedef struct { </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_cond_destroy(ErlNifCond *cnd)</nametext></name> <fsummary></fsummary> <desc> @@ -1104,7 +1134,7 @@ typedef struct { </func> <func> - <name><ret>char*</ret> + <name since="OTP 21.0"><ret>char*</ret> <nametext>enif_cond_name(ErlNifCond* cnd)</nametext></name> <fsummary></fsummary> <desc> @@ -1114,7 +1144,7 @@ typedef struct { </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_cond_signal(ErlNifCond *cnd)</nametext></name> <fsummary></fsummary> <desc> @@ -1124,7 +1154,7 @@ typedef struct { </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_cond_wait(ErlNifCond *cnd, ErlNifMutex *mtx)</nametext> </name> <fsummary></fsummary> @@ -1135,7 +1165,7 @@ typedef struct { </func> <func> - <name><ret>int</ret> + <name since="OTP R16B"><ret>int</ret> <nametext>enif_consume_timeslice(ErlNifEnv *env, int percent)</nametext> </name> <fsummary></fsummary> @@ -1170,7 +1200,7 @@ typedef struct { </func> <func> - <name><ret>ErlNifTime</ret><nametext>enif_convert_time_unit(ErlNifTime + <name since="OTP 18.3"><ret>ErlNifTime</ret><nametext>enif_convert_time_unit(ErlNifTime val, ErlNifTimeUnit from, ErlNifTimeUnit to)</nametext></name> <fsummary>Convert time unit of a time value.</fsummary> <desc> @@ -1195,7 +1225,7 @@ typedef struct { </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP 19.0"><ret>ERL_NIF_TERM</ret> <nametext>enif_cpu_time(ErlNifEnv *)</nametext></name> <fsummary></fsummary> <desc> @@ -1211,14 +1241,17 @@ typedef struct { </func> <func> - <name><ret>int</ret><nametext>enif_demonitor_process(ErlNifEnv* env, void* obj, - const ErlNifMonitor* mon)</nametext></name> + <name since="OTP 20.0"><ret>int</ret><nametext>enif_demonitor_process(ErlNifEnv* caller_env, + void* obj, const ErlNifMonitor* mon)</nametext></name> <fsummary>Cancel a process monitor.</fsummary> <desc> <marker id="enif_demonitor_process"></marker> <p>Cancels a monitor created earlier with <seealso marker="#enif_monitor_process"> <c>enif_monitor_process</c></seealso>. Argument <c>obj</c> is a pointer - to the resource holding the monitor and <c>*mon</c> identifies the monitor.</p> + to the resource holding the monitor and <c>*mon</c> identifies the + monitor.</p> + <p>Argument <c>caller_env</c> is the environment of the calling process + or callback. Must only be NULL if calling from a custom thread.</p> <p>Returns <c>0</c> if the monitor was successfully identified and removed. Returns a non-zero value if the monitor could not be identified, which means it was either</p> @@ -1235,7 +1268,7 @@ typedef struct { </func> <func> - <name><ret>int</ret> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2)</nametext> </name> <fsummary></fsummary> @@ -1246,19 +1279,20 @@ typedef struct { </func> <func> - <name><ret>int</ret><nametext>enif_fprintf(FILE *stream, const char *format, ...)</nametext></name> + <name since="OTP 21.0"><ret>int</ret><nametext>enif_fprintf(FILE *stream, const char *format, ...)</nametext></name> <fsummary>Format strings and Erlang terms.</fsummary> <desc> <p>Similar to <c>fprintf</c> but this format string also accepts - <c>"%T"</c>, which formats Erlang terms.</p> - <p>This function was originally intenden for debugging purpose. It is not + <c>"%T"</c>, which formats Erlang terms of type + <seealso marker="#ERL_NIF_TERM"><c>ERL_NIF_TERM</c></seealso>.</p> + <p>This function is primarily intended for debugging purpose. It is not recommended to print very large terms with <c>%T</c>. The function may change <c>errno</c>, even if successful.</p> </desc> </func> <func> - <name><ret>void</ret><nametext>enif_free(void* ptr)</nametext></name> + <name since=""><ret>void</ret><nametext>enif_free(void* ptr)</nametext></name> <fsummary>Free dynamic memory.</fsummary> <desc> <p>Frees memory allocated by @@ -1267,7 +1301,7 @@ typedef struct { </func> <func> - <name><ret>void</ret> + <name since="OTP R14B"><ret>void</ret> <nametext>enif_free_env(ErlNifEnv* env)</nametext></name> <fsummary>Free an environment allocated with enif_alloc_env.</fsummary> <desc> @@ -1278,7 +1312,7 @@ typedef struct { </func> <func> - <name><ret>void</ret> + <name since="OTP 20.1"><ret>void</ret> <nametext>enif_free_iovec(ErlNifIOvec* iov)</nametext></name> <fsummary>Free an ErlIOVec</fsummary> <desc> @@ -1303,7 +1337,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_atom(ErlNifEnv* env, ERL_NIF_TERM + <name since="OTP R13B04"><ret>int</ret><nametext>enif_get_atom(ErlNifEnv* env, ERL_NIF_TERM term, char* buf, unsigned size, ErlNifCharEncoding encode)</nametext> </name> <fsummary>Get the text representation of an atom term.</fsummary> @@ -1319,7 +1353,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_atom_length(ErlNifEnv* env, + <name since="OTP R14B"><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> @@ -1333,7 +1367,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_double(ErlNifEnv* env, + <name since="OTP R13B04"><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> <desc> @@ -1344,7 +1378,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_int(ErlNifEnv* env, ERL_NIF_TERM + <name since=""><ret>int</ret><nametext>enif_get_int(ErlNifEnv* env, ERL_NIF_TERM term, int* ip)</nametext></name> <fsummary>Read an integer term.</fsummary> <desc> @@ -1355,7 +1389,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_int64(ErlNifEnv* env, ERL_NIF_TERM + <name since="OTP R14B"><ret>int</ret><nametext>enif_get_int64(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifSInt64* ip)</nametext></name> <fsummary>Read a 64-bit integer term.</fsummary> <desc> @@ -1366,7 +1400,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_local_pid(ErlNifEnv* env, + <name since="OTP R14B"><ret>int</ret><nametext>enif_get_local_pid(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifPid* pid)</nametext></name> <fsummary>Read a local pid term.</fsummary> <desc> @@ -1374,11 +1408,14 @@ enif_free_iovec(iovec);]]></code> initializes the pid variable <c>*pid</c> from it and returns <c>true</c>. Otherwise returns <c>false</c>. No check is done to see if the process is alive.</p> + <note><p><c>enif_get_local_pid</c> will return false if argument + <c>term</c> is the atom <seealso marker="#enif_make_pid"> + <c>undefined</c></seealso>.</p></note> </desc> </func> <func> - <name><ret>int</ret><nametext>enif_get_local_port(ErlNifEnv* env, + <name since="OTP 19.0"><ret>int</ret><nametext>enif_get_local_port(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifPort* port_id)</nametext></name> <fsummary>Read a local port term.</fsummary> <desc> @@ -1390,7 +1427,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_list_cell(ErlNifEnv* env, + <name since=""><ret>int</ret><nametext>enif_get_list_cell(ErlNifEnv* env, ERL_NIF_TERM list, ERL_NIF_TERM* head, ERL_NIF_TERM* tail)</nametext> </name> <fsummary>Get head and tail from a list.</fsummary> @@ -1402,7 +1439,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_list_length(ErlNifEnv* env, + <name since="OTP R14B"><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> <desc> @@ -1413,7 +1450,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_long(ErlNifEnv* env, ERL_NIF_TERM + <name since="OTP R13B04"><ret>int</ret><nametext>enif_get_long(ErlNifEnv* env, ERL_NIF_TERM term, long int* ip)</nametext></name> <fsummary>Read a long integer term.</fsummary> <desc> @@ -1424,7 +1461,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_map_size(ErlNifEnv* env, + <name since="OTP 18.0"><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> @@ -1436,7 +1473,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_map_value(ErlNifEnv* env, + <name since="OTP 18.0"><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> @@ -1449,7 +1486,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_resource(ErlNifEnv* env, + <name since="OTP R13B04"><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> @@ -1458,11 +1495,14 @@ enif_free_iovec(iovec);]]></code> <c>term</c>.</p> <p>Returns <c>true</c> on success, or <c>false</c> if <c>term</c> is not a handle to a resource object of type <c>type</c>.</p> + <p><c>enif_get_resource</c> does not add a reference to the resource + object. However, the pointer received in <c>*objp</c> is guaranteed to + be valid at least as long as the resource handle <c>term</c> is valid.</p> </desc> </func> <func> - <name><ret>int</ret><nametext>enif_get_string(ErlNifEnv* env, + <name since="OTP R13B04"><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> @@ -1486,7 +1526,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_tuple(ErlNifEnv* env, ERL_NIF_TERM + <name since="OTP R13B04"><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> <desc> @@ -1502,7 +1542,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_uint(ErlNifEnv* env, ERL_NIF_TERM + <name since="OTP R13B04"><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> <desc> @@ -1514,7 +1554,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_uint64(ErlNifEnv* env, + <name since="OTP R14B"><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> <desc> @@ -1526,7 +1566,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_get_ulong(ErlNifEnv* env, ERL_NIF_TERM + <name since=""><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> <desc> @@ -1539,7 +1579,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_getenv(const char* key, char* value, + <name since="OTP 18.2"><ret>int</ret><nametext>enif_getenv(const char* key, char* value, size_t *value_size)</nametext></name> <fsummary>Get the value of an environment variable.</fsummary> <desc> @@ -1549,7 +1589,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_has_pending_exception(ErlNifEnv* env, + <name since="OTP 18.0"><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> @@ -1570,7 +1610,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name> + <name since="OTP 20.0"> <ret>ErlNifUInt64</ret> <nametext>enif_hash(ErlNifHash type, ERL_NIF_TERM term, ErlNifUInt64 salt)</nametext> </name> @@ -1583,7 +1623,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_inspect_binary(ErlNifEnv* env, + <name since=""><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> <desc> @@ -1595,7 +1635,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_inspect_iolist_as_binary(ErlNifEnv* + <name since="OTP R13B04"><ret>int</ret><nametext>enif_inspect_iolist_as_binary(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifBinary* bin)</nametext></name> <fsummary>Inspect the content of an iolist.</fsummary> <desc> @@ -1609,7 +1649,7 @@ enif_free_iovec(iovec);]]></code> </func> <func> - <name><ret>int</ret><nametext>enif_inspect_iovec(ErlNifEnv* + <name since="OTP 20.1"><ret>int</ret><nametext>enif_inspect_iovec(ErlNifEnv* env, size_t max_elements, ERL_NIF_TERM iovec_term, ERL_NIF_TERM* tail, ErlNifIOVec** iovec)</nametext></name> <fsummary>Inspect a list of binaries as an ErlNifIOVec.</fsummary> @@ -1649,7 +1689,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ErlNifIOQueue *</ret> + <name since="OTP 20.1"><ret>ErlNifIOQueue *</ret> <nametext>enif_ioq_create(ErlNifIOQueueOpts opts)</nametext></name> <fsummary>Create a new IO Queue</fsummary> <desc> @@ -1660,7 +1700,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>void</ret> + <name since="OTP 20.1"><ret>void</ret> <nametext>enif_ioq_destroy(ErlNifIOQueue *q)</nametext></name> <fsummary>Destroy an IO Queue and free it's content</fsummary> <desc> @@ -1669,7 +1709,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP 20.1"><ret>int</ret> <nametext>enif_ioq_deq(ErlNifIOQueue *q, size_t count, size_t *size)</nametext></name> <fsummary>Dequeue count bytes from the IO Queue</fsummary> <desc> @@ -1682,7 +1722,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP 20.1"><ret>int</ret> <nametext>enif_ioq_enq_binary(ErlNifIOQueue *q, ErlNifBinary *bin, size_t skip)</nametext></name> <fsummary>Enqueue the binary into the IO Queue</fsummary> <desc> @@ -1695,7 +1735,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP 20.1"><ret>int</ret> <nametext>enif_ioq_enqv(ErlNifIOQueue *q, ErlNifIOVec *iovec, size_t skip)</nametext></name> <fsummary>Enqueue the iovec into the IO Queue</fsummary> <desc> @@ -1706,7 +1746,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>SysIOVec *</ret> + <name since="OTP 20.1"><ret>SysIOVec *</ret> <nametext>enif_ioq_peek(ErlNifIOQueue *q, int *iovlen)</nametext></name> <fsummary>Peek inside the IO Queue</fsummary> <desc> @@ -1720,7 +1760,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP 21.0"><ret>int</ret> <nametext>enif_ioq_peek_head(ErlNifEnv *env, ErlNifIOQueue *q, size_t *size, ERL_NIF_TERM *bin_term)</nametext></name> <fsummary>Peek the head of the IO Queue.</fsummary> <desc> @@ -1735,7 +1775,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>size_t</ret> + <name since="OTP 20.1"><ret>size_t</ret> <nametext>enif_ioq_size(ErlNifIOQueue *q)</nametext></name> <fsummary>Get the current size of the IO Queue</fsummary> <desc> @@ -1744,7 +1784,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_is_atom(ErlNifEnv* env, ERL_NIF_TERM term)</nametext> </name> <fsummary>Determine if a term is an atom.</fsummary> @@ -1754,7 +1794,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since=""><ret>int</ret> <nametext>enif_is_binary(ErlNifEnv* env, ERL_NIF_TERM term)</nametext> </name> <fsummary>Determine if a term is a binary.</fsummary> @@ -1764,7 +1804,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP 19.0"><ret>int</ret> <nametext>enif_is_current_process_alive(ErlNifEnv* env)</nametext> </name> <fsummary>Determine if currently executing process is alive.</fsummary> @@ -1777,7 +1817,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_is_empty_list(ErlNifEnv* env, + <name since="OTP R13B04"><ret>int</ret><nametext>enif_is_empty_list(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name> <fsummary>Determine if a term is an empty list.</fsummary> <desc> @@ -1786,7 +1826,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_is_exception(ErlNifEnv* env, + <name since="OTP R14B03"><ret>int</ret><nametext>enif_is_exception(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name> <fsummary>Determine if a term is an exception.</fsummary> <desc><marker id="enif_is_exception"/> @@ -1795,7 +1835,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_is_fun(ErlNifEnv* env, ERL_NIF_TERM + <name since="OTP R13B04"><ret>int</ret><nametext>enif_is_fun(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name> <fsummary>Determine if a term is a fun.</fsummary> <desc> @@ -1804,7 +1844,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_is_identical(ERL_NIF_TERM lhs, + <name since="OTP R13B04"><ret>int</ret><nametext>enif_is_identical(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs)</nametext></name> <fsummary>Erlang operator =:=.</fsummary> <desc> @@ -1814,7 +1854,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP R14B"><ret>int</ret> <nametext>enif_is_list(ErlNifEnv* env, ERL_NIF_TERM term)</nametext> </name> <fsummary>Determine if a term is a list.</fsummary> @@ -1824,7 +1864,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_is_map(ErlNifEnv* env, ERL_NIF_TERM + <name since="OTP 18.0"><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> @@ -1834,7 +1874,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_is_number(ErlNifEnv* env, ERL_NIF_TERM + <name since="OTP R15B"><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> @@ -1843,7 +1883,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_is_pid(ErlNifEnv* env, ERL_NIF_TERM term)</nametext> </name> <fsummary>Determine if a term is a pid.</fsummary> @@ -1853,7 +1893,18 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP 22.0"><ret>int</ret> + <nametext>enif_is_pid_undefined(const ErlNifPid* pid)</nametext></name> + <fsummary>Determine if pid is undefined.</fsummary> + <desc> + <p>Returns <c>true</c> if <c>pid</c> has been set as undefined by + <seealso marker="#enif_set_pid_undefined"><c>enif_set_pid_undefined</c> + </seealso>.</p> + </desc> + </func> + + <func> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_is_port(ErlNifEnv* env, ERL_NIF_TERM term)</nametext> </name> <fsummary>Determine if a term is a port.</fsummary> @@ -1863,7 +1914,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_is_port_alive(ErlNifEnv* env, + <name since="OTP 19.0"><ret>int</ret><nametext>enif_is_port_alive(ErlNifEnv* env, ErlNifPort *port_id)</nametext></name> <fsummary>Determine if a local port is alive.</fsummary> <desc> @@ -1875,7 +1926,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_is_process_alive(ErlNifEnv* env, + <name since="OTP 19.0"><ret>int</ret><nametext>enif_is_process_alive(ErlNifEnv* env, ErlNifPid *pid)</nametext></name> <fsummary>Determine if a local process is alive.</fsummary> <desc> @@ -1887,7 +1938,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term)</nametext> </name> <fsummary>Determine if a term is a reference.</fsummary> @@ -1897,7 +1948,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP R14B"><ret>int</ret> <nametext>enif_is_tuple(ErlNifEnv* env, ERL_NIF_TERM term)</nametext> </name> <fsummary>Determine if a term is a tuple.</fsummary> @@ -1907,7 +1958,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP R14B"><ret>int</ret> <nametext>enif_keep_resource(void* obj)</nametext> </name> <fsummary>Add a reference to a resource object.</fsummary> @@ -1923,7 +1974,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since=""><ret>ERL_NIF_TERM</ret> <nametext>enif_make_atom(ErlNifEnv* env, const char* name)</nametext> </name> <fsummary>Create an atom term.</fsummary> @@ -1937,7 +1988,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_atom_len(ErlNifEnv* env, + <name since="OTP R14B"><ret>ERL_NIF_TERM</ret><nametext>enif_make_atom_len(ErlNifEnv* env, const char* name, size_t len)</nametext></name> <fsummary>Create an atom term.</fsummary> <desc> @@ -1951,7 +2002,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since=""><ret>ERL_NIF_TERM</ret> <nametext>enif_make_badarg(ErlNifEnv* env)</nametext></name> <fsummary>Make a badarg exception.</fsummary> <desc> @@ -1979,7 +2030,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since=""><ret>ERL_NIF_TERM</ret> <nametext>enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)</nametext> </name> <fsummary>Make a binary term.</fsummary> @@ -1992,7 +2043,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_copy(ErlNifEnv* dst_env, + <name since="OTP R14B"><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> <desc> @@ -2003,7 +2054,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret> <nametext>enif_make_double(ErlNifEnv* env, double d)</nametext></name> <fsummary>Create a floating-point term.</fsummary> <desc> @@ -2015,7 +2066,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_make_existing_atom(ErlNifEnv* env, + <name since="OTP R13B04"><ret>int</ret><nametext>enif_make_existing_atom(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom, ErlNifCharEncoding encode)</nametext></name> <fsummary>Create an existing atom term.</fsummary> @@ -2031,7 +2082,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_make_existing_atom_len(ErlNifEnv* env, + <name since="OTP R14B"><ret>int</ret><nametext>enif_make_existing_atom_len(ErlNifEnv* env, const char* name, size_t len, ERL_NIF_TERM* atom, ErlNifCharEncoding encoding)</nametext></name> <fsummary>Create an existing atom term.</fsummary> @@ -2047,7 +2098,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </desc> </func> - <func><name><ret>ERL_NIF_TERM</ret> + <func><name since=""><ret>ERL_NIF_TERM</ret> <nametext>enif_make_int(ErlNifEnv* env, int i)</nametext></name> <fsummary>Create an integer term.</fsummary> <desc> @@ -2056,7 +2107,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP R14B"><ret>ERL_NIF_TERM</ret> <nametext>enif_make_int64(ErlNifEnv* env, ErlNifSInt64 i)</nametext> </name> <fsummary>Create an integer term.</fsummary> @@ -2066,7 +2117,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since=""><ret>ERL_NIF_TERM</ret> <nametext>enif_make_list(ErlNifEnv* env, unsigned cnt, ...)</nametext> </name> <fsummary>Create a list term.</fsummary> @@ -2079,24 +2130,24 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret> <nametext>enif_make_list1(ErlNifEnv* env, ERL_NIF_TERM e1)</nametext> </name> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list2(ErlNifEnv* env, + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret><nametext>enif_make_list2(ErlNifEnv* env, ERL_NIF_TERM e1, ERL_NIF_TERM e2)</nametext></name> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list3(ErlNifEnv* env, + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret><nametext>enif_make_list3(ErlNifEnv* env, ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3)</nametext></name> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list4(ErlNifEnv* env, + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret><nametext>enif_make_list4(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4)</nametext></name> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list5(ErlNifEnv* env, + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret><nametext>enif_make_list5(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5)</nametext></name> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list6(ErlNifEnv* env, + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret><nametext>enif_make_list6(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6)</nametext></name> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list7(ErlNifEnv* env, + <name since="OTP R13B04"><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, + <name since="OTP R13B04"><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, + <name since="OTP R13B04"><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> <desc> @@ -2108,7 +2159,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list_cell(ErlNifEnv* + <name since=""><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> <desc> @@ -2117,7 +2168,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP R13B04"><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> @@ -2129,7 +2180,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP R13B04"><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> @@ -2138,7 +2189,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_make_map_put(ErlNifEnv* env, + <name since="OTP 18.0"><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> @@ -2154,7 +2205,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_make_map_remove(ErlNifEnv* env, + <name since="OTP 18.0"><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> @@ -2170,7 +2221,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_make_map_update(ErlNifEnv* env, + <name since="OTP 18.0"><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> @@ -2185,7 +2236,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP 21.0"><ret>int</ret> <nametext>enif_make_map_from_arrays(ErlNifEnv* env, ERL_NIF_TERM keys[], ERL_NIF_TERM values[], size_t cnt, ERL_NIF_TERM *map_out)</nametext></name> <fsummary>Make map term from the given keys and values.</fsummary> @@ -2199,7 +2250,19 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>unsigned char *</ret><nametext>enif_make_new_binary(ErlNifEnv* + <name since="OTP 22.0"><ret>ERL_NIF_TERM</ret> + <nametext>enif_make_monitor_term(ErlNifEnv* env, const ErlNifMonitor* mon)</nametext></name> + <fsummary>Make monitor term from the given monitor identifier.</fsummary> + <desc> + <p>Creates a term identifying the given monitor received from + <seealso marker="#enif_monitor_process"><c>enif_monitor_process</c> + </seealso>.</p> + <p>This function is primarily intended for debugging purpose.</p> + </desc> + </func> + + <func> + <name since="OTP R14B"><ret>unsigned char *</ret><nametext>enif_make_new_binary(ErlNifEnv* env, size_t size, ERL_NIF_TERM* termp)</nametext></name> <fsummary>Allocate and create a new binary term.</fsummary> <desc> @@ -2215,7 +2278,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP 18.0"><ret>ERL_NIF_TERM</ret> <nametext>enif_make_new_map(ErlNifEnv* env)</nametext></name> <fsummary>Make an empty map term.</fsummary> <desc> @@ -2224,17 +2287,18 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP R14B"><ret>ERL_NIF_TERM</ret> <nametext>enif_make_pid(ErlNifEnv* env, const ErlNifPid* pid)</nametext> </name> <fsummary>Make a pid term.</fsummary> <desc> - <p>Makes a pid term from <c>*pid</c>.</p> + <p>Makes a pid term or the atom <seealso marker="#enif_set_pid_undefined"> + <c>undefined</c></seealso> from <c>*pid</c>.</p> </desc> </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret> <nametext>enif_make_ref(ErlNifEnv* env)</nametext></name> <fsummary>Create a reference.</fsummary> <desc> @@ -2244,7 +2308,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret> <nametext>enif_make_resource(ErlNifEnv* env, void* obj)</nametext> </name> <fsummary>Create an opaque handle to a resource object.</fsummary> @@ -2267,7 +2331,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); between nodes.</p> <list type="bulleted"> <item> - <p>Two resource terms will compare equal iff they + <p>Two resource terms will compare equal if and only if they would yield the same resource object pointer when passed to <seealso marker="#enif_get_resource"><c>enif_get_resource</c></seealso>.</p> </item> @@ -2292,7 +2356,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP R14B"><ret>ERL_NIF_TERM</ret> <nametext>enif_make_resource_binary(ErlNifEnv* env, void* obj, const void* data, size_t size)</nametext></name> <fsummary>Create a custom binary term.</fsummary> @@ -2318,7 +2382,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret> + <name since="OTP R15B"><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> @@ -2334,7 +2398,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_string(ErlNifEnv* env, + <name since=""><ret>ERL_NIF_TERM</ret><nametext>enif_make_string(ErlNifEnv* env, const char* string, ErlNifCharEncoding encoding)</nametext></name> <fsummary>Create a string.</fsummary> <desc> @@ -2345,7 +2409,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_string_len(ErlNifEnv* + <name since="OTP R14B"><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> @@ -2358,7 +2422,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_sub_binary(ErlNifEnv* + <name since="OTP R13B04"><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> <desc> @@ -2370,7 +2434,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple(ErlNifEnv* env, + <name since=""><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)</nametext></name> <fsummary>Creates a tuple term.</fsummary> <desc> @@ -2381,23 +2445,23 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple1(ErlNifEnv* env, + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple1(ErlNifEnv* env, ERL_NIF_TERM e1)</nametext></name> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple2(ErlNifEnv* env, + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple2(ErlNifEnv* env, ERL_NIF_TERM e1, ERL_NIF_TERM e2)</nametext></name> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple3(ErlNifEnv* env, + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple3(ErlNifEnv* env, ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3)</nametext></name> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple4(ErlNifEnv* env, + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple4(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4)</nametext></name> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple5(ErlNifEnv* env, + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple5(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5)</nametext></name> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple6(ErlNifEnv* env, + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple6(ErlNifEnv* env, ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6)</nametext></name> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple7(ErlNifEnv* env, + <name since="OTP R13B04"><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, + <name since="OTP R13B04"><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, + <name since="OTP R13B04"><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> <desc> @@ -2409,7 +2473,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP R13B04"><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> @@ -2420,7 +2484,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP R13B04"><ret>ERL_NIF_TERM</ret> <nametext>enif_make_uint(ErlNifEnv* env, unsigned int i)</nametext> </name> <fsummary>Create an unsigned integer term.</fsummary> @@ -2430,7 +2494,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP R14B"><ret>ERL_NIF_TERM</ret> <nametext>enif_make_uint64(ErlNifEnv* env, ErlNifUInt64 i)</nametext> </name> <fsummary>Create an unsigned integer term.</fsummary> @@ -2440,7 +2504,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since=""><ret>ERL_NIF_TERM</ret> <nametext>enif_make_ulong(ErlNifEnv* env, unsigned long i)</nametext> </name> <fsummary>Create an integer term from an unsigned long int.</fsummary> @@ -2450,7 +2514,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_unique_integer(ErlNifEnv + <name since="OTP 19.0"><ret>ERL_NIF_TERM</ret><nametext>enif_make_unique_integer(ErlNifEnv *env, ErlNifUniqueInteger properties)</nametext></name> <fsummary></fsummary> <desc> @@ -2468,7 +2532,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> - <name><ret>int</ret><nametext>enif_map_iterator_create(ErlNifEnv *env, + <name since="OTP 18.0"><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> @@ -2503,7 +2567,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void</ret><nametext>enif_map_iterator_destroy(ErlNifEnv *env, + <name since="OTP 18.0"><ret>void</ret><nametext>enif_map_iterator_destroy(ErlNifEnv *env, ErlNifMapIterator *iter)</nametext></name> <fsummary>Destroy a map iterator.</fsummary> <desc> @@ -2514,7 +2578,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>int</ret><nametext>enif_map_iterator_get_pair(ErlNifEnv *env, + <name since="OTP 18.0"><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> @@ -2527,7 +2591,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>int</ret><nametext>enif_map_iterator_is_head(ErlNifEnv *env, + <name since="OTP 18.0"><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> @@ -2537,7 +2601,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>int</ret><nametext>enif_map_iterator_is_tail(ErlNifEnv *env, + <name since="OTP 18.0"><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> @@ -2547,7 +2611,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>int</ret><nametext>enif_map_iterator_next(ErlNifEnv *env, + <name since="OTP 18.0"><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> @@ -2559,7 +2623,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>int</ret><nametext>enif_map_iterator_prev(ErlNifEnv *env, + <name since="OTP 18.0"><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> @@ -2571,8 +2635,8 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>int</ret><nametext>enif_monitor_process(ErlNifEnv* env, void* obj, - const ErlNifPid* target_pid, ErlNifMonitor* mon)</nametext></name> + <name since="OTP 20.0"><ret>int</ret><nametext>enif_monitor_process(ErlNifEnv* caller_env, + void* obj, const ErlNifPid* target_pid, ErlNifMonitor* mon)</nametext></name> <fsummary>Monitor a process from a resource.</fsummary> <desc> <marker id="enif_monitor_process"></marker> @@ -2592,8 +2656,12 @@ enif_map_iterator_destroy(env, &iter);</code> <seealso marker="#enif_compare_monitors"><c>enif_compare_monitors</c></seealso>. A monitor is automatically removed when it triggers or when the resource is deallocated.</p> + <p>Argument <c>caller_env</c> is the environment of the calling process + or callback. Must only be NULL if calling from a custom thread.</p> <p>Returns <c>0</c> on success, < 0 if no <c>down</c> callback is - provided, and > 0 if the process is no longer alive.</p> + provided, and > 0 if the process is no longer alive or if + <c>target_pid</c> is <seealso marker="#enif_set_pid_undefined"> + undefined</seealso>.</p> <p>This function is only thread-safe when the emulator with SMP support is used. It can only be used in a non-SMP emulator from a NIF-calling thread.</p> @@ -2601,7 +2669,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>ErlNifTime</ret> + <name since="OTP 18.3"><ret>ErlNifTime</ret> <nametext>enif_monotonic_time(ErlNifTimeUnit time_unit)</nametext> </name> <fsummary>Get Erlang monotonic time.</fsummary> @@ -2622,7 +2690,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>ErlNifMutex *</ret> + <name since="OTP R13B04"><ret>ErlNifMutex *</ret> <nametext>enif_mutex_create(char *name)</nametext></name> <fsummary></fsummary> <desc> @@ -2632,7 +2700,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_mutex_destroy(ErlNifMutex *mtx)</nametext></name> <fsummary></fsummary> <desc> @@ -2642,7 +2710,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_mutex_lock(ErlNifMutex *mtx)</nametext></name> <fsummary></fsummary> <desc> @@ -2652,7 +2720,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>char*</ret> + <name since="OTP 21.0"><ret>char*</ret> <nametext>enif_mutex_name(ErlNifMutex* mtx)</nametext></name> <fsummary></fsummary> <desc> @@ -2662,7 +2730,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>int</ret> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_mutex_trylock(ErlNifMutex *mtx)</nametext></name> <fsummary></fsummary> <desc> @@ -2672,7 +2740,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_mutex_unlock(ErlNifMutex *mtx)</nametext></name> <fsummary></fsummary> <desc> @@ -2682,7 +2750,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>ERL_NIF_TERM</ret> + <name since="OTP 19.0"><ret>ERL_NIF_TERM</ret> <nametext>enif_now_time(ErlNifEnv *env)</nametext></name> <fsummary></fsummary> <desc> @@ -2693,7 +2761,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>ErlNifResourceType *</ret> + <name since="OTP R13B04"><ret>ErlNifResourceType *</ret> <nametext>enif_open_resource_type(ErlNifEnv* env, const char* module_str, const char* name, ErlNifResourceDtor* dtor, ErlNifResourceFlags flags, ErlNifResourceFlags* tried)</nametext> @@ -2732,7 +2800,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>ErlNifResourceType *</ret> + <name since="OTP 20.0"><ret>ErlNifResourceType *</ret> <nametext>enif_open_resource_type_x(ErlNifEnv* env, const char* name, const ErlNifResourceTypeInit* init, ErlNifResourceFlags flags, ErlNifResourceFlags* tried)</nametext> @@ -2751,7 +2819,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>int</ret><nametext>enif_port_command(ErlNifEnv* env, const + <name since="OTP 19.0"><ret>int</ret><nametext>enif_port_command(ErlNifEnv* env, const ErlNifPort* to_port, ErlNifEnv *msg_env, ERL_NIF_TERM msg)</nametext> </name> <fsummary>Send a port_command to to_port.</fsummary> @@ -2767,7 +2835,7 @@ enif_map_iterator_destroy(env, &iter);</code> <item>The port ID of the receiving port. The port ID is to refer to a port on the local node.</item> <tag><c>msg_env</c></tag> - <item>The environment of the message term. Can be a process-independent + <item>The environment of the message term. Can be a process independent environment allocated with <seealso marker="#enif_alloc_env"> <c>enif_alloc_env</c></seealso> or <c>NULL</c>.</item> <tag><c>msg</c></tag> @@ -2794,7 +2862,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void *</ret> + <name since="OTP R13B04"><ret>void *</ret> <nametext>enif_priv_data(ErlNifEnv* env)</nametext></name> <fsummary>Get the private data of a NIF library.</fsummary> <desc> @@ -2805,7 +2873,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_raise_exception(ErlNifEnv* + <name since="OTP 18.0"><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> @@ -2828,7 +2896,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void *</ret> + <name since="OTP 20.2"><ret>void *</ret> <nametext>enif_realloc(void* ptr, size_t size)</nametext></name> <fsummary>Reallocate dynamic memory.</fsummary> <desc> @@ -2842,7 +2910,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>int</ret> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_realloc_binary(ErlNifBinary* bin, size_t size)</nametext> </name> <fsummary>Change the size of a binary.</fsummary> @@ -2856,7 +2924,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void</ret> + <name since=""><ret>void</ret> <nametext>enif_release_binary(ErlNifBinary* bin)</nametext></name> <fsummary>Release a binary.</fsummary> <desc> @@ -2867,7 +2935,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_release_resource(void* obj)</nametext></name> <fsummary>Release a resource object.</fsummary> <desc> @@ -2882,11 +2950,15 @@ enif_map_iterator_destroy(env, &iter);</code> References made by <seealso marker="#enif_make_resource"> <c>enif_make_resource</c></seealso> can only be removed by the garbage collector.</p> + <p>There are no guarantees exactly when the destructor of an + unreferenced resource is called. It could be called directly by + <c>enif_release_resource</c> but it could also be scheduled to be + called at a later time possibly by another thread.</p> </desc> </func> <func> - <name><ret>ErlNifRWLock *</ret> + <name since="OTP R13B04"><ret>ErlNifRWLock *</ret> <nametext>enif_rwlock_create(char *name)</nametext></name> <fsummary></fsummary> <desc> @@ -2896,7 +2968,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_rwlock_destroy(ErlNifRWLock *rwlck)</nametext></name> <fsummary></fsummary> <desc> @@ -2906,7 +2978,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>char*</ret> + <name since="OTP 21.0"><ret>char*</ret> <nametext>enif_rwlock_name(ErlNifRWLock* rwlck)</nametext></name> <fsummary></fsummary> <desc> @@ -2916,7 +2988,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_rwlock_rlock(ErlNifRWLock *rwlck)</nametext></name> <fsummary></fsummary> <desc> @@ -2926,7 +2998,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_rwlock_runlock(ErlNifRWLock *rwlck)</nametext></name> <fsummary></fsummary> <desc> @@ -2936,7 +3008,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_rwlock_rwlock(ErlNifRWLock *rwlck)</nametext></name> <fsummary></fsummary> <desc> @@ -2946,7 +3018,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_rwlock_rwunlock(ErlNifRWLock *rwlck)</nametext></name> <fsummary></fsummary> <desc> @@ -2956,7 +3028,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>int</ret> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_rwlock_tryrlock(ErlNifRWLock *rwlck)</nametext></name> <fsummary></fsummary> <desc> @@ -2966,7 +3038,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>int</ret> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_rwlock_tryrwlock(ErlNifRWLock *rwlck)</nametext></name> <fsummary></fsummary> <desc> @@ -2976,7 +3048,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>ERL_NIF_TERM</ret><nametext>enif_schedule_nif(ErlNifEnv* env, + <name since="OTP 17.3"><ret>ERL_NIF_TERM</ret><nametext>enif_schedule_nif(ErlNifEnv* env, const char* fun_name, int flags, ERL_NIF_TERM (*fp)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]), int argc, const ERL_NIF_TERM argv[])</nametext></name> @@ -3021,7 +3093,7 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> - <name><ret>int</ret> + <name since="OTP 20.0"><ret>int</ret> <nametext>enif_select(ErlNifEnv* env, ErlNifEvent event, enum ErlNifSelectFlags mode, void* obj, const ErlNifPid* pid, ERL_NIF_TERM ref)</nametext> </name> @@ -3036,13 +3108,21 @@ enif_map_iterator_destroy(env, &iter);</code> <p>Argument <c>mode</c> describes the type of events to wait for. It can be <c>ERL_NIF_SELECT_READ</c>, <c>ERL_NIF_SELECT_WRITE</c> or a bitwise OR combination to wait for both. It can also be <c>ERL_NIF_SELECT_STOP</c> - which is described further below. When a read or write event is triggered, + or <c>ERL_NIF_SELECT_CANCEL</c> which are described further + below. When a read or write event is triggered, a notification message like this is sent to the process identified by <c>pid</c>:</p> <code type="none">{select, Obj, Ref, ready_input | ready_output}</code> <p><c>ready_input</c> or <c>ready_output</c> indicates if the event object is ready for reading or writing.</p> - <p>Argument <c>pid</c> may be <c>NULL</c> to indicate the calling process.</p> + <note><p>For complete control over the message format use the newer functions + <seealso marker="#enif_select_read"><c>enif_select_read</c></seealso> or + <seealso marker="#enif_select_write"><c>enif_select_write</c></seealso> + introduced in erts-11.0 (OTP-22.0).</p> + </note> + <p>Argument <c>pid</c> may be <c>NULL</c> to indicate the calling + process. It must not be set as <seealso marker="#enif_set_pid_undefined"> + undefined</seealso>.</p> <p>Argument <c>obj</c> is a resource object obtained from <seealso marker="#enif_alloc_resource"><c>enif_alloc_resource</c></seealso>. The purpose of the resource objects is as a container of the event object @@ -3053,17 +3133,29 @@ enif_map_iterator_destroy(env, &iter);</code> or the atom <c>undefined</c>. It will be passed as <c>Ref</c> in the notifications. If a selective <c>receive</c> statement is used to wait for the notification then a reference created just before the <c>receive</c> will exploit a runtime - optimization that bypasses all earlier received messages in the queue.</p> + optimization that bypasses all earlier received messages in the + queue.</p> <p>The notifications are one-shot only. To receive further notifications of the same type (read or write), repeated calls to <c>enif_select</c> must be made after receiving each notification.</p> + <p><c>ERL_NIF_SELECT_CANCEL</c> can be used to cancel previously + selected events. It must be used in a bitwise OR combination with + <c>ERL_NIF_SELECT_READ</c> and/or <c>ERL_NIF_SELECT_WRITE</c> to + indicate which type of event to cancel. Arguments <c>pid</c> and + <c>ref</c> are ignored when <c>ERL_NIF_SELECT_CANCEL</c> is specified. + The return value will tell if the event was actualy cancelled or if a + notification may already have been sent.</p> <p>Use <c>ERL_NIF_SELECT_STOP</c> as <c>mode</c> in order to safely close an event object that has been passed to <c>enif_select</c>. The <seealso marker="#ErlNifResourceStop"><c>stop</c></seealso> callback of the resource <c>obj</c> will be called when it is safe to close the event object. This safe way of closing event objects must be used - even if all notifications have been received and no further calls to - <c>enif_select</c> have been made.</p> + even if all notifications have been received (or cancelled) and no + further calls to <c>enif_select</c> have been made. + <c>ERL_NIF_SELECT_STOP</c> will first cancel any selected events + before it calls or schedules the <c>stop</c> callback. Arguments + <c>pid</c> and <c>ref</c> are ignored when <c>ERL_NIF_SELECT_STOP</c> + is specified.</p> <p>The first call to <c>enif_select</c> for a specific OS <c>event</c> will establish a relation between the event object and the containing resource. All subsequent calls for an <c>event</c> must pass its containing resource as argument @@ -3085,7 +3177,15 @@ enif_map_iterator_destroy(env, &iter);</code> <item>The stop callback was called directly by <c>enif_select</c>.</item> <tag><c>ERL_NIF_SELECT_STOP_SCHEDULED</c></tag> <item>The stop callback was scheduled to run on some other thread - or later by this thread.</item> + or later by this thread.</item> + <tag><c>ERL_NIF_SELECT_READ_CANCELLED</c></tag> + <item>A read event was cancelled by <c>ERL_NIF_SELECT_CANCEL</c> or + <c>ERL_NIF_SELECT_STOP</c> and is guaranteed not to generate a + <c>ready_input</c> notification message.</item> + <tag><c>ERL_NIF_SELECT_WRITE_CANCELLED</c></tag> + <item>A write event was cancelled by <c>ERL_NIF_SELECT_CANCEL</c> or + <c>ERL_NIF_SELECT_STOP</c> and is guaranteed not to generate a + <c>ready_output</c> notification message.</item> </taglist> <p>Returns a negative value if the call failed where the following bits can be set:</p> <taglist> @@ -3111,11 +3211,48 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { } </code> </note> + <note><p>The mode flag <c>ERL_NIF_SELECT_CANCEL</c> and the return flags + <c>ERL_NIF_SELECT_READ_CANCELLED</c> and + <c>ERL_NIF_SELECT_WRITE_CANCELLED</c> were introduced in erts-11.0 + (OTP-22.0).</p> + </note> </desc> </func> <func> - <name><ret>ErlNifPid *</ret> + <name since="OTP 22.0"><ret>int</ret> + <nametext>enif_select_read(ErlNifEnv* env, ErlNifEvent event, void* obj, + const ErlNifPid* pid, ERL_NIF_TERM msg, ErlNifEnv* msg_env)</nametext> + </name> + <name since="OTP 22.0"><ret>int</ret> + <nametext>enif_select_write(ErlNifEnv* env, ErlNifEvent event, void* obj, + const ErlNifPid* pid, ERL_NIF_TERM msg, ErlNifEnv* msg_env)</nametext> + </name> + <fsummary>Manage subscription on IO event.</fsummary> + <desc> + <p>These are variants of <seealso marker="#enif_select">enif_select</seealso> + where you can supply your own message term <c>msg</c> that will be sent to + the process instead of the predefined tuple <c>{select,_,_,_}.</c></p> + <p>Argument <c>msg_env</c> must either be <c>NULL</c> or the environment of + <c>msg</c> allocated with <seealso marker="#enif_alloc_env"> + <c>enif_alloc_env</c></seealso>. If argument <c>msg_env</c> is + <c>NULL</c> the term <c>msg</c> will be copied, otherwise both + <c>msg</c> and <c>msg_env</c> will be invalidated by a successful call + to <c>enif_select_read</c> or <c>enif_select_write</c>. The environment + is then to either be freed with <seealso marker="#enif_free_env"> + <c>enif_free_env</c></seealso> or cleared for reuse with + <seealso marker="#enif_clear_env"><c>enif_clear_env</c></seealso>. An + unsuccessful call will leave <c>msg</c> and <c>msg_env</c> still valid.</p> + <p>Apart from the message format <c>enif_select_read</c> and + <c>enif_select_write</c> behaves exactly the same as <seealso + marker="#enif_select">enif_select</seealso> with argument <c>mode</c> as + either <c>ERL_NIF_SELECT_READ</c> or <c>ERL_NIF_SELECT_WRITE</c>. To + cancel or close events use <seealso marker="#enif_select">enif_select</seealso>.</p> + </desc> + </func> + + <func> + <name since="OTP R14B"><ret>ErlNifPid *</ret> <nametext>enif_self(ErlNifEnv* caller_env, ErlNifPid* pid)</nametext> </name> <fsummary>Get the pid of the calling process.</fsummary> @@ -3123,26 +3260,26 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { <p>Initializes the <seealso marker="#ErlNifPid"><c>ErlNifPid</c></seealso> variable at <c>*pid</c> to represent the calling process.</p> <p>Returns <c>pid</c> if successful, or NULL if <c>caller_env</c> is not - a <seealso marker="#ErlNifEnv">process-bound environment</seealso>.</p> + a <seealso marker="#ErlNifEnv">process bound environment</seealso>.</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> + <name since="OTP R14B"><ret>int</ret><nametext>enif_send(ErlNifEnv* caller_env, + ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg)</nametext></name> <fsummary>Send a message to a process.</fsummary> <desc> <p>Sends a message to a process.</p> <taglist> - <tag><c>env</c></tag> - <item>The environment of the calling process. Must be <c>NULL</c> - only if calling from a created thread.</item> + <tag><c>caller_env</c></tag> + <item>The environment of the calling process or callback. Must be <c>NULL</c> + only if calling from a custom thread not spawned by ERTS.</item> <tag><c>*to_pid</c></tag> <item>The pid of the receiving process. The pid is to refer to a process on the local node.</item> <tag><c>msg_env</c></tag> <item>The environment of the message term. Must be a - process-independent environment allocated with + process independent environment allocated with <seealso marker="#enif_alloc_env"><c>enif_alloc_env</c></seealso> or NULL.</item> <tag><c>msg</c></tag> @@ -3159,8 +3296,9 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { <c>msg</c>) is invalidated by a successful call to <c>enif_send</c>. The environment is to either be freed with <seealso marker="#enif_free_env"> - <c>enif_free_env</c></seealso> of cleared for reuse with - <seealso marker="#enif_clear_env"><c>enif_clear_env</c></seealso>.</p> + <c>enif_free_env</c></seealso> or cleared for reuse with + <seealso marker="#enif_clear_env"><c>enif_clear_env</c></seealso>. An + unsuccessful call will leave <c>msg</c> and <c>msg_env</c> still valid.</p> <p>If <c>msg_env</c> is set to <c>NULL</c>, the <c>msg</c> term is copied and the original term and its environment is still valid after the call.</p> @@ -3175,7 +3313,18 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>unsigned</ret> + <name since="OTP 22.0"><ret>void</ret> + <nametext>enif_set_pid_undefined(ErlNifPid* pid)</nametext></name> + <fsummary>Set pid as undefined.</fsummary> + <desc> + <p>Sets an <seealso marker="#ErlNifPid"><c>ErlNifPid</c></seealso> + variable as undefined. See <seealso marker="#enif_is_pid_undefined"> + <c>enif_is_pid_undefined</c></seealso>.</p> + </desc> + </func> + + <func> + <name since="OTP R13B04"><ret>unsigned</ret> <nametext>enif_sizeof_resource(void* obj)</nametext></name> <fsummary>Get the byte size of a resource object.</fsummary> <desc> @@ -3186,20 +3335,21 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>int</ret><nametext>enif_snprintf(char *str, size_t size, const + <name since="OTP 19.0"><ret>int</ret><nametext>enif_snprintf(char *str, size_t size, const char *format, ...)</nametext></name> <fsummary>Format strings and Erlang terms.</fsummary> <desc> <p>Similar to <c>snprintf</c> but this format string also accepts - <c>"%T"</c>, which formats Erlang terms.</p> - <p>This function was originally intenden for debugging purpose. It is not + <c>"%T"</c>, which formats Erlang terms of type + <seealso marker="#ERL_NIF_TERM"><c>ERL_NIF_TERM</c></seealso>.</p> + <p>This function is primarily intended for debugging purpose. It is not recommended to print very large terms with <c>%T</c>. The function may change <c>errno</c>, even if successful.</p> </desc> </func> <func> - <name><ret>void</ret><nametext>enif_system_info(ErlNifSysInfo + <name since="OTP R13B04"><ret>void</ret><nametext>enif_system_info(ErlNifSysInfo *sys_info_ptr, size_t size)</nametext></name> <fsummary>Get information about the Erlang runtime system.</fsummary> <desc> @@ -3209,7 +3359,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>int</ret><nametext>enif_term_to_binary(ErlNifEnv *env, + <name since="OTP 19.0"><ret>int</ret><nametext>enif_term_to_binary(ErlNifEnv *env, ERL_NIF_TERM term, ErlNifBinary *bin)</nametext></name> <fsummary>Convert a term to the external format.</fsummary> <desc> @@ -3226,7 +3376,49 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>int</ret> + <name since="OTP 22.0"><ret>ErlNifTermType</ret> + <nametext>enif_term_type(ErlNifEnv *env, ERL_NIF_TERM term)</nametext> + </name> + <fsummary>Determine the type of a term.</fsummary> + <desc> + <p>Determines the type of the given term. The term must be an ordinary + Erlang term and not one of the special terms returned by + <seealso marker="#enif_raise_exception"> + <c>enif_raise_exception</c></seealso>, + <seealso marker="#enif_schedule_nif"> + <c>enif_schedule_nif</c></seealso>, or similar.</p> + <p>The following types are defined at the moment:</p> + <taglist> + <tag><c>ERL_NIF_TERM_TYPE_ATOM</c></tag> + <item/> + <tag><c>ERL_NIF_TERM_TYPE_BITSTRING</c></tag> + <item><p>A bitstring or binary</p></item> + <tag><c>ERL_NIF_TERM_TYPE_FLOAT</c></tag> + <item/> + <tag><c>ERL_NIF_TERM_TYPE_FUN</c></tag> + <item/> + <tag><c>ERL_NIF_TERM_TYPE_INTEGER</c></tag> + <item/> + <tag><c>ERL_NIF_TERM_TYPE_LIST</c></tag> + <item><p>A list, empty or not</p></item> + <tag><c>ERL_NIF_TERM_TYPE_MAP</c></tag> + <item/> + <tag><c>ERL_NIF_TERM_TYPE_PID</c></tag> + <item/> + <tag><c>ERL_NIF_TERM_TYPE_PORT</c></tag> + <item/> + <tag><c>ERL_NIF_TERM_TYPE_REFERENCE</c></tag> + <item/> + <tag><c>ERL_NIF_TERM_TYPE_TUPLE</c></tag> + <item/> + </taglist> + <p>Note that new types may be added in the future, so the caller must + be prepared to handle unknown types.</p> + </desc> + </func> + + <func> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_thread_create(char *name,ErlNifTid *tid,void * (*func)(void *),void *args,ErlNifThreadOpts *opts)</nametext></name> @@ -3238,7 +3430,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_thread_exit(void *resp)</nametext></name> <fsummary></fsummary> <desc> @@ -3248,7 +3440,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>int</ret> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_thread_join(ErlNifTid, void **respp)</nametext></name> <fsummary></fsummary> <desc> @@ -3258,7 +3450,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>char*</ret> + <name since="OTP 21.0"><ret>char*</ret> <nametext>enif_thread_name(ErlNifTid tid)</nametext></name> <fsummary>Thread name</fsummary> <desc> @@ -3268,7 +3460,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>ErlNifThreadOpts *</ret> + <name since="OTP R13B04"><ret>ErlNifThreadOpts *</ret> <nametext>enif_thread_opts_create(char *name)</nametext></name> <fsummary></fsummary> <desc> @@ -3278,7 +3470,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_thread_opts_destroy(ErlNifThreadOpts *opts)</nametext> </name> <fsummary></fsummary> @@ -3289,7 +3481,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>ErlNifTid</ret> + <name since="OTP R13B04"><ret>ErlNifTid</ret> <nametext>enif_thread_self(void)</nametext></name> <fsummary></fsummary> <desc> @@ -3299,7 +3491,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>int</ret> + <name since="OTP 19.0"><ret>int</ret> <nametext>enif_thread_type(void)</nametext></name> <fsummary>Determine type of current thread</fsummary> <desc> @@ -3321,7 +3513,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>ErlNifTime</ret> + <name since="OTP 18.3"><ret>ErlNifTime</ret> <nametext>enif_time_offset(ErlNifTimeUnit time_unit)</nametext></name> <fsummary>Get current time offset.</fsummary> <desc> @@ -3343,7 +3535,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>void *</ret> + <name since="OTP R13B04"><ret>void *</ret> <nametext>enif_tsd_get(ErlNifTSDKey key)</nametext></name> <fsummary></fsummary> <desc> @@ -3353,7 +3545,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>int</ret> + <name since="OTP R13B04"><ret>int</ret> <nametext>enif_tsd_key_create(char *name, ErlNifTSDKey *key)</nametext> </name> <fsummary></fsummary> @@ -3364,7 +3556,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_tsd_key_destroy(ErlNifTSDKey key)</nametext></name> <fsummary></fsummary> <desc> @@ -3374,7 +3566,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>void</ret> + <name since="OTP R13B04"><ret>void</ret> <nametext>enif_tsd_set(ErlNifTSDKey key, void *data)</nametext></name> <fsummary></fsummary> <desc> @@ -3384,7 +3576,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>int</ret> + <name since="OTP 21.0"><ret>int</ret> <nametext>enif_vfprintf(FILE *stream, const char *format, va_list ap) </nametext></name> <fsummary>Format strings and Erlang terms.</fsummary> @@ -3396,7 +3588,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>int</ret> + <name since="OTP 21.0"><ret>int</ret> <nametext>enif_vsnprintf(char *str, size_t size, const char *format, va_list ap) </nametext></name> <fsummary>Format strings and Erlang terms.</fsummary> @@ -3408,7 +3600,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>int</ret> + <name since="OTP 20.0"><ret>int</ret> <nametext>enif_whereis_pid(ErlNifEnv *env, ERL_NIF_TERM name, ErlNifPid *pid)</nametext></name> <fsummary>Looks up a process by its registered name.</fsummary> @@ -3436,7 +3628,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> - <name><ret>int</ret> + <name since="OTP 20.0"><ret>int</ret> <nametext>enif_whereis_port(ErlNifEnv *env, ERL_NIF_TERM name, ErlNifPort *port)</nametext></name> <fsummary>Looks up a port by its registered name.</fsummary> diff --git a/erts/doc/src/erl_prim_loader.xml b/erts/doc/src/erl_prim_loader.xml index 286bac6c93..043d11b7b4 100644 --- a/erts/doc/src/erl_prim_loader.xml +++ b/erts/doc/src/erl_prim_loader.xml @@ -29,7 +29,7 @@ <rev></rev> <file>erl_prim_loader.xml</file> </header> - <module>erl_prim_loader</module> + <module since="">erl_prim_loader</module> <modulesummary>Low-level Erlang loader.</modulesummary> <description> <p>This module is used to load all Erlang modules into @@ -47,7 +47,7 @@ <funcs> <func> - <name name="get_file" arity="1"/> + <name name="get_file" arity="1" since=""/> <fsummary>Get a file.</fsummary> <desc> <p>Fetches a file using the low-level loader. @@ -65,7 +65,7 @@ </func> <func> - <name name="get_path" arity="0"/> + <name name="get_path" arity="0" since=""/> <fsummary>Get the path set in the loader.</fsummary> <desc> <p>Gets the path set in the loader. The path is @@ -75,7 +75,7 @@ </func> <func> - <name name="list_dir" arity="1"/> + <name name="list_dir" arity="1" since=""/> <fsummary>List files in a directory.</fsummary> <desc> <p>Lists all the files in a directory. Returns @@ -92,7 +92,7 @@ </func> <func> - <name name="read_file_info" arity="1"/> + <name name="read_file_info" arity="1" since=""/> <fsummary>Get information about a file.</fsummary> <desc> <p>Retrieves information about a file. Returns @@ -114,7 +114,7 @@ </func> <func> - <name name="read_link_info" arity="1"/> + <name name="read_link_info" arity="1" since="OTP 17.1.2"/> <fsummary>Get information about a link or file.</fsummary> <desc> <p>Works like @@ -131,7 +131,7 @@ </func> <func> - <name name="set_path" arity="1"/> + <name name="set_path" arity="1" since=""/> <fsummary>Set the path of the loader.</fsummary> <desc> <p>Sets the path of the loader if diff --git a/erts/doc/src/erl_tracer.xml b/erts/doc/src/erl_tracer.xml index fd3c17f337..fa4717bc2f 100644 --- a/erts/doc/src/erl_tracer.xml +++ b/erts/doc/src/erl_tracer.xml @@ -28,7 +28,7 @@ <date></date> <rev></rev> </header> - <module>erl_tracer</module> + <module since="OTP 19.0">erl_tracer</module> <modulesummary>Erlang tracer behavior.</modulesummary> <description> <p>This behavior module implements the back end of the Erlang @@ -195,7 +195,7 @@ <funcs> <func> - <name>Module:enabled(TraceTag, TracerState, Tracee) -> Result</name> + <name since="OTP 19.0">Module:enabled(TraceTag, TracerState, Tracee) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> <v>TraceTag = <seealso marker="#type-trace_tag"> @@ -224,7 +224,7 @@ </func> <func> - <name>Module:enabled_call(TraceTag, TracerState, Tracee) -> Result</name> + <name since="OTP 19.0">Module:enabled_call(TraceTag, TracerState, Tracee) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> <v>TraceTag = <seealso marker="#type-trace_tag_call"> @@ -244,7 +244,7 @@ </func> <func> - <name>Module:enabled_garbage_collection(TraceTag, TracerState, Tracee) -> Result</name> + <name since="OTP 19.0">Module:enabled_garbage_collection(TraceTag, TracerState, Tracee) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> <v>TraceTag = <seealso marker="#type-trace_tag_gc"> @@ -264,7 +264,7 @@ </func> <func> - <name>Module:enabled_ports(TraceTag, TracerState, Tracee) -> Result</name> + <name since="OTP 19.0">Module:enabled_ports(TraceTag, TracerState, Tracee) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> <v>TraceTag = <seealso marker="#type-trace_tag_ports"> @@ -284,7 +284,7 @@ </func> <func> - <name>Module:enabled_procs(TraceTag, TracerState, Tracee) -> Result</name> + <name since="OTP 19.0">Module:enabled_procs(TraceTag, TracerState, Tracee) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> <v>TraceTag = <seealso marker="#type-trace_tag_procs"> @@ -304,7 +304,7 @@ </func> <func> - <name>Module:enabled_receive(TraceTag, TracerState, Tracee) -> Result + <name since="OTP 19.0">Module:enabled_receive(TraceTag, TracerState, Tracee) -> Result </name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> @@ -325,7 +325,7 @@ </func> <func> - <name>Module:enabled_running_ports(TraceTag, TracerState, Tracee) -> + <name since="OTP 19.0">Module:enabled_running_ports(TraceTag, TracerState, Tracee) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> @@ -346,7 +346,7 @@ </func> <func> - <name>Module:enabled_running_procs(TraceTag, TracerState, Tracee) -> + <name since="OTP 19.0">Module:enabled_running_procs(TraceTag, TracerState, Tracee) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> @@ -368,7 +368,7 @@ </func> <func> - <name>Module:enabled_send(TraceTag, TracerState, Tracee) -> Result</name> + <name since="OTP 19.0">Module:enabled_send(TraceTag, TracerState, Tracee) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> <v>TraceTag = <seealso marker="#type-trace_tag_send"> @@ -388,7 +388,7 @@ </func> <func> - <name>Module:trace(TraceTag, TracerState, Tracee, TraceTerm, + <name since="OTP 19.0">Module:trace(TraceTag, TracerState, Tracee, TraceTerm, Opts) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> @@ -417,7 +417,7 @@ </func> <func> - <name name="trace">Module:trace(seq_trace, TracerState, Label, + <name name="trace" since="OTP 19.0">Module:trace(seq_trace, TracerState, Label, SeqTraceInfo, Opts) -> Result</name> <fsummary>Check if a sequence trace event is to be generated.</fsummary> <type> @@ -439,7 +439,7 @@ </func> <func> - <name>Module:trace_call(TraceTag, TracerState, Tracee, TraceTerm, + <name since="OTP 19.0">Module:trace_call(TraceTag, TracerState, Tracee, TraceTerm, Opts) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> @@ -463,7 +463,7 @@ </func> <func> - <name>Module:trace_garbage_collection(TraceTag, TracerState, Tracee, + <name since="OTP 19.0">Module:trace_garbage_collection(TraceTag, TracerState, Tracee, TraceTerm, Opts) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> @@ -487,7 +487,7 @@ </func> <func> - <name>Module:trace_ports(TraceTag, TracerState, Tracee, TraceTerm, + <name since="OTP 19.0">Module:trace_ports(TraceTag, TracerState, Tracee, TraceTerm, Opts) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> @@ -511,7 +511,7 @@ </func> <func> - <name>Module:trace_procs(TraceTag, TracerState, Tracee, TraceTerm, + <name since="OTP 19.0">Module:trace_procs(TraceTag, TracerState, Tracee, TraceTerm, Opts) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> @@ -535,7 +535,7 @@ </func> <func> - <name>Module:trace_receive(TraceTag, TracerState, Tracee, TraceTerm, + <name since="OTP 19.0">Module:trace_receive(TraceTag, TracerState, Tracee, TraceTerm, Opts) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> @@ -559,7 +559,7 @@ </func> <func> - <name>Module:trace_running_ports(TraceTag, TracerState, Tracee, + <name since="OTP 19.0">Module:trace_running_ports(TraceTag, TracerState, Tracee, TraceTerm, Opts) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> @@ -583,7 +583,7 @@ </func> <func> - <name>Module:trace_running_procs(TraceTag, TracerState, Tracee, + <name since="OTP 19.0">Module:trace_running_procs(TraceTag, TracerState, Tracee, TraceTerm, Opts) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> @@ -607,7 +607,7 @@ </func> <func> - <name>Module:trace_send(TraceTag, TracerState, Tracee, TraceTerm, + <name since="OTP 19.0">Module:trace_send(TraceTag, TracerState, Tracee, TraceTerm, Opts) -> Result</name> <fsummary>Check if a trace event is to be generated.</fsummary> <type> diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index b39d0e5e23..0e82ceba7d 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -29,7 +29,7 @@ <rev></rev> <file>erlang.xml</file> </header> - <module>erlang</module> + <module since="">erlang</module> <modulesummary>The Erlang BIFs.</modulesummary> <description> <p>By convention, most Built-In Functions (BIFs) are included @@ -126,7 +126,7 @@ instance.</p> <p>One can get an approximation of the <c>native</c> time unit by calling - <seealso marker="erlang:convert_time_unit/3"> + <seealso marker="#convert_time_unit/3"> <c>erlang:convert_time_unit(1, second, native)</c></seealso>. The result equals the number of whole <c>native</c> time units per second. If @@ -197,12 +197,21 @@ </desc> </datatype> + <datatype> + <name name="nif_resource"></name> + <desc> + <p>An opaque handle identifing a + <seealso marker="erl_nif#resource_objects">NIF resource object + </seealso>.</p> + </desc> + </datatype> + </datatypes> <funcs> <func> - <name name="abs" arity="1" clause_i="1"/> - <name name="abs" arity="1" clause_i="2"/> + <name name="abs" arity="1" clause_i="1" since=""/> + <name name="abs" arity="1" clause_i="2" since=""/> <fsummary>Arithmetical absolute value.</fsummary> <desc> <p>Returns an integer or float that is the arithmetical @@ -218,7 +227,7 @@ </func> <func> - <name name="adler32" arity="1"/> + <name name="adler32" arity="1" since=""/> <fsummary>Compute adler32 checksum.</fsummary> <desc> <p>Computes and returns the adler32 checksum for @@ -227,7 +236,7 @@ </func> <func> - <name name="adler32" arity="2"/> + <name name="adler32" arity="2" since=""/> <fsummary>Compute adler32 checksum.</fsummary> <desc> <p>Continues computing the adler32 checksum by combining @@ -244,7 +253,7 @@ Y = erlang:adler32([Data1,Data2]).</code> </func> <func> - <name name="adler32_combine" arity="3"/> + <name name="adler32_combine" arity="3" since=""/> <fsummary>Combine two adler32 checksums.</fsummary> <desc> <p>Combines two previously computed adler32 checksums. @@ -263,7 +272,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="append_element" arity="2"/> + <name name="append_element" arity="2" since=""/> <fsummary>Append an extra element to a tuple.</fsummary> <desc> <p>Returns a new tuple that has one element more than @@ -280,7 +289,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="apply" arity="2"/> + <name name="apply" arity="2" since=""/> <fsummary>Apply a function to an argument list.</fsummary> <desc> <p>Calls a fun, passing the elements in <c><anno>Args</anno></c> @@ -298,7 +307,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="apply" arity="3"/> + <name name="apply" arity="3" since=""/> <fsummary>Apply a function to an argument list.</fsummary> <desc> <p>Returns the result of applying <c>Function</c> in @@ -328,7 +337,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="atom_to_binary" arity="2"/> + <name name="atom_to_binary" arity="2" since=""/> <fsummary>Return the binary representation of an atom.</fsummary> <desc> <p>Returns a binary corresponding to the text @@ -353,7 +362,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="atom_to_list" arity="1"/> + <name name="atom_to_list" arity="1" since=""/> <fsummary>Text representation of an atom.</fsummary> <desc> <p>Returns a string corresponding to the text @@ -365,7 +374,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="binary_part" arity="2"/> + <name name="binary_part" arity="2" since="OTP R14B"/> <fsummary>Extract a part of a binary.</fsummary> <desc> <p>Extracts the part of the binary described by @@ -390,7 +399,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="binary_part" arity="3"/> + <name name="binary_part" arity="3" since="OTP R14B"/> <fsummary>Extract a part of a binary.</fsummary> <desc> <p>The same as <c>binary_part(<anno>Subject</anno>, @@ -400,7 +409,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="binary_to_atom" arity="2"/> + <name name="binary_to_atom" arity="2" since=""/> <fsummary>Convert from text representation to an atom.</fsummary> <desc> <p>Returns the atom whose text representation is @@ -429,7 +438,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="binary_to_existing_atom" arity="2"/> + <name name="binary_to_existing_atom" arity="2" since=""/> <fsummary>Convert from text representation to an atom.</fsummary> <desc> <p>As @@ -450,7 +459,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="binary_to_float" arity="1"/> + <name name="binary_to_float" arity="1" since="OTP R16B"/> <fsummary>Convert from text representation to a float.</fsummary> <desc> <p>Returns the float whose text representation is @@ -464,7 +473,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="binary_to_integer" arity="1"/> + <name name="binary_to_integer" arity="1" since="OTP R16B"/> <fsummary>Convert from text representation to an integer.</fsummary> <desc> <p>Returns an integer whose text representation is @@ -478,7 +487,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="binary_to_integer" arity="2"/> + <name name="binary_to_integer" arity="2" since="OTP R16B"/> <fsummary>Convert from text representation to an integer.</fsummary> <desc> <p>Returns an integer whose text representation in base @@ -493,7 +502,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="binary_to_list" arity="1"/> + <name name="binary_to_list" arity="1" since=""/> <fsummary>Convert a binary to a list.</fsummary> <desc> <p>Returns a list of integers corresponding to the bytes of @@ -502,7 +511,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="binary_to_list" arity="3"/> + <name name="binary_to_list" arity="3" since=""/> <fsummary>Convert part of a binary to a list.</fsummary> <type_desc variable="Start">1..byte_size(<c><anno>Binary</anno></c>) </type_desc> @@ -524,7 +533,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="binary_to_term" arity="1"/> + <name name="binary_to_term" arity="1" since=""/> <fsummary>Decode an Erlang external term format binary.</fsummary> <desc> <p>Returns an Erlang term that is the result of decoding @@ -550,7 +559,7 @@ hello </func> <func> - <name name="binary_to_term" arity="2"/> + <name name="binary_to_term" arity="2" since="OTP R13B04"/> <fsummary>Decode an Erlang external term format binary.</fsummary> <desc> <p>As <c>binary_to_term/1</c>, but takes these options:</p> @@ -604,7 +613,7 @@ hello </func> <func> - <name name="bit_size" arity="1"/> + <name name="bit_size" arity="1" since=""/> <fsummary>Return the size of a bitstring.</fsummary> <desc> <p>Returns an integer that is the size in bits of @@ -619,7 +628,7 @@ hello </func> <func> - <name name="bitstring_to_list" arity="1"/> + <name name="bitstring_to_list" arity="1" since=""/> <fsummary>Convert a bitstring to a list.</fsummary> <desc> <p>Returns a list of integers corresponding to the bytes of @@ -630,7 +639,7 @@ hello </func> <func> - <name name="bump_reductions" arity="1"/> + <name name="bump_reductions" arity="1" since=""/> <fsummary>Increment the reduction counter.</fsummary> <desc> <p>This implementation-dependent function increments @@ -648,7 +657,7 @@ hello </func> <func> - <name name="byte_size" arity="1"/> + <name name="byte_size" arity="1" since=""/> <fsummary>Return the size of a bitstring (or binary).</fsummary> <desc> <p>Returns an integer that is the number of bytes needed to @@ -665,7 +674,7 @@ hello </func> <func> - <name name="cancel_timer" arity="1"/> + <name name="cancel_timer" arity="1" since=""/> <fsummary>Cancel a timer.</fsummary> <desc> <p>Cancels a timer. The same as calling @@ -675,7 +684,7 @@ hello </func> <func> - <name name="cancel_timer" arity="2"/> + <name name="cancel_timer" arity="2" since="OTP 18.0"/> <fsummary>Cancel a timer.</fsummary> <desc> <p>Cancels a timer that has been created by @@ -757,7 +766,7 @@ hello </func> <func> - <name name="ceil" arity="1"/> + <name name="ceil" arity="1" since="OTP 20.0"/> <fsummary>Returns the smallest integer not less than the argument</fsummary> <desc> <p>Returns the smallest integer not less than @@ -770,7 +779,7 @@ hello </desc> </func> <func> - <name name="check_old_code" arity="1"/> + <name name="check_old_code" arity="1" since="OTP R14B04"/> <fsummary>Check if a module has old code.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Module</anno></c> has old code, @@ -781,7 +790,7 @@ hello </func> <func> - <name name="check_process_code" arity="2"/> + <name name="check_process_code" arity="2" since=""/> <fsummary>Check if a process executes old code for a module.</fsummary> <desc> <p>The same as @@ -792,7 +801,7 @@ hello </func> <func> - <name name="check_process_code" arity="3"/> + <name name="check_process_code" arity="3" since="OTP 17.0"/> <fsummary>Check if a process executes old code for a module.</fsummary> <desc> <p>Checks if the node local process identified by @@ -895,7 +904,7 @@ hello </func> <func> - <name name="convert_time_unit" arity="3"/> + <name name="convert_time_unit" arity="3" since="OTP 18.0"/> <fsummary>Convert time unit of a time value.</fsummary> <desc> <p>Converts the <c><anno>Time</anno></c> value of time unit @@ -913,7 +922,7 @@ hello </func> <func> - <name name="crc32" arity="1"/> + <name name="crc32" arity="1" since=""/> <fsummary>Compute crc32 (IEEE 802.3) checksum.</fsummary> <desc> <p>Computes and returns the crc32 (IEEE 802.3 style) checksum @@ -922,7 +931,7 @@ hello </func> <func> - <name name="crc32" arity="2"/> + <name name="crc32" arity="2" since=""/> <fsummary>Compute crc32 (IEEE 802.3) checksum.</fsummary> <desc> <p>Continues computing the crc32 checksum by combining @@ -939,7 +948,7 @@ Y = erlang:crc32([Data1,Data2]).</code> </func> <func> - <name name="crc32_combine" arity="3"/> + <name name="crc32_combine" arity="3" since=""/> <fsummary>Combine two crc32 (IEEE 802.3) checksums.</fsummary> <desc> <p>Combines two previously computed crc32 checksums. @@ -958,7 +967,7 @@ Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="date" arity="0"/> + <name name="date" arity="0" since=""/> <fsummary>Current date.</fsummary> <desc> <p>Returns the current date as <c>{Year, Month, Day}</c>.</p> @@ -971,7 +980,7 @@ Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="decode_packet" arity="3"/> + <name name="decode_packet" arity="3" since=""/> <fsummary>Extract a protocol packet from a binary.</fsummary> <desc> <p>Decodes the binary <c><anno>Bin</anno></c> according to the packet @@ -1081,7 +1090,7 @@ Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="delete_element" arity="2"/> + <name name="delete_element" arity="2" since="OTP R16B"/> <fsummary>Delete element at index in a tuple.</fsummary> <type_desc variable="Index">1..tuple_size(<anno>Tuple1</anno>)</type_desc> <desc> @@ -1094,7 +1103,7 @@ Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="delete_module" arity="1"/> + <name name="delete_module" arity="1" since=""/> <fsummary>Make the current code for a module old.</fsummary> <desc> <p>Makes the current code for <c><anno>Module</anno></c> become old @@ -1112,7 +1121,7 @@ Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="demonitor" arity="1"/> + <name name="demonitor" arity="1" since=""/> <fsummary>Stop monitoring.</fsummary> <desc> <p>If <c><anno>MonitorRef</anno></c> is a reference that the @@ -1154,7 +1163,7 @@ Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).</code> </func> <func> - <name name="demonitor" arity="2"/> + <name name="demonitor" arity="2" since=""/> <fsummary>Stop monitoring.</fsummary> <desc> <p>The returned value is <c>true</c> unless <c>info</c> is part @@ -1222,7 +1231,7 @@ end</code> </func> <func> - <name name="disconnect_node" arity="1"/> + <name name="disconnect_node" arity="1" since=""/> <fsummary>Force the disconnection of a node.</fsummary> <desc> <p>Forces the disconnection of a node. This appears to @@ -1236,7 +1245,7 @@ end</code> </func> <func> - <name name="display" arity="1"/> + <name name="display" arity="1" since=""/> <fsummary>Print a term on standard output.</fsummary> <desc> <p>Prints a text representation of <c><anno>Term</anno></c> on the @@ -1248,7 +1257,7 @@ end</code> </func> <func> - <name name="dist_ctrl_get_data" arity="1"/> + <name name="dist_ctrl_get_data" arity="1" since="OTP 21.0"/> <fsummary>Get distribution channel data to pass to another node.</fsummary> <desc> <p> @@ -1260,6 +1269,13 @@ end</code> data is available by calling <seealso marker="erlang#dist_ctrl_get_data_notification/1"><c>erlang:dist_ctrl_get_data_notification(DHandle)</c></seealso>. </p> + <p>The returned value when there are data available depends + on the value of the <c>get_size</c> option configured on the + distribution channel identified by <c><anno>DHandle</anno></c>. + For more information see the documentation of the <c>get_size</c> + option for the + <seealso marker="#dist_ctrl_set_opt/3"><c>erlang:dist_ctrl_set_opt/3</c></seealso> + function.</p> <note><p> Only the process registered as distribution controller for the distribution channel identified by @@ -1281,7 +1297,36 @@ end</code> </func> <func> - <name name="dist_ctrl_get_data_notification" arity="1"/> + <name name="dist_ctrl_get_opt" arity="2" clause_i="1" since="OTP 22.0"/> + <fsummary>Get value of the get_size option on a distribution channel</fsummary> + <desc> + <p>Returns the value of the <c>get_size</c> option on the distribution channel + identified by <c><anno>DHandle</anno></c>. For more information see the + documentation of the <c>get_size</c> option for the + <seealso marker="#dist_ctrl_set_opt/3"><c>erlang:dist_ctrl_set_opt/3</c></seealso> + function.</p> + <note><p> + Only the process registered as distribution + controller for the distribution channel identified by + <c><anno>DHandle</anno></c> is allowed to call this + function. + </p></note> + <p> + This function is used when implementing an alternative + distribution carrier using processes as distribution + controllers. <c><anno>DHandle</anno></c> is retrived + via the callback + <seealso marker="erts:alt_dist#hs_data_f_handshake_complete"><c>f_handshake_complete</c></seealso>. + More information can be found in the documentation of + <seealso marker="erts:alt_dist#distribution_module">ERTS + User's Guide ➜ How to implement an Alternative Carrier + for the Erlang Distribution ➜ Distribution Module</seealso>. + </p> + </desc> + </func> + + <func> + <name name="dist_ctrl_get_data_notification" arity="1" since="OTP 21.0"/> <fsummary>Request notification about available outgoing distribution channel data.</fsummary> <desc> <p> @@ -1317,7 +1362,7 @@ end</code> </func> <func> - <name name="dist_ctrl_input_handler" arity="2"/> + <name name="dist_ctrl_input_handler" arity="2" since="OTP 21.0"/> <fsummary>Register distribution channel input handler process.</fsummary> <desc> <p> @@ -1350,7 +1395,7 @@ end</code> </func> <func> - <name name="dist_ctrl_put_data" arity="2"/> + <name name="dist_ctrl_put_data" arity="2" since="OTP 21.0"/> <fsummary>Pass data into the VM from a distribution channel.</fsummary> <desc> <p> @@ -1383,7 +1428,56 @@ end</code> </func> <func> - <name name="element" arity="2"/> + <name name="dist_ctrl_set_opt" arity="3" clause_i="1" since="OTP 22.0"/> + <fsummary>Set value of the get_size option on a distribution channel</fsummary> + <desc> + <p>Sets the value of the <c>get_size</c> option on the distribution channel + identified by <c><anno>DHandle</anno></c>. This option controls the return + value of calls to + <seealso marker="#dist_ctrl_get_data/1">erlang:dist_ctrl_get_data(<anno>DHandle</anno>)</seealso> + where <c><anno>DHandle</anno></c> equals <c><anno>DHandle</anno></c> used + when setting this option. + When the <c>get_size</c> option is:</p> + <taglist> + <tag><c>false</c></tag> + <item> + and there are distribution data available, a call to + <c>erlang:dist_ctrl_get_data(<anno>DHandle</anno>)</c> + will just return <c>Data</c> to pass over the channel. + This is the default value of the <c>get_size</c> option. + </item> + <tag><c>true</c></tag> + <item> + and there are distribution data available, a call to + <c>erlang:dist_ctrl_get_data(<anno>DHandle</anno>)</c> + will return <c>Data</c> to pass over the channel as well as + the <c>Size</c> of <c>Data</c> in bytes. This is returned as + a tuple on the form <c>{Size, Data}</c>. + </item> + </taglist> + <p>All options are set to default when a channel is closed.</p> + <note><p> + Only the process registered as distribution + controller for the distribution channel identified by + <c><anno>DHandle</anno></c> is allowed to call this + function. + </p></note> + <p> + This function is used when implementing an alternative + distribution carrier using processes as distribution + controllers. <c><anno>DHandle</anno></c> is retrived + via the callback + <seealso marker="erts:alt_dist#hs_data_f_handshake_complete"><c>f_handshake_complete</c></seealso>. + More information can be found in the documentation of + <seealso marker="erts:alt_dist#distribution_module">ERTS + User's Guide ➜ How to implement an Alternative Carrier + for the Erlang Distribution ➜ Distribution Module</seealso>. + </p> + </desc> + </func> + + <func> + <name name="element" arity="2" since=""/> <fsummary>Return the Nth element of a tuple.</fsummary> <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc> <desc> @@ -1397,7 +1491,7 @@ b</pre> </func> <func> - <name name="erase" arity="0"/> + <name name="erase" arity="0" since=""/> <fsummary>Return and delete the process dictionary.</fsummary> <desc> <p>Returns the process dictionary and deletes it, for @@ -1411,7 +1505,7 @@ b</pre> </func> <func> - <name name="erase" arity="1"/> + <name name="erase" arity="1" since=""/> <fsummary>Return and delete a value from the process dictionary. </fsummary> <desc> @@ -1428,7 +1522,7 @@ b</pre> </func> <func> - <name name="error" arity="1"/> + <name name="error" arity="1" since=""/> <fsummary>Stop execution with a specified reason.</fsummary> <desc> <p>Stops the execution of the calling process with the reason @@ -1452,7 +1546,7 @@ b</pre> </func> <func> - <name name="error" arity="2"/> + <name name="error" arity="2" since=""/> <fsummary>Stop execution with a specified reason.</fsummary> <desc> <p>Stops the execution of the calling process with the reason @@ -1469,7 +1563,7 @@ b</pre> </func> <func> - <name name="exit" arity="1"/> + <name name="exit" arity="1" since=""/> <fsummary>Stop execution with a specified reason.</fsummary> <desc> <p>Stops the execution of the calling process with exit reason @@ -1486,7 +1580,7 @@ b</pre> </func> <func> - <name name="exit" arity="2"/> + <name name="exit" arity="2" since=""/> <fsummary>Send an exit signal to a process or a port.</fsummary> <desc> <p>Sends an exit signal with exit reason <c><anno>Reason</anno></c> to @@ -1522,7 +1616,7 @@ b</pre> </func> <func> - <name name="external_size" arity="1"/> + <name name="external_size" arity="1" since="OTP R14B04"/> <fsummary>Calculate the maximum size for a term encoded in the Erlang external term format.</fsummary> <desc> @@ -1541,7 +1635,7 @@ erlang:external_size(<anno>Term</anno>, [])</code> </func> <func> - <name name="external_size" arity="2"/> + <name name="external_size" arity="2" since="OTP R14B04"/> <fsummary>Calculate the maximum size for a term encoded in the Erlang external term format.</fsummary> <desc> @@ -1561,7 +1655,7 @@ true</pre> </func> <func> - <name name="float" arity="1"/> + <name name="float" arity="1" since=""/> <fsummary>Convert a number to a float.</fsummary> <desc> <p>Returns a float by converting <c><anno>Number</anno></c> to a float, @@ -1583,7 +1677,7 @@ true</pre> </func> <func> - <name name="float_to_binary" arity="1"/> + <name name="float_to_binary" arity="1" since="OTP R16B"/> <fsummary>Text representation of a float.</fsummary> <desc> <p>The same as @@ -1592,7 +1686,7 @@ true</pre> </func> <func> - <name name="float_to_binary" arity="2"/> + <name name="float_to_binary" arity="2" since="OTP R16B"/> <fsummary>Text representation of a float formatted using specified options.</fsummary> <desc> @@ -1610,7 +1704,7 @@ true</pre> </func> <func> - <name name="float_to_list" arity="1"/> + <name name="float_to_list" arity="1" since=""/> <fsummary>Text representation of a float.</fsummary> <desc> <p>The same as @@ -1619,7 +1713,7 @@ true</pre> </func> <func> - <name name="float_to_list" arity="2"/> + <name name="float_to_list" arity="2" since="OTP R16B"/> <fsummary>Text representation of a float formatted using specified options.</fsummary> <desc> @@ -1655,7 +1749,7 @@ true</pre> </func> <func> - <name name="floor" arity="1"/> + <name name="floor" arity="1" since="OTP 20.0"/> <fsummary>Returns the largest integer not greater than the argument</fsummary> <desc> <p>Returns the largest integer not greater than @@ -1669,7 +1763,7 @@ true</pre> </func> <func> - <name name="fun_info" arity="1"/> + <name name="fun_info" arity="1" since=""/> <fsummary>Information about a fun.</fsummary> <desc> <p>Returns a list with information about the fun @@ -1742,6 +1836,10 @@ true</pre> <item> <p><c>Pid</c> is the process identifier of the process that originally created the fun.</p> + <p>It might point to the <c>init</c> process if the + <c>Fun</c> was statically allocated when module was + loaded (this optimisation is performed for local + functions that do not capture the enviornment).</p> </item> <tag><c>{index, Index}</c></tag> <item> @@ -1770,7 +1868,7 @@ true</pre> </func> <func> - <name name="fun_info" arity="2"/> + <name name="fun_info" arity="2" since=""/> <fsummary>Information about a fun.</fsummary> <type name="fun_info_item"/> <desc> @@ -1790,7 +1888,7 @@ true</pre> </func> <func> - <name name="fun_to_list" arity="1"/> + <name name="fun_to_list" arity="1" since=""/> <fsummary>Text representation of a fun.</fsummary> <desc> <p>Returns a string corresponding to the text @@ -1799,7 +1897,7 @@ true</pre> </func> <func> - <name name="function_exported" arity="3"/> + <name name="function_exported" arity="3" since=""/> <fsummary>Check if a function is exported and loaded.</fsummary> <desc> <p>Returns <c>true</c> if the module <c><anno>Module</anno></c> is @@ -1815,7 +1913,7 @@ true</pre> </func> <func> - <name name="garbage_collect" arity="0"/> + <name name="garbage_collect" arity="0" since=""/> <fsummary>Force an immediate garbage collection of the calling process. </fsummary> <desc> @@ -1831,7 +1929,7 @@ true</pre> </func> <func> - <name name="garbage_collect" arity="1"/> + <name name="garbage_collect" arity="1" since=""/> <fsummary>Garbage collect a process.</fsummary> <desc> <p>The same as @@ -1841,7 +1939,7 @@ true</pre> </func> <func> - <name name="garbage_collect" arity="2"/> + <name name="garbage_collect" arity="2" since="OTP 17.0"/> <fsummary>Garbage collect a process.</fsummary> <desc> <p>Garbage collects the node local process identified by @@ -1906,7 +2004,7 @@ true</pre> </func> <func> - <name name="get" arity="0"/> + <name name="get" arity="0" since=""/> <fsummary>Return the process dictionary.</fsummary> <desc> <p>Returns the process dictionary as a list of @@ -1921,7 +2019,7 @@ true</pre> </func> <func> - <name name="get" arity="1"/> + <name name="get" arity="1" since=""/> <fsummary>Return a value from the process dictionary.</fsummary> <desc> <p>Returns the value <c><anno>Val</anno></c> associated with @@ -1937,7 +2035,7 @@ true</pre> </func> <func> - <name name="get_cookie" arity="0"/> + <name name="get_cookie" arity="0" since=""/> <fsummary>Get the magic cookie of the local node.</fsummary> <desc> <p>Returns the magic cookie of the local node if the node is @@ -1946,7 +2044,7 @@ true</pre> </func> <func> - <name name="get_keys" arity="0"/> + <name name="get_keys" arity="0" since="OTP 18.0"/> <fsummary>Return a list of all keys from the process dictionary. </fsummary> <desc> @@ -1962,7 +2060,7 @@ true</pre> </func> <func> - <name name="get_keys" arity="1"/> + <name name="get_keys" arity="1" since=""/> <fsummary>Return a list of keys from the process dictionary.</fsummary> <desc> <p>Returns a list of keys that are associated with the value @@ -1980,7 +2078,7 @@ true</pre> </func> <func> - <name name="get_stacktrace" arity="0"/> + <name name="get_stacktrace" arity="0" since=""/> <fsummary>Get the call stack back-trace of the last exception.</fsummary> <type name="stack_item"/> <desc> @@ -2045,7 +2143,7 @@ end</pre> </func> <func> - <name name="group_leader" arity="0"/> + <name name="group_leader" arity="0" since=""/> <fsummary>Get the group leader for the calling process.</fsummary> <desc> <p>Returns the process identifier of the group leader for the @@ -2060,7 +2158,7 @@ end</pre> </func> <func> - <name name="group_leader" arity="2"/> + <name name="group_leader" arity="2" since=""/> <fsummary>Set the group leader for a process.</fsummary> <desc> <p>Sets the group leader of <c><anno>Pid</anno></c> @@ -2081,7 +2179,7 @@ end</pre> </func> <func> - <name name="halt" arity="0"/> + <name name="halt" arity="0" since=""/> <fsummary>Halt the Erlang runtime system and indicate normal exit to the calling environment.</fsummary> <desc> @@ -2094,7 +2192,7 @@ os_prompt%</pre> </func> <func> - <name name="halt" arity="1"/> + <name name="halt" arity="1" since=""/> <fsummary>Halt the Erlang runtime system.</fsummary> <desc> <p>The same as <seealso marker="#halt/2"> @@ -2108,7 +2206,7 @@ os_prompt%</pre> </func> <func> - <name name="halt" arity="2"/> + <name name="halt" arity="2" since="OTP R15B01"/> <fsummary>Halt the Erlang runtime system.</fsummary> <desc> <p><c><anno>Status</anno></c> must be a non-negative integer, a string, @@ -2150,7 +2248,7 @@ os_prompt%</pre> </func> <func> - <name name="hd" arity="1"/> + <name name="hd" arity="1" since=""/> <fsummary>Head of a list.</fsummary> <desc> <p>Returns the head of <c><anno>List</anno></c>, that is, @@ -2165,7 +2263,7 @@ os_prompt%</pre> </func> <func> - <name name="hibernate" arity="3"/> + <name name="hibernate" arity="3" since=""/> <fsummary>Hibernate a process until a message is sent to it.</fsummary> <desc> <p>Puts the calling process into a wait state where its memory @@ -2206,7 +2304,7 @@ os_prompt%</pre> </func> <func> - <name name="insert_element" arity="3"/> + <name name="insert_element" arity="3" since="OTP R16B"/> <fsummary>Insert an element at index in a tuple.</fsummary> <type_desc variable="Index">1..tuple_size(<anno>Tuple1</anno>) + 1</type_desc> @@ -2224,7 +2322,7 @@ os_prompt%</pre> </func> <func> - <name name="integer_to_binary" arity="1"/> + <name name="integer_to_binary" arity="1" since="OTP R16B"/> <fsummary>Text representation of an integer.</fsummary> <desc> <p>Returns a binary corresponding to the text @@ -2236,7 +2334,7 @@ os_prompt%</pre> </func> <func> - <name name="integer_to_binary" arity="2"/> + <name name="integer_to_binary" arity="2" since="OTP R16B"/> <fsummary>Text representation of an integer.</fsummary> <desc> <p>Returns a binary corresponding to the text @@ -2249,7 +2347,7 @@ os_prompt%</pre> </func> <func> - <name name="integer_to_list" arity="1"/> + <name name="integer_to_list" arity="1" since=""/> <fsummary>Text representation of an integer.</fsummary> <desc> <p>Returns a string corresponding to the text @@ -2261,7 +2359,7 @@ os_prompt%</pre> </func> <func> - <name name="integer_to_list" arity="2"/> + <name name="integer_to_list" arity="2" since=""/> <fsummary>Text representation of an integer.</fsummary> <desc> <p>Returns a string corresponding to the text @@ -2274,7 +2372,7 @@ os_prompt%</pre> </func> <func> - <name name="iolist_size" arity="1"/> + <name name="iolist_size" arity="1" since=""/> <fsummary>Size of an iolist.</fsummary> <desc> <p>Returns an integer, that is the size in bytes, @@ -2287,7 +2385,7 @@ os_prompt%</pre> </func> <func> - <name name="iolist_to_binary" arity="1"/> + <name name="iolist_to_binary" arity="1" since=""/> <fsummary>Convert an iolist to a binary.</fsummary> <desc> <p>Returns a binary that is made from the integers and @@ -2305,7 +2403,7 @@ os_prompt%</pre> </func> <func> - <name name="iolist_to_iovec" arity="1"/> + <name name="iolist_to_iovec" arity="1" since="OTP 20.1"/> <fsummary>Converts an iolist to a iovec.</fsummary> <desc> <p>Returns an iovec that is made from the integers and binaries in @@ -2314,7 +2412,7 @@ os_prompt%</pre> </func> <func> - <name name="is_alive" arity="0"/> + <name name="is_alive" arity="0" since=""/> <fsummary>Check whether the local node is alive.</fsummary> <desc> <p>Returns <c>true</c> if the local node is alive (that is, if @@ -2324,7 +2422,7 @@ os_prompt%</pre> </func> <func> - <name name="is_atom" arity="1"/> + <name name="is_atom" arity="1" since=""/> <fsummary>Check whether a term is an atom.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an atom, @@ -2334,7 +2432,7 @@ os_prompt%</pre> </func> <func> - <name name="is_binary" arity="1"/> + <name name="is_binary" arity="1" since=""/> <fsummary>Check whether a term is a binary.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a binary, @@ -2345,7 +2443,7 @@ os_prompt%</pre> </func> <func> - <name name="is_bitstring" arity="1"/> + <name name="is_bitstring" arity="1" since=""/> <fsummary>Check whether a term is a bitstring.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a @@ -2355,7 +2453,7 @@ os_prompt%</pre> </func> <func> - <name name="is_boolean" arity="1"/> + <name name="is_boolean" arity="1" since=""/> <fsummary>Check whether a term is a boolean.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is the @@ -2366,7 +2464,7 @@ os_prompt%</pre> </func> <func> - <name name="is_builtin" arity="3"/> + <name name="is_builtin" arity="3" since=""/> <fsummary>Check if a function is a BIF implemented in C.</fsummary> <desc> <p>This BIF is useful for builders of cross-reference tools.</p> @@ -2377,7 +2475,7 @@ os_prompt%</pre> </func> <func> - <name name="is_float" arity="1"/> + <name name="is_float" arity="1" since=""/> <fsummary>Check whether a term is a float.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a floating point @@ -2387,7 +2485,7 @@ os_prompt%</pre> </func> <func> - <name name="is_function" arity="1"/> + <name name="is_function" arity="1" since=""/> <fsummary>Check whether a term is a fun.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a fun, otherwise @@ -2397,7 +2495,7 @@ os_prompt%</pre> </func> <func> - <name name="is_function" arity="2"/> + <name name="is_function" arity="2" since=""/> <fsummary>Check whether a term is a fun with a specified given arity. </fsummary> <desc> @@ -2409,7 +2507,7 @@ os_prompt%</pre> </func> <func> - <name name="is_integer" arity="1"/> + <name name="is_integer" arity="1" since=""/> <fsummary>Check whether a term is an integer.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an integer, @@ -2419,7 +2517,7 @@ os_prompt%</pre> </func> <func> - <name name="is_list" arity="1"/> + <name name="is_list" arity="1" since=""/> <fsummary>Check whether a term is a list.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a list with @@ -2429,7 +2527,7 @@ os_prompt%</pre> </func> <func> - <name name="is_map" arity="1"/> + <name name="is_map" arity="1" since="OTP 17.0"/> <fsummary>Check whether a term is a map.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a map, @@ -2439,7 +2537,7 @@ os_prompt%</pre> </func> <func> - <name name="is_map_key" arity="2"/> + <name name="is_map_key" arity="2" since="OTP 21.0"/> <fsummary></fsummary> <desc> <p>Returns <c>true</c> if map <c><anno>Map</anno></c> contains @@ -2459,7 +2557,7 @@ false</code> </func> <func> - <name name="is_number" arity="1"/> + <name name="is_number" arity="1" since=""/> <fsummary>Check whether a term is a number.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an integer or a @@ -2469,7 +2567,7 @@ false</code> </func> <func> - <name name="is_pid" arity="1"/> + <name name="is_pid" arity="1" since=""/> <fsummary>Check whether a term is a process identifier.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a process @@ -2479,7 +2577,7 @@ false</code> </func> <func> - <name name="is_port" arity="1"/> + <name name="is_port" arity="1" since=""/> <fsummary>Check whether a term is a port.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a port identifier, @@ -2489,7 +2587,7 @@ false</code> </func> <func> - <name name="is_process_alive" arity="1"/> + <name name="is_process_alive" arity="1" since=""/> <fsummary>Check whether a process is alive.</fsummary> <desc> <p><c><anno>Pid</anno></c> must refer to a process at the local @@ -2501,7 +2599,7 @@ false</code> </func> <func> - <name name="is_record" arity="2"/> + <name name="is_record" arity="2" since=""/> <fsummary>Check whether a term appears to be a record.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a tuple and its @@ -2522,7 +2620,7 @@ false</code> </func> <func> - <name name="is_record" arity="3"/> + <name name="is_record" arity="3" since=""/> <fsummary>Check whether a term appears to be a record.</fsummary> <desc> <p><c><anno>RecordTag</anno></c> must be an atom.</p> @@ -2541,7 +2639,7 @@ false</code> </func> <func> - <name name="is_reference" arity="1"/> + <name name="is_reference" arity="1" since=""/> <fsummary>Check whether a term is a reference.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a reference, @@ -2551,7 +2649,7 @@ false</code> </func> <func> - <name name="is_tuple" arity="1"/> + <name name="is_tuple" arity="1" since=""/> <fsummary>Check whether a term is a tuple.</fsummary> <desc> <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a tuple, @@ -2561,7 +2659,7 @@ false</code> </func> <func> - <name name="length" arity="1"/> + <name name="length" arity="1" since=""/> <fsummary>Length of a list.</fsummary> <desc> <p>Returns the length of <c><anno>List</anno></c>, for example:</p> @@ -2573,7 +2671,7 @@ false</code> </func> <func> - <name name="link" arity="1"/> + <name name="link" arity="1" since=""/> <fsummary>Create a link to another process (or port).</fsummary> <desc> <p>Creates a link between the calling process and another @@ -2600,7 +2698,7 @@ false</code> </func> <func> - <name name="list_to_atom" arity="1"/> + <name name="list_to_atom" arity="1" since=""/> <fsummary>Convert from text representation to an atom.</fsummary> <desc> <p>Returns the atom whose text representation is @@ -2620,7 +2718,7 @@ false</code> </func> <func> - <name name="list_to_binary" arity="1"/> + <name name="list_to_binary" arity="1" since=""/> <fsummary>Convert a list to a binary.</fsummary> <desc> <p>Returns a binary that is made from the integers and @@ -2638,7 +2736,7 @@ false</code> </func> <func> - <name name="list_to_bitstring" arity="1"/> + <name name="list_to_bitstring" arity="1" since=""/> <fsummary>Convert a list to a bitstring.</fsummary> <type name="bitstring_list"/> <desc> @@ -2659,7 +2757,7 @@ false</code> </func> <func> - <name name="list_to_existing_atom" arity="1"/> + <name name="list_to_existing_atom" arity="1" since=""/> <fsummary>Convert from text representation to an atom.</fsummary> <desc> <p>Returns the atom whose text representation is @@ -2680,7 +2778,7 @@ false</code> </func> <func> - <name name="list_to_float" arity="1"/> + <name name="list_to_float" arity="1" since=""/> <fsummary>Convert from text representation to a float.</fsummary> <desc> <p>Returns the float whose text representation is @@ -2694,7 +2792,7 @@ false</code> </func> <func> - <name name="list_to_integer" arity="1"/> + <name name="list_to_integer" arity="1" since=""/> <fsummary>Convert from text representation to an integer.</fsummary> <desc> <p>Returns an integer whose text representation is @@ -2708,7 +2806,7 @@ false</code> </func> <func> - <name name="list_to_integer" arity="2"/> + <name name="list_to_integer" arity="2" since=""/> <fsummary>Convert from text representation to an integer.</fsummary> <desc> <p>Returns an integer whose text representation in base @@ -2723,7 +2821,7 @@ false</code> </func> <func> - <name name="list_to_pid" arity="1"/> + <name name="list_to_pid" arity="1" since=""/> <fsummary>Convert from text representation to a pid.</fsummary> <desc> <p>Returns a process identifier whose text representation is a @@ -2741,7 +2839,7 @@ false</code> </func> <func> - <name name="list_to_port" arity="1"/> + <name name="list_to_port" arity="1" since="OTP 20.0"/> <fsummary>Convert from text representation to a port.</fsummary> <desc> <p>Returns a port identifier whose text representation is a @@ -2759,7 +2857,7 @@ false</code> </func> <func> - <name name="list_to_ref" arity="1"/> + <name name="list_to_ref" arity="1" since="OTP 20.0"/> <fsummary>Convert from text representation to a ref.</fsummary> <desc> <p>Returns a reference whose text representation is a @@ -2777,7 +2875,7 @@ false</code> </func> <func> - <name name="list_to_tuple" arity="1"/> + <name name="list_to_tuple" arity="1" since=""/> <fsummary>Convert a list to a tuple.</fsummary> <desc> <p>Returns a tuple corresponding to <c><anno>List</anno></c>, @@ -2790,7 +2888,7 @@ false</code> </func> <func> - <name name="load_module" arity="2"/> + <name name="load_module" arity="2" since=""/> <fsummary>Load object code for a module.</fsummary> <desc> <p>If <c><anno>Binary</anno></c> contains the object code for module @@ -2823,7 +2921,7 @@ false</code> </func> <func> - <name name="load_nif" arity="2"/> + <name name="load_nif" arity="2" since=""/> <fsummary>Load NIF library.</fsummary> <desc> <p>Loads and links a dynamic library containing native @@ -2876,7 +2974,7 @@ false</code> </func> <func> - <name name="loaded" arity="0"/> + <name name="loaded" arity="0" since=""/> <fsummary>List all loaded modules.</fsummary> <desc> <p>Returns a list of all loaded Erlang modules (current and @@ -2887,7 +2985,7 @@ false</code> </func> <func> - <name name="localtime" arity="0"/> + <name name="localtime" arity="0" since=""/> <fsummary>Current local date and time.</fsummary> <desc> <p>Returns the current local date and time, @@ -2902,7 +3000,7 @@ false</code> </func> <func> - <name name="localtime_to_universaltime" arity="1"/> + <name name="localtime_to_universaltime" arity="1" since=""/> <fsummary>Convert from local to Universal Time Coordinated (UTC) date and time.</fsummary> <desc> @@ -2919,7 +3017,7 @@ false</code> </func> <func> - <name name="localtime_to_universaltime" arity="2"/> + <name name="localtime_to_universaltime" arity="2" since=""/> <fsummary>Convert from local to Universal Time Coordinated (UTC) date and time.</fsummary> <desc> @@ -2945,7 +3043,7 @@ false</code> </func> <func> - <name name="make_ref" arity="0"/> + <name name="make_ref" arity="0" since=""/> <fsummary>Return a unique reference.</fsummary> <desc> <p>Returns a @@ -2962,7 +3060,7 @@ false</code> </func> <func> - <name name="make_tuple" arity="2"/> + <name name="make_tuple" arity="2" since=""/> <fsummary>Create a new tuple of a specified arity.</fsummary> <desc> <p>Creates a new tuple of the specified <c><anno>Arity</anno></c>, where @@ -2974,7 +3072,7 @@ false</code> </func> <func> - <name name="make_tuple" arity="3"/> + <name name="make_tuple" arity="3" since=""/> <fsummary>Create a new tuple with specifed arity and contents.</fsummary> <desc> <p>Creates a tuple of size <c><anno>Arity</anno></c>, where each element @@ -2992,7 +3090,7 @@ false</code> </func> <func> - <name name="map_get" arity="2" /> + <name name="map_get" arity="2" since="OTP 21.0"/> <fsummary>Extract a value from a map</fsummary> <desc> <p>Returns value <c><anno>Value</anno></c> associated with @@ -3007,11 +3105,12 @@ false</code> Map = #{42 => value_two,1337 => "value one","a" => 1}, map_get(Key,Map). "value one"</code> + <p>Allowed in guard tests.</p> </desc> </func> <func> - <name name="map_size" arity="1"/> + <name name="map_size" arity="1" since="OTP 17.0"/> <fsummary>Return the size of a map.</fsummary> <desc> <p>Returns an integer, which is the number of key-value pairs @@ -3024,7 +3123,7 @@ false</code> </func> <func> - <name name="match_spec_test" arity="3"/> + <name name="match_spec_test" arity="3" since="OTP 19.0"/> <fsummary>Test that a match specification works.</fsummary> <desc> <p>Tests a match specification used in calls to @@ -3062,7 +3161,7 @@ false</code> </func> <func> - <name name="max" arity="2"/> + <name name="max" arity="2" since=""/> <fsummary>Return the largest of two terms.</fsummary> <desc> <p>Returns the largest of <c><anno>Term1</anno></c> and @@ -3072,7 +3171,7 @@ false</code> </func> <func> - <name name="md5" arity="1"/> + <name name="md5" arity="1" since=""/> <fsummary>Compute an MD5 message digest.</fsummary> <desc> <p>Computes an MD5 message digest from <c><anno>Data</anno></c>, where @@ -3090,7 +3189,7 @@ false</code> </func> <func> - <name name="md5_final" arity="1"/> + <name name="md5_final" arity="1" since=""/> <fsummary>Finish the update of an MD5 context and return the computed MD5 message digest.</fsummary> <desc> @@ -3100,7 +3199,7 @@ false</code> </func> <func> - <name name="md5_init" arity="0"/> + <name name="md5_init" arity="0" since=""/> <fsummary>Create an MD5 context.</fsummary> <desc> <p>Creates an MD5 context, to be used in the following calls to @@ -3109,7 +3208,7 @@ false</code> </func> <func> - <name name="md5_update" arity="2"/> + <name name="md5_update" arity="2" since=""/> <fsummary>Update an MD5 context with data and return a new context. </fsummary> <desc> @@ -3120,7 +3219,7 @@ false</code> </func> <func> - <name name="memory" arity="0"/> + <name name="memory" arity="0" since=""/> <fsummary>Information about dynamically allocated memory.</fsummary> <type name="memory_type"/> <desc> @@ -3264,8 +3363,8 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="memory" arity="1" clause_i="1"/> - <name name="memory" arity="1" clause_i="2"/> + <name name="memory" arity="1" clause_i="1" since=""/> + <name name="memory" arity="1" clause_i="2" since=""/> <fsummary>Information about dynamically allocated memory.</fsummary> <type name="memory_type"/> <desc> @@ -3304,7 +3403,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="min" arity="2"/> + <name name="min" arity="2" since=""/> <fsummary>Return the smallest of two terms.</fsummary> <desc> <p>Returns the smallest of <c><anno>Term1</anno></c> and @@ -3314,7 +3413,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="module_loaded" arity="1"/> + <name name="module_loaded" arity="1" since=""/> <fsummary>Check if a module is loaded.</fsummary> <desc> <p>Returns <c>true</c> if the module <c><anno>Module</anno></c> @@ -3329,9 +3428,9 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="monitor" arity="2" clause_i="1"/> - <name name="monitor" arity="2" clause_i="2"/> - <name name="monitor" arity="2" clause_i="3"/> + <name name="monitor" arity="2" clause_i="1" since=""/> + <name name="monitor" arity="2" clause_i="2" since="OTP 19.0"/> + <name name="monitor" arity="2" clause_i="3" since="OTP 18.0"/> <fsummary>Start monitoring.</fsummary> <type name="registered_name"/> <type name="registered_process_identifier"/> @@ -3503,7 +3602,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="monitor_node" arity="2"/> + <name name="monitor_node" arity="2" since=""/> <fsummary>Monitor the status of a node.</fsummary> <desc> <p>Monitor the status of the node <c><anno>Node</anno></c>. @@ -3527,7 +3626,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="monitor_node" arity="3"/> + <name name="monitor_node" arity="3" since=""/> <fsummary>Monitor the status of a node.</fsummary> <desc> <p>Behaves as @@ -3553,7 +3652,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="monotonic_time" arity="0"/> + <name name="monotonic_time" arity="0" since="OTP 18.0"/> <fsummary>Current Erlang monotonic time.</fsummary> <desc> <p>Returns the current @@ -3587,7 +3686,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="monotonic_time" arity="1"/> + <name name="monotonic_time" arity="1" since="OTP 18.0"/> <fsummary>Current Erlang monotonic time.</fsummary> <desc> <p>Returns the current @@ -3605,7 +3704,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="nif_error" arity="1"/> + <name name="nif_error" arity="1" since="OTP R14B"/> <fsummary>Stop execution with a specified reason.</fsummary> <desc> <p>Works exactly like @@ -3618,7 +3717,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="nif_error" arity="2"/> + <name name="nif_error" arity="2" since="OTP R14B"/> <fsummary>Stop execution with a specified reason.</fsummary> <desc> <p>Works exactly like @@ -3631,7 +3730,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="node" arity="0"/> + <name name="node" arity="0" since=""/> <fsummary>Name of the local node.</fsummary> <desc> <p>Returns the name of the local node. If the node is not alive, @@ -3641,7 +3740,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="node" arity="1"/> + <name name="node" arity="1" since=""/> <fsummary>At which node a pid, port, or reference originates.</fsummary> <desc> <p>Returns the node where <c><anno>Arg</anno></c> originates. @@ -3654,7 +3753,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="nodes" arity="0"/> + <name name="nodes" arity="0" since=""/> <fsummary>All visible nodes in the system.</fsummary> <desc> <p>Returns a list of all visible nodes in the system, except @@ -3663,7 +3762,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="nodes" arity="1"/> + <name name="nodes" arity="1" since=""/> <fsummary>All nodes of a certain type in the system.</fsummary> <desc> <p>Returns a list of nodes according to the argument specified. @@ -3706,7 +3805,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="now" arity="0"/> + <name name="now" arity="0" since=""/> <fsummary>Elapsed time since 00:00 GMT.</fsummary> <type name="timestamp"/> <desc> @@ -3735,7 +3834,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="open_port" arity="2"/> + <name name="open_port" arity="2" since=""/> <fsummary>Open a port.</fsummary> <desc> <p>Returns a port identifier as the result of opening a @@ -3772,13 +3871,6 @@ RealSystem = system + MissedSystem</code> If found, that driver is started. A driver runs in the Erlang work space, which means that it is linked with the Erlang runtime system.</p> - <p>When starting external programs on Solaris, the system - call <c>vfork</c> is used in preference to <c>fork</c> - for performance reasons, although it has a history of - being less robust. If there are problems using - <c>vfork</c>, setting environment variable - <c>ERL_NO_VFORK</c> to any value causes <c>fork</c> - to be used instead.</p> <p>For external programs, <c>PATH</c> is searched (or an equivalent method is used to find programs, depending on the OS). This is done by invoking @@ -4083,7 +4175,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="phash" arity="2"/> + <name name="phash" arity="2" since=""/> <fsummary>Portable hash function.</fsummary> <type_desc variable="Range">Range = 1..2^32, Hash = 1..Range</type_desc> <desc> @@ -4098,8 +4190,8 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="phash2" arity="1"/> - <name name="phash2" arity="2"/> + <name name="phash2" arity="1" since=""/> + <name name="phash2" arity="2" since=""/> <fsummary>Portable hash function.</fsummary> <type_desc variable="Range">1..2^32</type_desc> <type_desc variable="Hash">0..Range-1</type_desc> @@ -4123,7 +4215,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="pid_to_list" arity="1"/> + <name name="pid_to_list" arity="1" since=""/> <fsummary>Text representation of a pid.</fsummary> <desc> <p>Returns a string corresponding to the text @@ -4132,7 +4224,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_call" arity="3"/> + <name name="port_call" arity="3" since=""/> <fsummary>Perform a synchronous call to a port with term data.</fsummary> <desc> <p>Performs a synchronous call to a port. The meaning of @@ -4168,16 +4260,23 @@ RealSystem = system + MissedSystem</code> </item> <tag><c>badarg</c></tag> <item> - If the port driver so decides for any reason (probably + <p>If the port driver so decides for any reason (probably something wrong with <c><anno>Operation</anno></c> - or <c><anno>Data</anno></c>). + or <c><anno>Data</anno></c>).</p> + <warning> + <p>Do not call <c>port_call</c> with an unknown + <c><anno>Port</anno></c> identifier and expect <c>badarg</c> + exception. Any undefined behavior is possible (including node + crash) depending on how the port driver interprets the supplied + arguments.</p> + </warning> </item> </taglist> </desc> </func> <func> - <name name="port_close" arity="1"/> + <name name="port_close" arity="1" since=""/> <fsummary>Close an open port.</fsummary> <desc> <p>Closes an open port. Roughly the same as <c><anno>Port</anno> ! @@ -4217,7 +4316,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_command" arity="2"/> + <name name="port_command" arity="2" since=""/> <fsummary>Send data to a port.</fsummary> <desc> <p>Sends data to a port. Same as @@ -4260,11 +4359,16 @@ RealSystem = system + MissedSystem</code> <p>If <c><anno>Data</anno></c> is an invalid I/O list.</p> </item> </taglist> + <warning> + <p>Do not send data to an unknown port. Any undefined behavior is + possible (including node crash) depending on how the port driver + interprets the data.</p> + </warning> </desc> </func> <func> - <name name="port_command" arity="3"/> + <name name="port_command" arity="3" since=""/> <fsummary>Send data to a port.</fsummary> <desc> <p>Sends data to a port. <c>port_command(Port, Data, [])</c> @@ -4319,11 +4423,16 @@ RealSystem = system + MissedSystem</code> a busy port. </item> </taglist> + <warning> + <p>Do not send data to an unknown port. Any undefined behavior is + possible (including node crash) depending on how the port driver + interprets the data.</p> + </warning> </desc> </func> <func> - <name name="port_connect" arity="2"/> + <name name="port_connect" arity="2" since=""/> <fsummary>Set the owner of a port.</fsummary> <desc> <p>Sets the port owner (the connected port) to <c><anno>Pid</anno></c>. @@ -4392,7 +4501,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_control" arity="3"/> + <name name="port_control" arity="3" since=""/> <fsummary>Perform a synchronous control operation on a port.</fsummary> <desc> <p>Performs a synchronous control operation on a port. @@ -4423,13 +4532,20 @@ RealSystem = system + MissedSystem</code> If the port driver so decides for any reason (probably something wrong with <c><anno>Operation</anno></c> or <c><anno>Data</anno></c>). + <warning> + <p>Do not call <c>port_control/3</c> with an unknown + <c><anno>Port</anno></c> identifier and expect <c>badarg</c> + exception. Any undefined behavior is possible (including node + crash) depending on how the port driver interprets the supplied + arguments.</p> + </warning> </item> </taglist> </desc> </func> <func> - <name name="port_info" arity="1"/> + <name name="port_info" arity="1" since=""/> <fsummary>Information about a port.</fsummary> <desc> <p>Returns a list containing tuples with information about @@ -4460,7 +4576,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="1"/> + <name name="port_info" arity="2" clause_i="1" since=""/> <fsummary>Information about the connected process of a port.</fsummary> <desc> <p><c><anno>Pid</anno></c> is the process identifier of the process @@ -4476,7 +4592,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="2"/> + <name name="port_info" arity="2" clause_i="2" since=""/> <fsummary>Information about the internal index of a port.</fsummary> <desc> <p><c><anno>Index</anno></c> is the internal index of the port. This @@ -4492,7 +4608,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="3"/> + <name name="port_info" arity="2" clause_i="3" since=""/> <fsummary>Information about the input of a port.</fsummary> <desc> <p><c><anno>Bytes</anno></c> is the total number of bytes @@ -4508,7 +4624,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="4"/> + <name name="port_info" arity="2" clause_i="4" since=""/> <fsummary>Information about the links of a port.</fsummary> <desc> <p><c><anno>Pids</anno></c> is a list of the process identifiers @@ -4524,7 +4640,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="5"/> + <name name="port_info" arity="2" clause_i="5" since="OTP R16B"/> <fsummary>Information about the locking of a port.</fsummary> <desc> <p><c><anno>Locking</anno></c> is one of the following:</p> @@ -4545,9 +4661,10 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="6"/> + <name name="port_info" arity="2" clause_i="6" since="OTP R16B"/> <fsummary>Information about the memory size of a port.</fsummary> <desc> + <marker id="port_info_memory"/> <p><c><anno>Bytes</anno></c> is the total number of bytes allocated for this port by the runtime system. The port itself can have allocated memory that is not @@ -4563,7 +4680,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="7"/> + <name name="port_info" arity="2" clause_i="7" since="OTP R16B"/> <fsummary>Information about the monitors of a port.</fsummary> <desc> <p><c><anno>Monitors</anno></c> represent processes monitored by @@ -4579,7 +4696,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="8"/> + <name name="port_info" arity="2" clause_i="8" since="OTP 19.0"/> <fsummary>Which processes are monitoring this port.</fsummary> <desc> <p>Returns list of pids that are monitoring given port at the @@ -4595,7 +4712,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="9"/> + <name name="port_info" arity="2" clause_i="9" since=""/> <fsummary>Information about the name of a port.</fsummary> <desc> <p><c><anno>Name</anno></c> is the command name set by @@ -4611,7 +4728,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="10"/> + <name name="port_info" arity="2" clause_i="10" since="OTP R16B"/> <fsummary>Information about the OS pid of a port.</fsummary> <desc> <p><c><anno>OsPid</anno></c> is the process identifier (or equivalent) @@ -4630,7 +4747,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="11"/> + <name name="port_info" arity="2" clause_i="11" since=""/> <fsummary>Information about the output of a port.</fsummary> <desc> <p><c><anno>Bytes</anno></c> is the total number of bytes written @@ -4649,7 +4766,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="12"/> + <name name="port_info" arity="2" clause_i="12" since="OTP R16B"/> <fsummary>Information about the parallelism hint of a port.</fsummary> <desc> <p><c><anno>Boolean</anno></c> corresponds to the port parallelism @@ -4660,7 +4777,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="13"/> + <name name="port_info" arity="2" clause_i="13" since="OTP R16B"/> <fsummary>Information about the queue size of a port.</fsummary> <desc> <p><c><anno>Bytes</anno></c> is the total number @@ -4677,7 +4794,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_info" arity="2" clause_i="14"/> + <name name="port_info" arity="2" clause_i="14" since=""/> <fsummary>Information about the registered name of a port.</fsummary> <desc> <p><c><anno>RegisteredName</anno></c> is the registered name of @@ -4694,7 +4811,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="port_to_list" arity="1"/> + <name name="port_to_list" arity="1" since=""/> <fsummary>Text representation of a port identifier.</fsummary> <desc> <p>Returns a string corresponding to the text @@ -4703,7 +4820,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="ports" arity="0"/> + <name name="ports" arity="0" since=""/> <fsummary>List all existing ports.</fsummary> <desc> <p>Returns a list of port identifiers corresponding to all the @@ -4713,7 +4830,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="pre_loaded" arity="0"/> + <name name="pre_loaded" arity="0" since=""/> <fsummary>List all preloaded modules.</fsummary> <desc> <p>Returns a list of Erlang modules that are preloaded in @@ -4724,7 +4841,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_display" arity="2"/> + <name name="process_display" arity="2" since=""/> <fsummary>Write information about a local process on standard error. </fsummary> <desc> @@ -4738,7 +4855,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_flag" arity="2" clause_i="1"/> + <name name="process_flag" arity="2" clause_i="1" since=""/> <fsummary>Set process flag trap_exit for the calling process.</fsummary> <desc> <p>When <c>trap_exit</c> is set to <c>true</c>, exit signals @@ -4755,7 +4872,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_flag" arity="2" clause_i="2"/> + <name name="process_flag" arity="2" clause_i="2" since=""/> <fsummary>Set process flag error_handler for the calling process. </fsummary> <desc> @@ -4770,7 +4887,7 @@ RealSystem = system + MissedSystem</code> <func> <name name="process_flag" arity="2" clause_i="3" - anchor="process_flag_min_heap_size"/> + anchor="process_flag_min_heap_size" since=""/> <fsummary>Set process flag min_heap_size for the calling process. </fsummary> <desc> @@ -4780,7 +4897,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_flag" arity="2" clause_i="4"/> + <name name="process_flag" arity="2" clause_i="4" since="OTP R13B04"/> <fsummary>Set process flag min_bin_vheap_size for the calling process. </fsummary> <desc> @@ -4792,7 +4909,7 @@ RealSystem = system + MissedSystem</code> <func> <name name="process_flag" arity="2" clause_i="5" - anchor="process_flag_max_heap_size"/> + anchor="process_flag_max_heap_size" since="OTP 19.0"/> <fsummary>Set process flag max_heap_size for the calling process. </fsummary> <type name="max_heap_size"/> @@ -4866,7 +4983,7 @@ RealSystem = system + MissedSystem</code> <func> <name name="process_flag" arity="2" clause_i="6" - anchor="process_flag_message_queue_data"/> + anchor="process_flag_message_queue_data" since="OTP 19.0"/> <fsummary>Set process flag message_queue_data for the calling process. </fsummary> <type name="message_queue_data"/> @@ -4908,7 +5025,7 @@ RealSystem = system + MissedSystem</code> <func> <name name="process_flag" arity="2" clause_i="7" - anchor="process_flag_priority"/> + anchor="process_flag_priority" since=""/> <fsummary>Set process flag priority for the calling process.</fsummary> <type name="priority_level"/> <desc> @@ -4980,7 +5097,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_flag" arity="2" clause_i="8"/> + <name name="process_flag" arity="2" clause_i="8" since=""/> <fsummary>Set process flag save_calls for the calling process.</fsummary> <desc> <p><c><anno>N</anno></c> must be an integer in the interval 0..10000. @@ -5011,7 +5128,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_flag" arity="2" clause_i="9"/> + <name name="process_flag" arity="2" clause_i="9" since=""/> <fsummary>Set process flag sensitive for the calling process.</fsummary> <desc> <p>Sets or clears flag <c>sensitive</c> for the current process. @@ -5045,7 +5162,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_flag" arity="3"/> + <name name="process_flag" arity="3" since=""/> <fsummary>Set process flags for a process.</fsummary> <desc> <p>Sets certain flags for the process <c><anno>Pid</anno></c>, @@ -5060,7 +5177,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_info" arity="1"/> + <name name="process_info" arity="1" since=""/> <fsummary>Information about a process.</fsummary> <type name="process_info_result_item"/> <type name="priority_level"/> @@ -5111,8 +5228,8 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_info" arity="2" clause_i="1"/> - <name name="process_info" arity="2" clause_i="2"/> + <name name="process_info" arity="2" clause_i="1" since=""/> + <name name="process_info" arity="2" clause_i="2" since=""/> <fsummary>Information about a process.</fsummary> <type name="process_info_item"/> <type name="process_info_result_item"/> @@ -5180,11 +5297,13 @@ RealSystem = system + MissedSystem</code> changed or removed without prior notice.</p> </item> <tag><c>{current_function, {<anno>Module</anno>, - <anno>Function</anno>, Arity}}</c></tag> + <anno>Function</anno>, Arity} | undefined}</c></tag> <item> <p><c><anno>Module</anno></c>, <c><anno>Function</anno></c>, <c><anno>Arity</anno></c> is - the current function call of the process.</p> + the current function call of the process. The value + <c>undefined</c> can be returned if the process is + currently executing native compiled code.</p> </item> <tag><c>{current_location, {<anno>Module</anno>, <anno>Function</anno>, <anno>Arity</anno>, @@ -5270,6 +5389,7 @@ RealSystem = system + MissedSystem</code> </item> <tag><c>{memory, <anno>Size</anno>}</c></tag> <item> + <marker id="process_info_memory"/> <p><c><anno>Size</anno></c> is the size in bytes of the process. This includes call stack, heap, and internal structures.</p> </item> @@ -5295,10 +5415,10 @@ RealSystem = system + MissedSystem</code> <p><c><anno>MinBinVHeapSize</anno></c> is the minimum binary virtual heap size for the process.</p> </item> - <tag><c>{monitored_by, <anno>Pids</anno>}</c></tag> + <tag><c>{monitored_by, <anno>MonitoredBy</anno>}</c></tag> <item> - <p>A list of process identifiers monitoring the process (with - <c>monitor/2</c>).</p> + <p>A list of identifiers for all the processes, ports and NIF + resources, that are monitoring the process.</p> </item> <tag><c>{monitors, <anno>Monitors</anno>}</c></tag> <item> @@ -5445,7 +5565,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="processes" arity="0"/> + <name name="processes" arity="0" since=""/> <fsummary>All processes.</fsummary> <desc> <p>Returns a list of process identifiers corresponding to @@ -5462,7 +5582,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="purge_module" arity="1"/> + <name name="purge_module" arity="1" since=""/> <fsummary>Remove old code for a module.</fsummary> <desc> <p>Removes old code for <c><anno>Module</anno></c>. @@ -5487,7 +5607,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="put" arity="2"/> + <name name="put" arity="2" since=""/> <fsummary>Add a new value to the process dictionary.</fsummary> <desc> <p>Adds a new <c><anno>Key</anno></c> to the process dictionary, @@ -5509,7 +5629,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="raise" arity="3"/> + <name name="raise" arity="3" since=""/> <fsummary>Stop execution with an exception of specified class, reason, and call stack backtrace.</fsummary> <type name="raise_stacktrace"/> @@ -5548,7 +5668,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="read_timer" arity="1"/> + <name name="read_timer" arity="1" since=""/> <fsummary>Read the state of a timer.</fsummary> <desc> <p>Reads the state of a timer. The same as calling @@ -5558,7 +5678,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="read_timer" arity="2"/> + <name name="read_timer" arity="2" since="OTP 18.0"/> <fsummary>Read the state of a timer.</fsummary> <desc> <p>Reads the state of a timer that has been created by either @@ -5614,7 +5734,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="ref_to_list" arity="1"/> + <name name="ref_to_list" arity="1" since=""/> <fsummary>Text representation of a reference.</fsummary> <desc> <p>Returns a string corresponding to the text @@ -5627,7 +5747,7 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="register" arity="2"/> + <name name="register" arity="2" since=""/> <fsummary>Register a name for a pid (or port).</fsummary> <desc> <p>Associates the name <c><anno>RegName</anno></c> with a process @@ -5656,7 +5776,7 @@ true</pre> </func> <func> - <name name="registered" arity="0"/> + <name name="registered" arity="0" since=""/> <fsummary>All registered names.</fsummary> <desc> <p>Returns a list of names that have been registered using @@ -5669,7 +5789,7 @@ true</pre> </func> <func> - <name name="resume_process" arity="1"/> + <name name="resume_process" arity="1" since=""/> <fsummary>Resume a suspended process.</fsummary> <desc> <p>Decreases the suspend count on the process identified by @@ -5710,7 +5830,7 @@ true</pre> </func> <func> - <name name="round" arity="1"/> + <name name="round" arity="1" since=""/> <fsummary>Return an integer by rounding a number.</fsummary> <desc> <p>Returns an integer by rounding <c><anno>Number</anno></c>, @@ -5723,7 +5843,7 @@ true</pre> </func> <func> - <name name="self" arity="0"/> + <name name="self" arity="0" since=""/> <fsummary>Return pid of the calling process.</fsummary> <desc> <p>Returns the process identifier of the calling process, for @@ -5736,7 +5856,7 @@ true</pre> </func> <func> - <name name="send" arity="2"/> + <name name="send" arity="2" since=""/> <fsummary>Send a message.</fsummary> <type name="dst"/> <desc> @@ -5756,7 +5876,7 @@ true</pre> </func> <func> - <name name="send" arity="3"/> + <name name="send" arity="3" since=""/> <fsummary>Send a message conditionally.</fsummary> <type name="dst"/> <desc> @@ -5788,7 +5908,7 @@ true</pre> </func> <func> - <name name="send_after" arity="3"/> + <name name="send_after" arity="3" since=""/> <fsummary>Start a timer.</fsummary> <desc> <p>Starts a timer. The same as calling @@ -5799,7 +5919,7 @@ true</pre> </func> <func> - <name name="send_after" arity="4"/> + <name name="send_after" arity="4" since="OTP 18.0"/> <fsummary>Start a timer.</fsummary> <desc> <p>Starts a timer. When the timer expires, the message @@ -5812,7 +5932,7 @@ true</pre> </func> <func> - <name name="send_nosuspend" arity="2"/> + <name name="send_nosuspend" arity="2" since=""/> <fsummary>Try to send a message without ever blocking.</fsummary> <type name="dst"/> <desc> @@ -5862,7 +5982,7 @@ true</pre> </func> <func> - <name name="send_nosuspend" arity="3"/> + <name name="send_nosuspend" arity="3" since=""/> <fsummary>Try to send a message without ever blocking.</fsummary> <type name="dst"/> <desc> @@ -5895,7 +6015,7 @@ true</pre> </func> <func> - <name name="set_cookie" arity="2"/> + <name name="set_cookie" arity="2" since=""/> <fsummary>Set the magic cookie of a node.</fsummary> <desc> <p>Sets the magic cookie of <c><anno>Node</anno></c> to the atom @@ -5912,7 +6032,7 @@ true</pre> </func> <func> - <name name="setelement" arity="3"/> + <name name="setelement" arity="3" since=""/> <fsummary>Set the Nth element of a tuple.</fsummary> <type_desc variable="Index">1..tuple_size(<anno>Tuple1</anno></type_desc> <desc> @@ -5929,7 +6049,7 @@ true</pre> </func> <func> - <name name="size" arity="1"/> + <name name="size" arity="1" since=""/> <fsummary>Size of a tuple or binary.</fsummary> <desc> <p>Returns the number of elements in a tuple or the number of @@ -5952,7 +6072,7 @@ true</pre> </func> <func> - <name name="spawn" arity="1"/> + <name name="spawn" arity="1" since=""/> <fsummary>Create a new process with a fun as entry point.</fsummary> <desc> <p>Returns the process identifier of a new process started by the @@ -5963,7 +6083,7 @@ true</pre> </func> <func> - <name name="spawn" arity="2"/> + <name name="spawn" arity="2" since=""/> <fsummary>Create a new process with a fun as entry point on a specified node.</fsummary> <desc> @@ -5977,7 +6097,7 @@ true</pre> </func> <func> - <name name="spawn" arity="3"/> + <name name="spawn" arity="3" since=""/> <fsummary>Create a new process with a function as entry point.</fsummary> <desc> <p>Returns the process identifier of a new process started by @@ -6002,7 +6122,7 @@ true</pre> </func> <func> - <name name="spawn" arity="4"/> + <name name="spawn" arity="4" since=""/> <fsummary>Create a new process with a function as entry point on a specified node.</fsummary> <desc> @@ -6017,7 +6137,7 @@ true</pre> </func> <func> - <name name="spawn_link" arity="1"/> + <name name="spawn_link" arity="1" since=""/> <fsummary>Create and link to a new process with a fun as entry point. </fsummary> <desc> @@ -6031,7 +6151,7 @@ true</pre> </func> <func> - <name name="spawn_link" arity="2"/> + <name name="spawn_link" arity="2" since=""/> <fsummary>Create and link to a new process with a fun as entry point on a specified node.</fsummary> <desc> @@ -6048,7 +6168,7 @@ true</pre> </func> <func> - <name name="spawn_link" arity="3"/> + <name name="spawn_link" arity="3" since=""/> <fsummary>Create and link to a new process with a function as entry point. </fsummary> <desc> @@ -6062,7 +6182,7 @@ true</pre> </func> <func> - <name name="spawn_link" arity="4"/> + <name name="spawn_link" arity="4" since=""/> <fsummary>Create and link to a new process with a function as entry point on a specified node.</fsummary> <desc> @@ -6080,7 +6200,7 @@ true</pre> </func> <func> - <name name="spawn_monitor" arity="1"/> + <name name="spawn_monitor" arity="1" since=""/> <fsummary>Create and monitor a new process with a fun as entry point. </fsummary> <desc> @@ -6094,7 +6214,7 @@ true</pre> </func> <func> - <name name="spawn_monitor" arity="3"/> + <name name="spawn_monitor" arity="3" since=""/> <fsummary>Create and monitor a new process with a function as entry point. </fsummary> <desc> @@ -6108,7 +6228,7 @@ true</pre> </func> <func> - <name name="spawn_opt" arity="2"/> + <name name="spawn_opt" arity="2" since=""/> <fsummary>Create a new process with a fun as entry point.</fsummary> <type name="priority_level"/> <type name="max_heap_size"/> @@ -6126,7 +6246,7 @@ true</pre> </func> <func> - <name name="spawn_opt" arity="3"/> + <name name="spawn_opt" arity="3" since=""/> <fsummary>Create a new process with a fun as entry point on a specified node.</fsummary> <type name="priority_level"/> @@ -6144,7 +6264,7 @@ true</pre> </func> <func> - <name name="spawn_opt" arity="4"/> + <name name="spawn_opt" arity="4" since=""/> <fsummary>Create a new process with a function as entry point.</fsummary> <type name="priority_level"/> <type name="max_heap_size"/> @@ -6170,7 +6290,7 @@ true</pre> <p>Monitors the new process (like <seealso marker="#monitor/2"><c>monitor/2</c></seealso> does).</p> </item> - <tag><c>{priority, <anno>Level</anno></c></tag> + <tag><c>{priority, <anno>Level</anno>}</c></tag> <item> <p>Sets the priority of the new process. Equivalent to executing <seealso marker="#process_flag_priority"> @@ -6280,7 +6400,7 @@ true</pre> </func> <func> - <name name="spawn_opt" arity="5"/> + <name name="spawn_opt" arity="5" since=""/> <fsummary>Create a new process with a function as entry point on a specified node.</fsummary> <type name="priority_level"/> @@ -6303,7 +6423,7 @@ true</pre> </func> <func> - <name name="split_binary" arity="2"/> + <name name="split_binary" arity="2" since=""/> <fsummary>Split a binary into two.</fsummary> <type_desc variable="Pos">0..byte_size(Bin)</type_desc> <desc> @@ -6327,7 +6447,7 @@ true</pre> </func> <func> - <name name="start_timer" arity="3"/> + <name name="start_timer" arity="3" since=""/> <fsummary>Start a timer.</fsummary> <desc> <p>Starts a timer. The same as calling @@ -6338,7 +6458,7 @@ true</pre> </func> <func> - <name name="start_timer" arity="4"/> + <name name="start_timer" arity="4" since="OTP 18.0"/> <fsummary>Start a timer.</fsummary> <desc> <p>Starts a timer. When the timer expires, the message @@ -6397,7 +6517,7 @@ true</pre> <func> <name name="statistics" arity="1" clause_i="1" - anchor="statistics_active_tasks"/> + anchor="statistics_active_tasks" since="OTP 18.3"/> <fsummary>Information about active processes and ports.</fsummary> <desc> <p>Returns the same as @@ -6412,7 +6532,7 @@ true</pre> <func> <name name="statistics" arity="1" clause_i="2" - anchor="statistics_active_tasks_all"/> + anchor="statistics_active_tasks_all" since="OTP 20.0"/> <fsummary>Information about active processes and ports.</fsummary> <desc> <p>Returns a list where each element represents the amount @@ -6453,7 +6573,7 @@ true</pre> </func> <func> - <name name="statistics" arity="1" clause_i="3"/> + <name name="statistics" arity="1" clause_i="3" since=""/> <fsummary>Information about context switches.</fsummary> <desc> <p>Returns the total number of context switches since the @@ -6463,7 +6583,7 @@ true</pre> <func> <name name="statistics" arity="1" clause_i="4" - anchor="statistics_exact_reductions"/> + anchor="statistics_exact_reductions" since=""/> <fsummary>Information about exact reductions.</fsummary> <desc> <p>Returns the number of exact reductions.</p> @@ -6477,7 +6597,7 @@ true</pre> </func> <func> - <name name="statistics" arity="1" clause_i="5"/> + <name name="statistics" arity="1" clause_i="5" since=""/> <fsummary>Information about garbage collection.</fsummary> <desc> <p>Returns information about garbage collection, for example:</p> @@ -6489,7 +6609,7 @@ true</pre> </func> <func> - <name name="statistics" arity="1" clause_i="6"/> + <name name="statistics" arity="1" clause_i="6" since=""/> <fsummary>Information about I/O.</fsummary> <desc> <p>Returns <c><anno>Input</anno></c>, @@ -6501,7 +6621,7 @@ true</pre> <func> <name name="statistics" arity="1" clause_i="7" - anchor="statistics_microstate_accounting"/> + anchor="statistics_microstate_accounting" since="OTP 19.0"/> <fsummary>Information about microstate accounting.</fsummary> <desc> <p>Microstate accounting can be used to measure how much time the Erlang @@ -6559,7 +6679,7 @@ lists:map( <tag><c>async</c></tag> <item>Async threads are used by various linked-in drivers (mainly the file drivers) do offload non-CPU intensive work. See - <seealso marker="erts:erl#+async_thread_pool_size">erl +A</seealso> for more details.</item> + <seealso marker="erts:erl#async_thread_pool_size">erl +A</seealso> for more details.</item> <tag><c>aux</c></tag> <item>Takes care of any work that is not specifically assigned to a scheduler.</item> @@ -6644,7 +6764,7 @@ lists:map( <func> <name name="statistics" arity="1" clause_i="8" - anchor="statistics_reductions"/> + anchor="statistics_reductions" since=""/> <fsummary>Information about reductions.</fsummary> <desc> <p>Returns information about reductions, for example:</p> @@ -6663,7 +6783,7 @@ lists:map( <func> <name name="statistics" arity="1" clause_i="9" - anchor="statistics_run_queue"/> + anchor="statistics_run_queue" since=""/> <fsummary>Information about the run-queues.</fsummary> <desc> <p>Returns the total length of all normal run-queues. That is, the number @@ -6680,7 +6800,7 @@ lists:map( <func> <name name="statistics" arity="1" clause_i="10" - anchor="statistics_run_queue_lengths"/> + anchor="statistics_run_queue_lengths" since="OTP 18.3"/> <fsummary>Information about the run-queue lengths.</fsummary> <desc> <p>Returns the same as @@ -6695,7 +6815,7 @@ lists:map( <func> <name name="statistics" arity="1" clause_i="11" - anchor="statistics_run_queue_lengths_all"/> + anchor="statistics_run_queue_lengths_all" since="OTP 20.0"/> <fsummary>Information about the run-queue lengths.</fsummary> <desc> <p>Returns a list where each element represents the amount @@ -6737,7 +6857,7 @@ lists:map( </func> <func> - <name name="statistics" arity="1" clause_i="12"/> + <name name="statistics" arity="1" clause_i="12" since=""/> <fsummary>Information about runtime.</fsummary> <desc> <p>Returns information about runtime, in milliseconds.</p> @@ -6756,7 +6876,7 @@ lists:map( <func> <name name="statistics" arity="1" clause_i="13" - anchor="statistics_scheduler_wall_time"/> + anchor="statistics_scheduler_wall_time" since="OTP R15B01"/> <fsummary>Information about each schedulers work time.</fsummary> <desc> <p>Returns a list of tuples with @@ -6880,7 +7000,7 @@ ok <func> <name name="statistics" arity="1" clause_i="14" - anchor="statistics_scheduler_wall_time_all"/> + anchor="statistics_scheduler_wall_time_all" since="OTP 20.0"/> <fsummary>Information about each schedulers work time.</fsummary> <desc> <p>The same as @@ -6908,7 +7028,7 @@ ok </func> <func> <name name="statistics" arity="1" clause_i="15" - anchor="statistics_total_active_tasks"/> + anchor="statistics_total_active_tasks" since="OTP 18.3"/> <fsummary>Information about active processes and ports.</fsummary> <desc> <p>The same as calling @@ -6919,7 +7039,7 @@ ok <func> <name name="statistics" arity="1" clause_i="16" - anchor="statistics_total_active_tasks_all"/> + anchor="statistics_total_active_tasks_all" since="OTP 20.0"/> <fsummary>Information about active processes and ports.</fsummary> <desc> <p>The same as calling @@ -6930,7 +7050,7 @@ ok <func> <name name="statistics" arity="1" clause_i="17" - anchor="statistics_total_run_queue_lengths"/> + anchor="statistics_total_run_queue_lengths" since="OTP 18.3"/> <fsummary>Information about the run-queue lengths.</fsummary> <desc> <p>The same as calling @@ -6941,7 +7061,7 @@ ok <func> <name name="statistics" arity="1" clause_i="18" - anchor="statistics_total_run_queue_lengths_all"/> + anchor="statistics_total_run_queue_lengths_all" since="OTP 20.0"/> <fsummary>Information about the run-queue lengths.</fsummary> <desc> <p>The same as calling @@ -6951,7 +7071,7 @@ ok </func> <func> - <name name="statistics" arity="1" clause_i="19"/> + <name name="statistics" arity="1" clause_i="19" since=""/> <fsummary>Information about wall clock.</fsummary> <desc> <p>Returns information about wall clock. <c>wall_clock</c> can @@ -6962,7 +7082,7 @@ ok </func> <func> - <name name="suspend_process" arity="1"/> + <name name="suspend_process" arity="1" since=""/> <fsummary>Suspend a process.</fsummary> <desc> <p>Suspends the process identified by @@ -6977,7 +7097,7 @@ ok </func> <func> - <name name="suspend_process" arity="2"/> + <name name="suspend_process" arity="2" since=""/> <fsummary>Suspend a process.</fsummary> <desc> <p>Increases the suspend count on the process identified by @@ -7123,7 +7243,7 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="1"/> + <name name="system_flag" arity="2" clause_i="1" since=""/> <fsummary>Set system flag <c>backtrace_depth</c>.</fsummary> <desc> <p>Sets the maximum depth of call stack back-traces in the @@ -7136,7 +7256,7 @@ ok <func> <name name="system_flag" arity="2" clause_i="2" - anchor="system_flag_cpu_topology"/> + anchor="system_flag_cpu_topology" since=""/> <fsummary>Set system flag <c>cpu_topology</c>.</fsummary> <type name="cpu_topology"/> <type name="level_entry"/> @@ -7184,7 +7304,7 @@ ok <func> <name name="system_flag" arity="2" clause_i="3" - anchor="system_flag_dirty_cpu_schedulers_online"/> + anchor="system_flag_dirty_cpu_schedulers_online" since="OTP 17.0"/> <fsummary>Set system_flag_dirty_cpu_schedulers_online.</fsummary> <desc> <p> @@ -7212,7 +7332,7 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="4"/> + <name name="system_flag" arity="2" clause_i="4" since="OTP 20.2.3"/> <fsummary>Set system flag for erts_alloc.</fsummary> <desc> <p>Sets system flags for @@ -7229,7 +7349,7 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="5"/> + <name name="system_flag" arity="2" clause_i="5" since=""/> <fsummary>Set system flag fullsweep_after.</fsummary> <desc> <p>Sets system flag <c>fullsweep_after</c>. @@ -7249,7 +7369,7 @@ ok <func> <name name="system_flag" arity="2" clause_i="6" - anchor="system_flag_microstate_accounting"/> + anchor="system_flag_microstate_accounting" since="OTP 19.0"/> <fsummary>Set system flag microstate_accounting.</fsummary> <desc> <p> @@ -7262,7 +7382,7 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="7"/> + <name name="system_flag" arity="2" clause_i="7" since=""/> <fsummary>Set system flag min_heap_size.</fsummary> <desc> <p>Sets the default minimum heap size for processes. The size @@ -7277,7 +7397,7 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="8"/> + <name name="system_flag" arity="2" clause_i="8" since="OTP R13B04"/> <fsummary>Set system flag min_bin_vheap_size.</fsummary> <desc> <p>Sets the default minimum binary virtual heap size for @@ -7295,7 +7415,7 @@ ok <func> <name name="system_flag" arity="2" clause_i="9" - anchor="system_flag_max_heap_size"/> + anchor="system_flag_max_heap_size" since="OTP 19.0"/> <fsummary>Set system flag max_heap_size.</fsummary> <type name="max_heap_size"/> <desc> @@ -7313,7 +7433,7 @@ ok <func> <name name="system_flag" arity="2" clause_i="10" - anchor="system_flag_multi_scheduling"/> + anchor="system_flag_multi_scheduling" since=""/> <fsummary>Set system flag multi_scheduling.</fsummary> <desc> <p> @@ -7369,7 +7489,7 @@ ok <func> <name name="system_flag" arity="2" clause_i="11" - anchor="system_flag_scheduler_bind_type"/> + anchor="system_flag_scheduler_bind_type" since=""/> <fsummary>Set system flag scheduler_bind_type.</fsummary> <type name="scheduler_bind_type"/> <desc> @@ -7496,7 +7616,7 @@ ok <func> <name name="system_flag" arity="2" clause_i="12" - anchor="system_flag_scheduler_wall_time"/> + anchor="system_flag_scheduler_wall_time" since="OTP R15B01"/> <fsummary>Set system flag scheduler_wall_time.</fsummary> <desc> <p> @@ -7509,7 +7629,7 @@ ok <func> <name name="system_flag" arity="2" clause_i="13" - anchor="system_flag_schedulers_online"/> + anchor="system_flag_schedulers_online" since=""/> <fsummary>Set system flag schedulers_online.</fsummary> <desc> <p> @@ -7537,7 +7657,39 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="14"/> + <name name="system_flag" arity="2" clause_i="14" since="OTP 21.3"/> + <fsummary>Set system logger process.</fsummary> + <desc> + <p>Sets the process that will receive the logging + messages generated by ERTS. If set to <c>undefined</c>, + all logging messages generated by ERTS will be dropped. + The messages will be in the format:</p> + <code> +{log,Level,Format,ArgList,Metadata} where + +Level = atom(), +Format = string(), +ArgList = list(term()), +Metadata = #{ pid => pid(), + group_leader => pid(), + time := logger:timestamp(), + error_logger := #{ emulator := true, tag := atom() } + </code> + <p>If the <c>system_logger</c> process dies, + this flag will be reset to <c>logger</c>.</p> + <p>The default is the process named <c>logger</c>.</p> + <p>Returns the old value of the flag.</p> + <note><p>This function is designed to be used by the + KERNEL <seealso marker="kernel:logger"><c>logger</c></seealso>. + Be careful if you change it to something else as + log messages may be lost. If you want to intercept + emulator log messages, do it by adding a specialized handler + to the KERNEL logger.</p></note> + </desc> + </func> + + <func> + <name name="system_flag" arity="2" clause_i="15" since=""/> <fsummary>Set system flag trace_control_word.</fsummary> <desc> <p>Sets the value of the node trace control word to @@ -7551,8 +7703,8 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="15" - anchor="system_flag_time_offset"/> + <name name="system_flag" arity="2" clause_i="16" + anchor="system_flag_time_offset" since="OTP 18.0"/> <fsummary>Finalize the time offset.</fsummary> <desc> <p> @@ -7581,7 +7733,7 @@ ok </func> <func> - <name name="system_info" arity="1" clause_i="75"/> + <name name="system_info" arity="1" clause_i="76" since=""/> <fsummary>System info overview.</fsummary> <desc> <p>Returns information about the current system. @@ -7629,6 +7781,7 @@ ok <p> <seealso marker="#system_info_atom_count"><c>atom_count</c></seealso>, <seealso marker="#system_info_atom_limit"><c>atom_limit</c></seealso>, + <seealso marker="#system_info_ets_count"><c>ets_count</c></seealso>, <seealso marker="#system_info_ets_limit"><c>ets_limit</c></seealso>, <seealso marker="#system_info_port_count"><c>port_count</c></seealso>, <seealso marker="#system_info_port_limit"><c>port_limit</c></seealso>, @@ -7700,8 +7853,9 @@ ok <seealso marker="#system_info_nif_version"><c>nif_version</c></seealso>, <seealso marker="#system_info_otp_release"><c>otp_release</c></seealso>, <seealso marker="#system_info_port_parallelism"><c>port_parallelism</c></seealso>, - <seealso marker="#system_info_system_version"><c>system_version</c></seealso>, <seealso marker="#system_info_system_architecture"><c>system_architecture</c></seealso>, + <seealso marker="#system_info_system_logger"><c>system_logger</c></seealso>, + <seealso marker="#system_info_system_version"><c>system_version</c></seealso>, <seealso marker="#system_info_trace_control_word"><c>trace_control_word</c></seealso>, <seealso marker="#system_info_version"><c>version</c></seealso>, <seealso marker="#system_info_wordsize"><c>wordsize</c></seealso> @@ -7713,12 +7867,12 @@ ok <func> <name name="system_info" arity="1" clause_i="1" - anchor="system_info_allocator"/> <!-- allocated_areas --> - <name name="system_info" arity="1" clause_i="2"/> <!-- allocator --> - <name name="system_info" arity="1" clause_i="3"/> <!-- {allocator, _} --> - <name name="system_info" arity="1" clause_i="4"/> <!-- alloc_util_allocators --> - <name name="system_info" arity="1" clause_i="5"/> <!-- {allocator_sizes, _} --> - <name name="system_info" arity="1" clause_i="27"/> <!-- elib_malloc --> + anchor="system_info_allocator" since=""/> <!-- allocated_areas --> + <name name="system_info" arity="1" clause_i="2" since=""/> <!-- allocator --> + <name name="system_info" arity="1" clause_i="3" since=""/> <!-- {allocator, _} --> + <name name="system_info" arity="1" clause_i="4" since=""/> <!-- alloc_util_allocators --> + <name name="system_info" arity="1" clause_i="5" since=""/> <!-- {allocator_sizes, _} --> + <name name="system_info" arity="1" clause_i="27" since=""/> <!-- elib_malloc --> <fsummary>Information about the system allocators.</fsummary> <type variable="Allocator" name_i="2"/> <type variable="Version" name_i="2"/> @@ -7870,10 +8024,10 @@ ok <func> <name name="system_info" arity="1" clause_i="12" - anchor="system_info_cpu_topology"/> <!-- cpu_topology --> - <name name="system_info" arity="1" clause_i="13"/> <!-- {cpu_topology, _} --> - <name name="system_info" arity="1" clause_i="37"/> <!-- logical_processors --> - <name name="system_info" arity="1" clause_i="72"/> <!-- update_cpu_info --> + anchor="system_info_cpu_topology" since=""/> <!-- cpu_topology --> + <name name="system_info" arity="1" clause_i="13" since=""/> <!-- {cpu_topology, _} --> + <name name="system_info" arity="1" clause_i="38" since=""/> <!-- logical_processors --> + <name name="system_info" arity="1" clause_i="74" since="OTP R14B"/> <!-- update_cpu_info --> <fsummary>Information about the CPU topology of the system.</fsummary> <type name="cpu_topology"/> <type name="level_entry"/> @@ -8024,16 +8178,16 @@ ok </func> <func> - <name name="system_info" arity="1" clause_i="30" - anchor="system_info_process"/> <!-- fullsweep_after --> - <name name="system_info" arity="1" clause_i="31"/> <!-- garbage_collection --> - <name name="system_info" arity="1" clause_i="32"/> <!-- heap_sizes --> - <name name="system_info" arity="1" clause_i="33"/> <!-- heap_type --> - <name name="system_info" arity="1" clause_i="39"/> <!-- max_heap_size --> - <name name="system_info" arity="1" clause_i="40"/> <!-- message_queue_data --> - <name name="system_info" arity="1" clause_i="41"/> <!-- min_heap_size --> - <name name="system_info" arity="1" clause_i="42"/> <!-- min_bin_vheap_size --> - <name name="system_info" arity="1" clause_i="56"/> <!-- procs --> + <name name="system_info" arity="1" clause_i="31" + anchor="system_info_process" since=""/> <!-- fullsweep_after --> + <name name="system_info" arity="1" clause_i="32" since=""/> <!-- garbage_collection --> + <name name="system_info" arity="1" clause_i="33" since=""/> <!-- heap_sizes --> + <name name="system_info" arity="1" clause_i="34" since=""/> <!-- heap_type --> + <name name="system_info" arity="1" clause_i="40" since="OTP 19.0"/> <!-- max_heap_size --> + <name name="system_info" arity="1" clause_i="41" since="OTP 19.0"/> <!-- message_queue_data --> + <name name="system_info" arity="1" clause_i="42" since="OTP R13B04"/> <!-- min_heap_size --> + <name name="system_info" arity="1" clause_i="43" since="OTP R13B04"/> <!-- min_bin_vheap_size --> + <name name="system_info" arity="1" clause_i="57" since=""/> <!-- procs --> <fsummary>Information about the default process heap settings.</fsummary> <type name="message_queue_data"/> <type name="max_heap_size"/> @@ -8143,14 +8297,14 @@ ok </func> <func> - <name name="system_info" arity="1" clause_i="6" - anchor="system_info_limits"/> <!-- atom_count --> - <name name="system_info" arity="1" clause_i="7"/> <!-- atom_limit --> - <name name="system_info" arity="1" clause_i="29"/> <!-- ets_limit --> - <name name="system_info" arity="1" clause_i="52"/> <!-- port_count --> - <name name="system_info" arity="1" clause_i="53"/> <!-- port_limit --> - <name name="system_info" arity="1" clause_i="54"/> <!-- process_count --> - <name name="system_info" arity="1" clause_i="55"/> <!-- process_limit --> + <name name="system_info" arity="1" clause_i="6" anchor="system_info_limits" since="OTP 20.0"/> <!-- atom_count --> + <name name="system_info" arity="1" clause_i="7" since="OTP 20.0"/> <!-- atom_limit --> + <name name="system_info" arity="1" clause_i="29" since="OTP 21.1"/> <!-- ets_count --> + <name name="system_info" arity="1" clause_i="30" since="OTP R16B03"/> <!-- ets_limit --> + <name name="system_info" arity="1" clause_i="53" since="OTP R16B"/> <!-- port_count --> + <name name="system_info" arity="1" clause_i="54" since="OTP R16B"/> <!-- port_limit --> + <name name="system_info" arity="1" clause_i="55" since=""/> <!-- process_count --> + <name name="system_info" arity="1" clause_i="56" since=""/> <!-- process_limit --> <fsummary>Information about various system limits.</fsummary> <desc> <marker id="system_info_limits"/> @@ -8173,7 +8327,7 @@ ok <c>erl(1)</c>. </p> </item> - <tag><marker id="system_info_ets_count"/> + <tag><marker id="system_info_ets_count"/> <c>ets_count</c></tag> <item> <p>Returns the number of ETS tables currently existing at the @@ -8224,14 +8378,14 @@ ok <func> <name name="system_info" arity="1" clause_i="26" - anchor="system_info_time"/> <!-- end_time --> - <name name="system_info" arity="1" clause_i="49"/> <!-- os_monotonic_time_source --> - <name name="system_info" arity="1" clause_i="50"/> <!-- os_system_time_source --> - <name name="system_info" arity="1" clause_i="62"/> <!-- start_time --> - <name name="system_info" arity="1" clause_i="67"/> <!-- time_correction --> - <name name="system_info" arity="1" clause_i="68"/> <!-- time_offset --> - <name name="system_info" arity="1" clause_i="69"/> <!-- time_warp_mode --> - <name name="system_info" arity="1" clause_i="70"/> <!-- tolerant_timeofday --> + anchor="system_info_time" since="OTP 18.0"/> <!-- end_time --> + <name name="system_info" arity="1" clause_i="50" since="OTP 18.0"/> <!-- os_monotonic_time_source --> + <name name="system_info" arity="1" clause_i="51" since="OTP 18.0"/> <!-- os_system_time_source --> + <name name="system_info" arity="1" clause_i="63" since="OTP 18.0"/> <!-- start_time --> + <name name="system_info" arity="1" clause_i="69" since="OTP 18.0"/> <!-- time_correction --> + <name name="system_info" arity="1" clause_i="70" since="OTP 18.0"/> <!-- time_offset --> + <name name="system_info" arity="1" clause_i="71" since="OTP 18.0"/> <!-- time_warp_mode --> + <name name="system_info" arity="1" clause_i="72" since="OTP 17.1"/> <!-- tolerant_timeofday --> <fsummary>Information about system time.</fsummary> <desc> <marker id="system_info_time_tags"/> @@ -8321,7 +8475,7 @@ ok system time</seealso> that is used by the runtime system.</p> <p>The list contains two-tuples with <c>Key</c>s as first element, and <c>Value</c>s as second element. The - order if these tuples is undefined. The following + order of these tuples is undefined. The following tuples can be part of the list, but more tuples can be introduced in the future:</p> <taglist> @@ -8452,19 +8606,19 @@ ok <func> <name name="system_info" arity="1" clause_i="17" - anchor="system_info_scheduler"/> <!-- dirty_cpu_schedulers --> - <name name="system_info" arity="1" clause_i="18"/> <!-- dirty_cpu_schedulers_online --> - <name name="system_info" arity="1" clause_i="19"/> <!-- dirty_io_schedulers --> - <name name="system_info" arity="1" clause_i="44"/> <!-- multi_scheduling --> - <name name="system_info" arity="1" clause_i="45"/> <!-- multi_scheduling_blockers --> - <name name="system_info" arity="1" clause_i="47"/> <!-- normal_multi_scheduling_blockers --> - <name name="system_info" arity="1" clause_i="57"/> <!-- scheduler_bind_type --> - <name name="system_info" arity="1" clause_i="58"/> <!-- scheduler_bindings --> - <name name="system_info" arity="1" clause_i="59"/> <!-- scheduler_id --> - <name name="system_info" arity="1" clause_i="60"/> <!-- schedulers --> - <name name="system_info" arity="1" clause_i="61"/> <!-- smp_support --> - <name name="system_info" arity="1" clause_i="65"/> <!-- threads --> - <name name="system_info" arity="1" clause_i="66"/> <!-- thread_pool_size --> + anchor="system_info_scheduler" since="OTP 17.0"/> <!-- dirty_cpu_schedulers --> + <name name="system_info" arity="1" clause_i="18" since="OTP 17.0"/> <!-- dirty_cpu_schedulers_online --> + <name name="system_info" arity="1" clause_i="19" since="OTP 17.0"/> <!-- dirty_io_schedulers --> + <name name="system_info" arity="1" clause_i="45" since=""/> <!-- multi_scheduling --> + <name name="system_info" arity="1" clause_i="46" since=""/> <!-- multi_scheduling_blockers --> + <name name="system_info" arity="1" clause_i="49" since="OTP 19.0"/> <!-- normal_multi_scheduling_blockers --> + <name name="system_info" arity="1" clause_i="58" since=""/> <!-- scheduler_bind_type --> + <name name="system_info" arity="1" clause_i="59" since=""/> <!-- scheduler_bindings --> + <name name="system_info" arity="1" clause_i="60" since=""/> <!-- scheduler_id --> + <name name="system_info" arity="1" clause_i="61" since=""/> <!-- schedulers --> + <name name="system_info" arity="1" clause_i="62" since=""/> <!-- smp_support --> + <name name="system_info" arity="1" clause_i="67" since=""/> <!-- threads --> + <name name="system_info" arity="1" clause_i="68" since=""/> <!-- thread_pool_size --> <fsummary>Information about system schedulers.</fsummary> <desc> <marker id="system_info_scheduler_tags"/> @@ -8752,11 +8906,11 @@ ok <func> <name name="system_info" arity="1" clause_i="14" - anchor="system_info_dist"/> <!-- creation --> - <name name="system_info" arity="1" clause_i="16"/> <!-- delayed_node_table_gc --> - <name name="system_info" arity="1" clause_i="20"/> <!-- dist --> - <name name="system_info" arity="1" clause_i="21"/> <!-- dist_buf_busy_limit --> - <name name="system_info" arity="1" clause_i="22"/> <!-- dist_ctrl --> + anchor="system_info_dist" since=""/> <!-- creation --> + <name name="system_info" arity="1" clause_i="16" since="OTP 18.0"/> <!-- delayed_node_table_gc --> + <name name="system_info" arity="1" clause_i="20" since=""/> <!-- dist --> + <name name="system_info" arity="1" clause_i="21" since="OTP R14B01"/> <!-- dist_buf_busy_limit --> + <name name="system_info" arity="1" clause_i="22" since=""/> <!-- dist_ctrl --> <fsummary>Information about erlang distribution.</fsummary> <desc> <marker id="system_info_dist_tags"/> @@ -8830,14 +8984,14 @@ ok <!-- <name name="system_info" arity="1" clause_i="6"/> atom_count --> <!-- <name name="system_info" arity="1" clause_i="7"/> atom_limit --> <name name="system_info" arity="1" clause_i="8" - anchor="system_info_misc"/> <!-- build_type --> - <name name="system_info" arity="1" clause_i="9"/> <!-- c_compiler_used --> - <name name="system_info" arity="1" clause_i="10"/> <!-- check_io --> - <name name="system_info" arity="1" clause_i="11"/> <!-- compat_rel --> + anchor="system_info_misc" since="OTP R14B"/> <!-- build_type --> + <name name="system_info" arity="1" clause_i="9" since=""/> <!-- c_compiler_used --> + <name name="system_info" arity="1" clause_i="10" since=""/> <!-- check_io --> + <name name="system_info" arity="1" clause_i="11" since=""/> <!-- compat_rel --> <!-- <name name="system_info" arity="1" clause_i="12"/> cpu_topology --> <!-- <name name="system_info" arity="1" clause_i="13"/> {cpu_topology, _} --> <!-- <name name="system_info" arity="1" clause_i="14"/> creation --> - <name name="system_info" arity="1" clause_i="15"/> <!-- debug_compiled --> + <name name="system_info" arity="1" clause_i="15" since=""/> <!-- debug_compiled --> <!-- <name name="system_info" arity="1" clause_i="16"/> delayed_node_table_gc --> <!-- <name name="system_info" arity="1" clause_i="17"/> dirty_cpu_schedulers --> <!-- <name name="system_info" arity="1" clause_i="18"/> dirty_cpu_schedulers_online --> @@ -8845,59 +8999,61 @@ ok <!-- <name name="system_info" arity="1" clause_i="20"/> dist --> <!-- <name name="system_info" arity="1" clause_i="21"/> dist_buf_busy_limit --> <!-- <name name="system_info" arity="1" clause_i="22"/> dist_ctrl --> - <name name="system_info" arity="1" clause_i="23"/> <!-- driver_version --> - <name name="system_info" arity="1" clause_i="24"/> <!-- dynamic_trace --> - <name name="system_info" arity="1" clause_i="25"/> <!-- dynamic_trace_probes --> + <name name="system_info" arity="1" clause_i="23" since=""/> <!-- driver_version --> + <name name="system_info" arity="1" clause_i="24" since="OTP R15B01"/> <!-- dynamic_trace --> + <name name="system_info" arity="1" clause_i="25" since="OTP R15B01"/> <!-- dynamic_trace_probes --> <!-- <name name="system_info" arity="1" clause_i="26"/> end_time --> <!-- <name name="system_info" arity="1" clause_i="27"/> elib_malloc --> <!-- <name name="system_info" arity="1" clause_i="28"/> eager_check_io, removed --> - <!-- <name name="system_info" arity="1" clause_i="29"/> ets_limit --> - <!-- <name name="system_info" arity="1" clause_i="30"/> fullsweep_after --> - <!-- <name name="system_info" arity="1" clause_i="31"/> garbage_collection --> - <!-- <name name="system_info" arity="1" clause_i="32"/> heap_sizes --> - <!-- <name name="system_info" arity="1" clause_i="33"/> heap_type --> - <name name="system_info" arity="1" clause_i="34"/> <!-- info --> - <name name="system_info" arity="1" clause_i="35"/> <!-- kernel_poll --> - <name name="system_info" arity="1" clause_i="36"/> <!-- loaded --> - <!-- <name name="system_info" arity="1" clause_i="37"/> logical_processors --> - <name name="system_info" arity="1" clause_i="38"/> <!-- machine --> - <!-- <name name="system_info" arity="1" clause_i="39"/> max_heap_size --> - <!-- <name name="system_info" arity="1" clause_i="40"/> message_queue_data --> - <!-- <name name="system_info" arity="1" clause_i="41"/> min_heap_size --> - <!-- <name name="system_info" arity="1" clause_i="42"/> min_bin_vheap_size --> - <name name="system_info" arity="1" clause_i="43"/> <!-- modified_timing_level --> - <!-- <name name="system_info" arity="1" clause_i="44"/> multi_scheduling --> - <!-- <name name="system_info" arity="1" clause_i="45"/> multi_scheduling_blockers --> - <name name="system_info" arity="1" clause_i="46"/> <!-- nif_version --> - <!-- n<name name="system_info" arity="1" clause_i="47"/> ormal_multi_scheduling_blockers --> - <name name="system_info" arity="1" clause_i="48"/> <!-- otp_release --> - <!-- <name name="system_info" arity="1" clause_i="49"/> os_monotonic_time_source --> - <!-- <name name="system_info" arity="1" clause_i="50"/> os_system_time_source --> - <name name="system_info" arity="1" clause_i="51"/> <!-- port_parallelism --> - <!-- <name name="system_info" arity="1" clause_i="52"/> port_count --> - <!-- <name name="system_info" arity="1" clause_i="53"/> port_limit --> - <!-- <name name="system_info" arity="1" clause_i="54"/> process_count --> - <!-- <name name="system_info" arity="1" clause_i="55"/> process_limit --> - <!-- <name name="system_info" arity="1" clause_i="56"/> procs --> - <!-- <name name="system_info" arity="1" clause_i="57"/> scheduler_bind_type --> - <!-- <name name="system_info" arity="1" clause_i="58"/> scheduler_bindings --> - <!-- <name name="system_info" arity="1" clause_i="59"/> scheduler_id --> - <!-- <name name="system_info" arity="1" clause_i="60"/> schedulers --> - <!-- <name name="system_info" arity="1" clause_i="61"/> smp_support --> - <!-- <name name="system_info" arity="1" clause_i="62"/> start_time --> - <name name="system_info" arity="1" clause_i="63"/> <!-- system_version --> - <name name="system_info" arity="1" clause_i="64"/> <!-- system_architecture --> - <!-- <name name="system_info" arity="1" clause_i="65"/> threads --> - <!-- <name name="system_info" arity="1" clause_i="66"/> thread_pool_size --> - <!-- <name name="system_info" arity="1" clause_i="67"/> time_correction --> - <!-- <name name="system_info" arity="1" clause_i="68"/> time_offset --> - <!-- <name name="system_info" arity="1" clause_i="69"/> time_warp_mode --> - <!-- <name name="system_info" arity="1" clause_i="70"/> tolerant_timeofday --> - <name name="system_info" arity="1" clause_i="71"/> <!-- trace_control_word --> - <!-- <name name="system_info" arity="1" clause_i="72"/> update_cpu_info --> - <name name="system_info" arity="1" clause_i="73"/> <!-- version --> - <name name="system_info" arity="1" clause_i="74"/> <!-- wordsize --> - <!-- <name name="system_info" arity="1" clause_i="75"/> overview --> + <!-- <name name="system_info" arity="1" clause_i="29"/> ets_count --> + <!-- <name name="system_info" arity="1" clause_i="30"/> ets_limit --> + <!-- <name name="system_info" arity="1" clause_i="31"/> fullsweep_after --> + <!-- <name name="system_info" arity="1" clause_i="32"/> garbage_collection --> + <!-- <name name="system_info" arity="1" clause_i="33"/> heap_sizes --> + <!-- <name name="system_info" arity="1" clause_i="34"/> heap_type --> + <name name="system_info" arity="1" clause_i="35" since=""/> <!-- info --> + <name name="system_info" arity="1" clause_i="36" since=""/> <!-- kernel_poll --> + <name name="system_info" arity="1" clause_i="37" since=""/> <!-- loaded --> + <!-- <name name="system_info" arity="1" clause_i="38"/> logical_processors --> + <name name="system_info" arity="1" clause_i="39" since=""/> <!-- machine --> + <!-- <name name="system_info" arity="1" clause_i="40"/> max_heap_size --> + <!-- <name name="system_info" arity="1" clause_i="41"/> message_queue_data --> + <!-- <name name="system_info" arity="1" clause_i="42"/> min_heap_size --> + <!-- <name name="system_info" arity="1" clause_i="43"/> min_bin_vheap_size --> + <name name="system_info" arity="1" clause_i="44" since=""/> <!-- modified_timing_level --> + <!-- <name name="system_info" arity="1" clause_i="45"/> multi_scheduling --> + <!-- <name name="system_info" arity="1" clause_i="46"/> multi_scheduling_blockers --> + <name name="system_info" arity="1" clause_i="47" since="OTP 17.4"/> <!-- nif_version --> + <!-- n<name name="system_info" arity="1" clause_i="48"/> ormal_multi_scheduling_blockers --> + <name name="system_info" arity="1" clause_i="49" since=""/> <!-- otp_release --> + <!-- <name name="system_info" arity="1" clause_i="50"/> os_monotonic_time_source --> + <!-- <name name="system_info" arity="1" clause_i="51"/> os_system_time_source --> + <name name="system_info" arity="1" clause_i="52" since="OTP R16B"/> <!-- port_parallelism --> + <!-- <name name="system_info" arity="1" clause_i="53"/> port_count --> + <!-- <name name="system_info" arity="1" clause_i="54"/> port_limit --> + <!-- <name name="system_info" arity="1" clause_i="55"/> process_count --> + <!-- <name name="system_info" arity="1" clause_i="56"/> process_limit --> + <!-- <name name="system_info" arity="1" clause_i="57"/> procs --> + <!-- <name name="system_info" arity="1" clause_i="58"/> scheduler_bind_type --> + <!-- <name name="system_info" arity="1" clause_i="59"/> scheduler_bindings --> + <!-- <name name="system_info" arity="1" clause_i="60"/> scheduler_id --> + <!-- <name name="system_info" arity="1" clause_i="61"/> schedulers --> + <!-- <name name="system_info" arity="1" clause_i="62"/> smp_support --> + <!-- <name name="system_info" arity="1" clause_i="63"/> start_time --> + <name name="system_info" arity="1" clause_i="64" since=""/> <!-- system_architecture --> + <name name="system_info" arity="1" clause_i="65" since="OTP 21.3"/> <!-- system_logger --> + <name name="system_info" arity="1" clause_i="66" since=""/> <!-- system_version --> + <!-- <name name="system_info" arity="1" clause_i="67"/> threads --> + <!-- <name name="system_info" arity="1" clause_i="68"/> thread_pool_size --> + <!-- <name name="system_info" arity="1" clause_i="69"/> time_correction --> + <!-- <name name="system_info" arity="1" clause_i="70"/> time_offset --> + <!-- <name name="system_info" arity="1" clause_i="71"/> time_warp_mode --> + <!-- <name name="system_info" arity="1" clause_i="72"/> tolerant_timeofday --> + <name name="system_info" arity="1" clause_i="73" since=""/> <!-- trace_control_word --> + <!-- <name name="system_info" arity="1" clause_i="74"/> update_cpu_info --> + <name name="system_info" arity="1" clause_i="75" since=""/> <!-- version --> + <name name="system_info" arity="1" clause_i="76" since=""/> <!-- wordsize --> + <!-- <name name="system_info" arity="1" clause_i="77"/> overview --> <fsummary>Information about the system.</fsummary> <desc> <marker id="system_info_misc_tags"/> @@ -9053,18 +9209,24 @@ ok <seealso marker="erl#+spp"><c>+spp</c></seealso> in <c>erl(1)</c>.</p> </item> - <tag><marker id="system_info_system_version"/> - <c>system_version</c></tag> - <item> - <p>Returns a string containing version number and - some important properties, such as the number of schedulers.</p> - </item> <tag><marker id="system_info_system_architecture"/> <c>system_architecture</c></tag> <item> <p>Returns a string containing the processor and OS architecture the emulator is built for.</p> </item> + <tag><marker id="system_info_system_logger"/> + <c>system_logger</c></tag> + <item> + <p>Returns the current <c>system_logger</c> as set by + <seealso marker="#system_flag/2"><c>erlang:system_flag(system_logger, _)</c></seealso>.</p> + </item> + <tag><marker id="system_info_system_version"/> + <c>system_version</c></tag> + <item> + <p>Returns a string containing version number and + some important properties, such as the number of schedulers.</p> + </item> <tag><marker id="system_info_trace_control_word"/> <c>trace_control_word</c></tag> <item> @@ -9106,7 +9268,7 @@ ok </func> <func> - <name name="system_monitor" arity="0"/> + <name name="system_monitor" arity="0" since=""/> <fsummary>Current system performance monitoring settings.</fsummary> <type name="system_monitor_option"/> <desc> @@ -9120,7 +9282,7 @@ ok </func> <func> - <name name="system_monitor" arity="1"/> + <name name="system_monitor" arity="1" since=""/> <fsummary>Set or clear system performance monitoring options.</fsummary> <type name="system_monitor_option"/> <desc> @@ -9138,7 +9300,7 @@ ok </func> <func> - <name name="system_monitor" arity="2"/> + <name name="system_monitor" arity="2" since=""/> <fsummary>Set system performance monitoring options.</fsummary> <type name="system_monitor_option"/> <desc> @@ -9251,6 +9413,18 @@ ok <p>Returns the previous system monitor settings just like <seealso marker="#system_monitor/0"> <c>erlang:system_monitor/0</c></seealso>.</p> + <p>The arguments to <c>system_monitor/2</c> specifies how all + system monitoring on the node should be done, not how it should be + changed. This means only one process at a time + (<c><anno>MonitorPid</anno></c>) can be the receiver of system monitor + messages. Also, the way to clear a specific monitor option + is to not include it in the list <c><anno>Options</anno></c>. All + system monitoring will, however, be cleared if the process identified by + <c><anno>MonitorPid</anno></c> terminates.</p> + <p>There are no special option values (like zero) to clear an option. + Some of the options have a unspecified minimum value. Lower values + will be adjusted to the minimum value. For example, it is currently not + possible to monitor all garbage collections with <c>{long_gc, 0}</c>.</p> <note> <p>If a monitoring process gets so large that it itself starts to cause system monitor messages when garbage @@ -9270,7 +9444,7 @@ ok </func> <func> - <name name="system_profile" arity="0"/> + <name name="system_profile" arity="0" since=""/> <fsummary>Current system profiling settings.</fsummary> <type name="system_profile_option"/> <desc> @@ -9285,7 +9459,7 @@ ok </func> <func> - <name name="system_profile" arity="2"/> + <name name="system_profile" arity="2" since=""/> <fsummary>Current system profiling settings.</fsummary> <type name="system_profile_option"/> <desc> @@ -9359,7 +9533,7 @@ ok </func> <func> - <name name="system_time" arity="0"/> + <name name="system_time" arity="0" since="OTP 18.0"/> <fsummary>Current Erlang system time.</fsummary> <desc> <p>Returns current @@ -9381,7 +9555,7 @@ ok </func> <func> - <name name="system_time" arity="1"/> + <name name="system_time" arity="1" since="OTP 18.0"/> <fsummary>Current Erlang system time.</fsummary> <desc> <p>Returns current @@ -9403,7 +9577,7 @@ ok </func> <func> - <name name="term_to_binary" arity="1"/> + <name name="term_to_binary" arity="1" since=""/> <fsummary>Encode a term to an Erlang external term format binary. </fsummary> <desc> @@ -9431,7 +9605,7 @@ hello </func> <func> - <name name="term_to_binary" arity="2"/> + <name name="term_to_binary" arity="2" since=""/> <fsummary>Encode a term to en Erlang external term format binary. </fsummary> <desc> @@ -9496,7 +9670,7 @@ hello </func> <func> - <name name="throw" arity="1"/> + <name name="throw" arity="1" since=""/> <fsummary>Throw an exception.</fsummary> <desc> <p>A non-local return from a function. If evaluated within a @@ -9510,7 +9684,7 @@ hello </func> <func> - <name name="time" arity="0"/> + <name name="time" arity="0" since=""/> <fsummary>Current time.</fsummary> <desc> <p>Returns the current time as <c>{Hour, Minute, Second}</c>.</p> @@ -9523,7 +9697,7 @@ hello </func> <func> - <name name="time_offset" arity="0"/> + <name name="time_offset" arity="0" since="OTP 18.0"/> <fsummary>Current time offset.</fsummary> <desc> <p>Returns the current time offset between @@ -9555,7 +9729,7 @@ hello </func> <func> - <name name="time_offset" arity="1"/> + <name name="time_offset" arity="1" since="OTP 18.0"/> <fsummary>Current time offset.</fsummary> <desc> <p>Returns the current time offset between @@ -9574,7 +9748,7 @@ hello </func> <func> - <name name="timestamp" arity="0"/> + <name name="timestamp" arity="0" since="OTP 18.0"/> <fsummary>Current Erlang System time.</fsummary> <type name="timestamp"/> <desc> @@ -9613,7 +9787,7 @@ timestamp() -> </func> <func> - <name name="tl" arity="1"/> + <name name="tl" arity="1" since=""/> <fsummary>Tail of a list.</fsummary> <desc> <p>Returns the tail of <c><anno>List</anno></c>, that is, @@ -9628,7 +9802,7 @@ timestamp() -> </func> <func> - <name name="trace" arity="3"/> + <name name="trace" arity="3" since=""/> <fsummary>Set trace flags for a process or processes.</fsummary> <type name="trace_flag"/> <desc> @@ -9955,6 +10129,11 @@ timestamp() -> time stamp flags are remembered, so if two are passed and the one with highest precedence later is disabled, the other one becomes active.</p> + <p>If a match specification (applicable only for <c>call</c>, <c>send</c> + and <c>'receive'</c> tracing) contains a <c>{message}</c> action + function with a non-boolean value, that value is added as an extra + element to the message tuple either in the last position or before + the timestamp (if it is present).</p> <p>Trace messages:</p> <marker id="trace_3_trace_messages"></marker> <taglist> @@ -10284,7 +10463,7 @@ timestamp() -> </func> <func> - <name name="trace_delivered" arity="1"/> + <name name="trace_delivered" arity="1" since=""/> <fsummary>Notification when trace has been delivered.</fsummary> <desc> <p>The delivery of trace messages (generated by @@ -10339,7 +10518,7 @@ timestamp() -> </func> <func> - <name name="trace_info" arity="2"/> + <name name="trace_info" arity="2" since=""/> <fsummary>Trace information about a process or function.</fsummary> <type name="trace_info_return"/> <type name="trace_info_item_result"/> @@ -10475,7 +10654,7 @@ timestamp() -> </func> <func> - <name name="trace_pattern" arity="2" clause_i="1"/> + <name name="trace_pattern" arity="2" clause_i="1" since=""/> <fsummary>Set trace patterns for call, send, or 'receive' tracing. </fsummary> <type name="trace_pattern_mfa"/> @@ -10493,7 +10672,7 @@ timestamp() -> </func> <func> - <name name="trace_pattern" arity="3" clause_i="1"/> + <name name="trace_pattern" arity="3" clause_i="1" since="OTP 19.0"/> <fsummary>Set trace pattern for message sending.</fsummary> <type name="trace_match_spec"/> <type name="match_variable"/> @@ -10564,7 +10743,7 @@ timestamp() -> </func> <func> - <name name="trace_pattern" arity="3" clause_i="2"/> + <name name="trace_pattern" arity="3" clause_i="2" since="OTP 19.0"/> <fsummary>Set trace pattern for tracing of message receiving.</fsummary> <type name="trace_match_spec"/> <type name="match_variable"/> @@ -10636,7 +10815,7 @@ timestamp() -> </func> <func> - <name name="trace_pattern" arity="3" clause_i="3"/> + <name name="trace_pattern" arity="3" clause_i="3" since=""/> <fsummary>Set trace patterns for tracing of function calls.</fsummary> <type name="trace_pattern_mfa"/> <type name="trace_match_spec"/> @@ -10827,7 +11006,7 @@ timestamp() -> </func> <func> - <name name="trunc" arity="1"/> + <name name="trunc" arity="1" since=""/> <fsummary>Return an integer by truncating a number.</fsummary> <desc> <p>Returns an integer by truncating <c><anno>Number</anno></c>, @@ -10840,7 +11019,7 @@ timestamp() -> </func> <func> - <name name="tuple_size" arity="1"/> + <name name="tuple_size" arity="1" since=""/> <fsummary>Return the size of a tuple.</fsummary> <desc> <p>Returns an integer that is the number of elements in @@ -10853,7 +11032,7 @@ timestamp() -> </func> <func> - <name name="tuple_to_list" arity="1"/> + <name name="tuple_to_list" arity="1" since=""/> <fsummary>Convert a tuple to a list.</fsummary> <desc> <p>Returns a list corresponding to <c><anno>Tuple</anno></c>. @@ -10866,7 +11045,7 @@ timestamp() -> </func> <func> - <name name="unique_integer" arity="0"/> + <name name="unique_integer" arity="0" since="OTP 18.0"/> <fsummary>Get a unique integer value.</fsummary> <desc> <p>Generates and returns an @@ -10879,7 +11058,7 @@ timestamp() -> </func> <func> - <name name="unique_integer" arity="1"/> + <name name="unique_integer" arity="1" since="OTP 18.0"/> <fsummary>Get a unique integer value.</fsummary> <desc> <p>Generates and returns an @@ -10961,7 +11140,7 @@ timestamp() -> </func> <func> - <name name="universaltime" arity="0"/> + <name name="universaltime" arity="0" since=""/> <fsummary>Current date and time according to Universal Time Coordinated (UTC).</fsummary> <desc> @@ -10978,7 +11157,7 @@ timestamp() -> </func> <func> - <name name="universaltime_to_localtime" arity="1"/> + <name name="universaltime_to_localtime" arity="1" since=""/> <fsummary>Convert from Universal Time Coordinated (UTC) to local date and time.</fsummary> <desc> @@ -10997,7 +11176,7 @@ timestamp() -> </func> <func> - <name name="unlink" arity="1"/> + <name name="unlink" arity="1" since=""/> <fsummary>Remove a link to another process or port.</fsummary> <desc> <p>Removes the link, if there is one, between the calling @@ -11043,7 +11222,7 @@ end</code> </func> <func> - <name name="unregister" arity="1"/> + <name name="unregister" arity="1" since=""/> <fsummary>Remove the registered name for a process (or port).</fsummary> <desc> <p>Removes the registered name <c><anno>RegName</anno></c> @@ -11059,7 +11238,7 @@ true</pre> </func> <func> - <name name="whereis" arity="1"/> + <name name="whereis" arity="1" since=""/> <fsummary>Get the pid (or port) with a specified registered name. </fsummary> <desc> @@ -11073,7 +11252,7 @@ true</pre> </func> <func> - <name name="yield" arity="0"/> + <name name="yield" arity="0" since=""/> <fsummary>Let other processes get a chance to execute.</fsummary> <desc> <p>Voluntarily lets other processes (if any) get a chance to diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml index a094217959..962bc9a244 100644 --- a/erts/doc/src/erts_alloc.xml +++ b/erts/doc/src/erts_alloc.xml @@ -487,11 +487,10 @@ utilization value used. Once a carrier is abandoned, no new allocations are made in it. When an allocator instance gets an increased multiblock carrier need, it first tries to fetch an - abandoned carrier from an allocator instance of the same - allocator type. If no abandoned carrier can be fetched, it - creates a new empty carrier. When an abandoned carrier has been - fetched, it will function as an ordinary carrier. This feature has - special requirements on the + abandoned carrier from another allocator instance. If no abandoned + carrier can be fetched, it creates a new empty carrier. When an + abandoned carrier has been fetched, it will function as an ordinary + carrier. This feature has special requirements on the <seealso marker="#M_as">allocation strategy</seealso> used. Only the strategies <c>aoff</c>, <c>aoffcbf</c>, <c>aoffcaobf</c>, <c>ageffcaoff</c>m, <c>ageffcbf</c> and <c>ageffcaobf</c> @@ -584,7 +583,7 @@ carriers are decided in section <seealso marker="#mseg_mbc_sizes"> The alloc_util Framework</seealso>. On - 32-bit Unix style OS this limit cannot be set > 128 MB.</p> + 32-bit Unix style OS this limit cannot be set > 64 MB.</p> </item> <tag><marker id="M_mbcgs"/><c><![CDATA[+M<S>mbcgs <ratio>]]></c></tag> <item> diff --git a/erts/doc/src/escript.xml b/erts/doc/src/escript.xml index 9b0d42185e..be1664b39f 100644 --- a/erts/doc/src/escript.xml +++ b/erts/doc/src/escript.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>2007</year><year>2017</year> + <year>2007</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -155,9 +155,12 @@ io:setopts([{encoding, unicode}])</code> for example:</p> <pre> halt(1).</pre> - <p>To retrieve the pathname of the script, call - <seealso marker="#script_name_0"> - <c>escript:script_name()</c></seealso> from your script + <p> + To retrieve the pathname of the script, call + <seealso marker="#script_name-0"> + <c>escript:script_name()</c> + </seealso> + from your script (the pathname is usually, but not always, absolute).</p> <p>If the file contains source code (as in the example above), it is processed by the @@ -229,6 +232,7 @@ $ <input>escript factorial.beam 5</input> factorial 5 = 120 $ <input>escript factorial.zip 5</input> factorial 5 = 120</pre> + <marker id="create-2"/> </desc> </func> @@ -259,7 +263,7 @@ factorial 5 = 120</pre> zip:create_option()</seealso>]</v> </type> <desc> - <p><marker id="create_2"></marker> + <p> Creates an escript from a list of sections. The sections can be specified in any order. An escript begins with an optional <c>Header</c> followed by a mandatory <c>Body</c>. If @@ -344,6 +348,7 @@ ok {{2010,3,2},{0,59,22}}, 54,1,0,0,0,0,0}, <<"%% demo.erl\n-module(demo).\n-export([main/1]).\n\n%% Demo\nmain(_Arg"...>>}]}</pre> + <marker id="extract-2"/> </desc> </func> @@ -368,9 +373,11 @@ ok <v>SourceCode = BeamCode = ZipArchive = binary()</v> </type> <desc> - <p><marker id="extract_2"></marker> - Parses an escript and extracts its sections. This is the reverse - of <seealso marker="#create_2"><c>create/2</c></seealso>.</p> + <p> + Parses an escript and extracts its sections. + This is the reverse of + <seealso marker="#create-2"><c>create/2</c></seealso>. + </p> <p>All sections are returned even if they do not exist in the escript. If a particular section happens to have the same value as the default value, the extracted value is set to the @@ -393,6 +400,7 @@ ok {ok,[{{archive,<<80,75,3,4,20,0,0,0,8,0,118,7,98,60,105, 152,61,93,107,0,0,0,118,0,...>>} {emu_args,undefined}]}</pre> + <marker id="script_name-0"/> </desc> </func> @@ -403,7 +411,7 @@ ok <v>File = filename()</v> </type> <desc> - <p><marker id="script_name_0"></marker> + <p> Returns the name of the escript that is executed. If the function is invoked outside the context of an escript, the behavior is undefined.</p> diff --git a/erts/doc/src/init.xml b/erts/doc/src/init.xml index c14f0a558d..c824e37976 100644 --- a/erts/doc/src/init.xml +++ b/erts/doc/src/init.xml @@ -29,7 +29,7 @@ <rev></rev> <file>init.xml</file> </header> - <module>init</module> + <module since="">init</module> <modulesummary>Coordination of system startup.</modulesummary> <description> <p>This module is preloaded and contains the code for @@ -50,7 +50,7 @@ <funcs> <func> - <name name="boot" arity="1"/> + <name name="boot" arity="1" since=""/> <fsummary>Start the Erlang runtime system.</fsummary> <desc> <p>Starts the Erlang runtime system. This function is called @@ -69,7 +69,7 @@ </func> <func> - <name name="get_argument" arity="1"/> + <name name="get_argument" arity="1" since=""/> <fsummary>Get the values associated with a command-line user flag. </fsummary> <desc> @@ -112,7 +112,7 @@ </func> <func> - <name name="get_arguments" arity="0"/> + <name name="get_arguments" arity="0" since=""/> <fsummary>Get all command-line user flags.</fsummary> <desc> <p>Returns all command-line flags and the system-defined flags, see @@ -121,7 +121,7 @@ </func> <func> - <name name="get_plain_arguments" arity="0"/> + <name name="get_plain_arguments" arity="0" since=""/> <fsummary>Get all non-flag command-line arguments.</fsummary> <desc> <p>Returns any plain command-line arguments as a list of strings @@ -130,7 +130,7 @@ </func> <func> - <name name="get_status" arity="0"/> + <name name="get_status" arity="0" since=""/> <fsummary>Get system status information.</fsummary> <type name="internal_status"/> <desc> @@ -146,7 +146,7 @@ </func> <func> - <name name="reboot" arity="0"/> + <name name="reboot" arity="0" since=""/> <fsummary>Take down and restart an Erlang node smoothly.</fsummary> <desc> <p>All applications are taken down smoothly, all code is @@ -162,7 +162,7 @@ </func> <func> - <name name="restart" arity="0"/> + <name name="restart" arity="0" since=""/> <fsummary>Restart the running Erlang node.</fsummary> <desc> <p>The system is restarted <em>inside</em> the running Erlang @@ -178,7 +178,7 @@ </func> <func> - <name name="script_id" arity="0"/> + <name name="script_id" arity="0" since=""/> <fsummary>Get the identity of the used boot script.</fsummary> <desc> <p>Gets the identity of the boot script used to boot the system. @@ -189,7 +189,7 @@ </func> <func> - <name name="stop" arity="0"/> + <name name="stop" arity="0" since=""/> <fsummary>Take down an Erlang node smoothly.</fsummary> <desc> <p>The same as @@ -198,7 +198,7 @@ </func> <func> - <name name="stop" arity="1"/> + <name name="stop" arity="1" since=""/> <fsummary>Take down an Erlang node smoothly.</fsummary> <desc> <p>All applications are taken down smoothly, all code is diff --git a/erts/doc/src/internal.xml b/erts/doc/src/internal.xml new file mode 100644 index 0000000000..88609d492a --- /dev/null +++ b/erts/doc/src/internal.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE part SYSTEM "part.dtd"> + +<internal xmlns:xi="http://www.w3.org/2001/XInclude"> + <header> + <copyright> + <year>2018</year><year>2018</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>ERTS Internal Documentation</title> + <prepared>Lukas Larsson</prepared> + <docno></docno> + <date>2018-07-07</date> + <rev>4.5.2</rev> + <file>internal.xml</file> + </header> + <xi:include href="CarrierMigration.xml"/> + <xi:include href="ThreadProgress.xml"/> + <xi:include href="CodeLoading.xml"/> + <xi:include href="Tracing.xml"/> + <xi:include href="DelayedDealloc.xml"/> + <xi:include href="beam_makeops.xml"/> + <xi:include href="CountingInstructions.xml"/> + <xi:include href="GarbageCollection.xml"/> + <xi:include href="PTables.xml"/> + <xi:include href="PortSignals.xml"/> + <xi:include href="ProcessManagementOptimizations.xml"/> + <xi:include href="SuperCarrier.xml"/> +</internal> diff --git a/erts/doc/src/match_spec.xml b/erts/doc/src/match_spec.xml index 5cd6dc1750..48e502739a 100644 --- a/erts/doc/src/match_spec.xml +++ b/erts/doc/src/match_spec.xml @@ -113,6 +113,7 @@ <c><![CDATA[length]]></c> | <c><![CDATA[map_get]]></c> | <c><![CDATA[map_size]]></c> | <c><![CDATA[node]]></c> | <c><![CDATA[round]]></c> | <c><![CDATA[size]]></c> | + <c><![CDATA[bit_size]]></c> | <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> | <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> | <c><![CDATA['*']]></c> | <c><![CDATA['div']]></c> | @@ -194,6 +195,7 @@ <c><![CDATA[length]]></c> | <c><![CDATA[map_get]]></c> | <c><![CDATA[map_size]]></c> | <c><![CDATA[node]]></c> | <c><![CDATA[round]]></c> | <c><![CDATA[size]]></c> | + <c><![CDATA[bit_size]]></c> | <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> | <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> | <c><![CDATA['*']]></c> | <c><![CDATA['div']]></c> | @@ -269,8 +271,9 @@ other <c>false</c> to return <c><![CDATA[true]]></c>; otherwise <c><![CDATA['xor']]></c> returns false.</p> </item> - <tag><c>abs</c>, <c>element</c>, <c>hd</c>, <c>length</c>, <c>node</c>, - <c>round</c>, <c>size</c>, <c>tl</c>, <c>trunc</c>, <c>'+'</c>, + <tag><c>abs</c>, <c>element</c>, <c>hd</c>, <c>length</c>, + <c>map_get</c>, <c>map_size</c>, <c>node</c>, <c>round</c>, + <c>size</c>, <c>bit_size</c>, <c>tl</c>, <c>trunc</c>, <c>'+'</c>, <c>'-'</c>, <c>'*'</c>, <c>'div'</c>, <c>'rem'</c>, <c>'band'</c>, <c>'bor'</c>, <c>'bxor'</c>, <c>'bnot'</c>, <c>'bsl'</c>, <c>'bsr'</c>, <c>'>'</c>, <c>'>='</c>, <c>'<'</c>, <c>'=<'</c>, diff --git a/erts/doc/src/net.xml b/erts/doc/src/net.xml new file mode 100644 index 0000000000..6fbc37076c --- /dev/null +++ b/erts/doc/src/net.xml @@ -0,0 +1,129 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2018</year><year>2018</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>net</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + <file>net.xml</file> + </header> + <module since="OTP 22.0">net</module> + <modulesummary>Network interface.</modulesummary> + <description> + <p>This module provides an API for the network interface.</p> + <note> + <p>There is currently <em>no</em> support for Windows. </p> + </note> + </description> + + <datatypes> + <datatype> + <name name="address_info"/> + </datatype> + <datatype> + <name name="name_info"/> + </datatype> + <datatype> + <name name="name_info_flags"/> + </datatype> + <datatype> + <name name="name_info_flag"/> + </datatype> + <datatype> + <name name="name_info_flag_ext"/> + </datatype> + <datatype> + <name name="network_interface_name"/> + </datatype> + <datatype> + <name name="network_interface_index"/> + </datatype> + </datatypes> + + <funcs> + <func> + <name name="gethostname" arity="0"/> + <fsummary>Get hostname.</fsummary> + <desc> + <p>Returns the name of the current host.</p> + </desc> + </func> + + <func> + <name name="getnameinfo" arity="1" since="OTP 22.0"/> + <name name="getnameinfo" arity="2" since="OTP 22.0"/> + <fsummary>Address-to-name transaltion.</fsummary> + <desc> + <p>Address-to-name translation in a protocol-independant manner.</p> + <p>This function is the inverse of + <seealso marker="#getaddrinfo/1"><c>getaddrinfo</c></seealso>. + It converts a socket address to a corresponding host and service.</p> + </desc> + </func> + + <func> + <name name="getaddrinfo" arity="1" since="OTP 22.0"/> + <name name="getaddrinfo" arity="2" clause_i="1" since="OTP 22.0"/> + <name name="getaddrinfo" arity="2" clause_i="2" since="OTP 22.0"/> + <name name="getaddrinfo" arity="2" clause_i="3" since="OTP 22.0"/> + <fsummary>Network address and service transation.</fsummary> + <desc> + <p>Network address and service translation.</p> + <p>This function is the inverse of + <seealso marker="#getnameinfo/1"><c>getnameinfo</c></seealso>. + It converts host and service to a corresponding socket address.</p> + <p>One of the <c>Host</c> and <c>Service</c> may be <c>undefined</c> + but <em>not</em> both.</p> + </desc> + </func> + + <func> + <name name="if_name2index" arity="1" since="OTP 22.0"/> + <fsummary>Mappings between network interface names and indexes.</fsummary> + <desc> + <p>Mappings between network interface names and indexes.</p> + </desc> + </func> + + <func> + <name name="if_index2name" arity="1" since="OTP 22.0"/> + <fsummary>Mappings between network interface index and names.</fsummary> + <desc> + <p>Mappings between network interface index and names.</p> + </desc> + </func> + + <func> + <name name="if_names" arity="0" since="OTP 22.0"/> + <fsummary>Get network interface names and indexes.</fsummary> + <desc> + <p>Get network interface names and indexes.</p> + </desc> + </func> + + </funcs> + +</erlref> + diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index ed0946d6ba..cfa952f01c 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -31,6 +31,1746 @@ </header> <p>This document describes the changes made to the ERTS application.</p> +<section><title>Erts 10.4.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a buffer overflow when + <c>binary_to_existing_atom/2</c> and + <c>list_to_existing_atom/2</c> was used with the + <c>latin1</c> encoding.</p> + <p> + Own Id: OTP-15819 Aux Id: ERL-944 </p> + </item> + <item> + <p> + The runtime system disconnected a connection if it + received an <c>exit/2</c> signal where the recipient was + a process on an old incarnation of the current node. That + is, the receiving node had the same node name, but + another "creation" number. The signal will now just be + dropped since the receiving process no longer exists.</p> + <p> + Own Id: OTP-15867 Aux Id: ERIERL-373 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.4.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed <c>process_info(Pid,reductions)</c> to not + categorically increase reduction count of the measured + process <c>Pid</c>. Repeated reduction measure of an idle + process will most often (but not guaranteed) return the + same value, like it behaved before OTP 21.3.8.</p> + <p> + Own Id: OTP-15865 Aux Id: ERL-964 </p> + </item> + <item> + <p>Fixed an incorrect load-time optimization that could + cause a crash when extracting deeply nested tuple + elements.</p> + <p> + Own Id: OTP-15871 Aux Id: ERIERL-374 </p> + </item> + <item> + <p> + Fix bug causing VM crash when pressing P for "proc info" + in Erlang shell break menu. Bug exists since OTP 22.0.</p> + <p> + Own Id: OTP-15873 Aux Id: ERL-965 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.4.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>In nested use of <c>try</c>/<c>catch</c>, rethrowing + an exception using <c>erlang:raise/3</c> with a different + class would not always be able to change the class of the + exception.</p> + <p> + Own Id: OTP-15834 Aux Id: ERIERL-367 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Do not allocate new bitstring/binary when an empty binary + is appended.</p> + <p> + Own Id: OTP-15535 Aux Id: PR-2055 </p> + </item> + <item> + <p> + Document that <c>process_info(_, current_function)</c> + can return <c>{current_function, undefined}</c> in case + of execution of native code.</p> + <p> + Own Id: OTP-15543 Aux Id: PR-2089 </p> + </item> + <item> + <p> + Fixed bug in <c>ets:select</c>, <c>ets:match</c> and + friends which could cause the table to remain fixated (as + if <c>ets:safe_fixtable</c> had been called) after the + call returned. This could happen for <c>protected</c> + tables if another concurrent running process transferred + table ownership to the process during its + ets:select/match call. Ownership can be transferred using + either <c>ets:give_away</c> or the <c>heir</c> table + option.</p> + <p> + Own Id: OTP-15672</p> + </item> + <item> + <p>Fixed a Windows-specific bug in <c>file:list_dir/1</c> + that caused it to misbehave on network shares.</p> + <p> + Own Id: OTP-15693</p> + </item> + <item> + <p> + Fixed bug when calling <c>enif_whereis_*</c> from NIF + resource destructor. Symptoms could be emulator crash or + hanging scheduler threads.</p> + <p> + Own Id: OTP-15694 Aux Id: ERL-863 </p> + </item> + <item> + <p>Fixed a bug in the error case of <c>apply/3</c>, where + the exception would erroneously have an empty argument + list in some cases.</p> + <p> + Own Id: OTP-15698</p> + </item> + <item> + <p>A bug has been fixed in the <c>maps</c> implementation + that could cause a crash or memory usage to grow until + the machine ran out of memory. This could happen when + inserting a new key-value pair with a key <c>K1</c> + containing a binary <c>B1</c> into a map <c>M</c> having + a key <c>K2</c> with a binary <c>B2</c> if the following + conditions were met:</p> <list> <item><c>B1 =/= + B2</c></item> <item><c>size(B1) >= 4294967296</c></item> + <item><c>size(B2) >= 4294967296</c></item> + <item><c>size(M) >= 32</c></item> <item><c>(size(B1) rem + 4294967296) == (size(B2) rem 4294967296)</c></item> + <item>the first <c>(size(B1) rem 4294967296)</c> bytes + are the same both in <c>B1</c> and <c>B2</c></item> + <item>substituting <c>B1</c> in <c>K1</c> with <c>B2</c> + would create a term with the same value as + <c>K2</c></item> </list> <p>The root cause of the problem + is that the <c>maps</c> implementation only hashed the + first <c>(X rem 4294967296)</c> bytes of binaries so that + different binaries could get the same hash value + independently of the hash seed.</p> + <p> + Own Id: OTP-15707</p> + </item> + <item> + <p> + <c>term_to_binary()</c> and distributed sends will now + throw a <c>system_limit</c> exception instead of + producing erroneous results when trying to encode a + binary larger than 4 GB.</p> + <p> + Own Id: OTP-15708</p> + </item> + <item> + <p> + The vxworks configure has been updated to respect the + environment CFLAGS.</p> + <p> + Own Id: OTP-15773</p> + </item> + <item> + <p> + Fix configure to not enable PGO (profile guided + optimizations) when linking of the PGO binary fails. For + instance this happens when there is no gcov lib + installed.</p> + <p> + Own Id: OTP-15788</p> + </item> + <item> + <p> + Fix bug on OpenBSD where sockets using <c>active, + true</c> or <c>active, N</c> could cause the system to + live lock. The bug was introduced in erts-10.2 + (OTP-21.2).</p> + <p> + Own Id: OTP-15791</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Add support for Erlang Distribution protocol to split the + payload of large signals into several fragments. This + allows other processes to communicate uninterrupted + during the transmission of these signals.</p> + <p> + Own Id: OTP-13397</p> + </item> + <item> + <p> + A simple socket API is provided through the socket + module. This is a low level API that does *not* replace + gen_[tcp|udp|sctp]. It is intended to *eventually* + replace the inet driver, but not the high level + gen-modules (gen_tcp, gen_udp and gen_sctp). It also + provides a basic API that facilitates the implementation + of other protocols, that is TCP, UDP and SCTP. </p> + <p> + Known issues are; No support for the Windows OS + (currently).</p> + <p> + Own Id: OTP-14831</p> + </item> + <item> + <p>Added NIF functions <seealso + marker="erl_nif#enif_set_pid_undefined"><c>enif_set_pid_undefined</c></seealso>, + <seealso + marker="erl_nif#enif_is_pid_undefined"><c>enif_is_pid_undefined</c></seealso> + and <seealso + marker="erl_nif#enif_compare_pids"><c>enif_compare_pids</c></seealso>.</p> + <p> + Own Id: OTP-15011 Aux Id: PR-2147 </p> + </item> + <item> + <p>Underutilized memory segments (carriers) can now move + between all allocator instances, rather than just between + instances of the same type, which greatly reduces memory + usage in some scenarios. </p> + <p> + Own Id: OTP-15063</p> + </item> + <item> + <p>The emulator will now mark free blocks in pooled + carriers with <c>madvise(2) + MADV_FREE</c> (or similar), + letting the OS reclaim the associated physical memory if + necessary.</p> + <p> + Own Id: OTP-15075</p> + </item> + <item> + <p> + New <c>ERL_NIF_SELECT_CANCEL</c> feature added to + <c>enif_select</c> in order to cancel (or "deselect") a + read or write event on a previously selected file + descriptor.</p> + <p> + Own Id: OTP-15095</p> + </item> + <item> + <p> + ETS option <c>write_concurrency</c> now also affects and + improves the scalability of <c>ordered_set</c> tables. + The implementation is based on a data structure called + contention adapting search tree, where the lock + granularity adapts to the actual amount of concurrency + exploited by the applications in runtime.</p> + <p> + Own Id: OTP-15128</p> + </item> + <item> + <p> + Build configuration of the <c>crypto</c> application has + been moved from the <c>erts</c> application into the + <c>crypto</c> application.</p> + <p> + Own Id: OTP-15129</p> + </item> + <item> + <p>Anonymous functions that don't capture environment are + now created at load-time instead of in run-time.</p> + <p> + Own Id: OTP-15195 Aux Id: PR-1812 </p> + </item> + <item> + <p> + Optimize updates of maps with identical keys and values. + E.g. in the example below the original Map will be reused + as the return of the update.</p> + <p> + 1> Map = #{ a => b }. #{ a => b } 2> Map#{ a := b }.</p> + <p> + Own Id: OTP-15211 Aux Id: PR-1889 </p> + </item> + <item> + <p> + Optimize <c>binary:match/2</c> and + <c>binary:matches/2</c> to use memchr internally.</p> + <p> + Own Id: OTP-15238 Aux Id: PR-1803 </p> + </item> + <item> + <p> + The runtime system used to terminate when a message + larger than 2 Gb was passed over the distribution. The + send operation will now instead throw a + <c>system_limit</c> exception.</p> + <p> + Own Id: OTP-15261</p> + </item> + <item> + <p> + Change the first module called by erts to be named + erl_init instead of otp_ring0. systools in sasl have been + updated to reflect this change.</p> + <p> + Own Id: OTP-15336 Aux Id: PR-1825 </p> + </item> + <item> + <p> + Minor adjustments made to build system for parallel + configure.</p> + <p> + Own Id: OTP-15340 Aux Id: OTP-14625 </p> + </item> + <item> + <p> + Two new NIF interface functions <c>enif_select_read</c> + and <c>enif_select_write</c>. They are similar to + existing <c>enif_select</c> but allow a custom event + message as an argument.</p> + <p> + Own Id: OTP-15349 Aux Id: PR-2084 </p> + </item> + <item> + <p>The embedded copy of <c>zlib</c> has been updated from + <c>1.2.8</c> to <c>1.2.11</c>.</p> + <p>Note that this copy is only used as a fallback when + the target platform doesn't provide any <c>zlib</c> + development libraries. If your system provides + <c>zlib</c> then it will be used even if it is older than + <c>1.2.11</c>.</p> + <p> + Own Id: OTP-15351 Aux Id: ERL-749 </p> + </item> + <item> + <p> + New NIF function <c>enif_make_monitor_term</c>.</p> + <p> + Own Id: OTP-15362 Aux Id: PR-2127 </p> + </item> + <item> + <p>Appending lists (The ++ operator) will now yield + properly on large inputs.</p> + <p> + Own Id: OTP-15427</p> + </item> + <item> + <p>The <c>length/1</c> BIF used to calculate the length + of the list in one go without yielding, even if the list + was very long. In OTP 22, <c>length/1</c> will yield when + called with long lists.</p> + <p> + Own Id: OTP-15439</p> + </item> + <item> + <p> + Processes sending messages are now punished with a + reduction cost based on message size. That is, a process + sending a large message will yield earlier than before.</p> + <p> + Own Id: OTP-15513 Aux Id: ERL-773 </p> + </item> + <item> + <p>The transitory emulator option <c>+ztma true</c> + (introduced in OTP 21.3) has been removed.</p> + <p> + Own Id: OTP-15581 Aux Id: OTP-15580 </p> + </item> + <item> + <p>In OTP 22, HiPE (the native code compiler) is not + fully functional. The reasons for this are:</p> + <p>There are new BEAM instructions for binary matching + that the HiPE native code compiler does not support.</p> + <p>The new optimizations in the Erlang compiler create + new combination of instructions that HiPE currently does + not handle correctly.</p> + <p>If erlc is invoked with the <c>+native</c> option, and + if any of the new binary matching instructions are used, + the compiler will issue a warning and produce a BEAM file + without native code.</p> + <p> + Own Id: OTP-15596</p> + </item> + <item> + <p> + The termination behaviour of processes has changed to + allow processes to yield while sending link exit/monitor + down signals.</p> + <p> + The erl crash dump has been expanded to now also include + processes that are termeinating but have not yet + terminated.</p> + <p> + Own Id: OTP-15610</p> + </item> + <item> + <p> + The dist messages EXIT, EXIT2 and MONITOR_DOWN have been + updated with new versions that send the reason term as + part of the payload of the message instead of as part of + the control message.</p> + <p> + The old versions are still present and can be used when + communicating with nodes that don't support the new + versions.</p> + <p> + Own Id: OTP-15611</p> + </item> + <item> + <p> + When sending messages, exit, exit2 and monitor down + distributed signals, the process sending will now yield + appropriately.</p> + <p> + This means that a terminating process will yield and + possibly be suspended on busy distribution entries while + they are terminating. This means that any memory held by + such processes will not be released until after all + exit/monitor down signals have been sent.</p> + <p> + Own Id: OTP-15612</p> + </item> + <item> + <p> + All external pids/ports/refs created by + erlang:list_to_pid/port/ref debug functions now compare + equal to any other pid/port/ref with the same number from + that node.</p> + <p> + Before this change they compared differently because the + node creation of the pid/port/ref did not compare equal + to any real pid/port/ref creation.</p> + <p> + This will mostly effect pids/ports/refs typed in the + shell.</p> + <p> + Own Id: OTP-15613</p> + </item> + <item> + <p> + The <c>persistent_term</c> functions <c>put/2</c> and + <c>erase/1</c> are now yielding.</p> + <p> + Own Id: OTP-15615</p> + </item> + <item> + <p> + A new <seealso + marker="erlang#dist_ctrl_set_opt/3"><c>erlang:dist_ctrl_set_opt(DHandle, + get_size, Value)</c></seealso> option has been added. + This option makes it possible to configure the + distribution channel identified by <c>DHandle</c> so that + <seealso + marker="erlang#dist_ctrl_get_data/1"><c>erlang:dist_ctrl_get_data(DHandle)</c></seealso> + also returns the size of the data to pass over the + channel.</p> + <p> + Own Id: OTP-15617</p> + </item> + <item> + <p>Previously, all ETS tables used centralized counter + variables to keep track of the number of items stored and + the amount of memory consumed. These counters can cause + scalability problems (especially on big NUMA systems). + This change adds an implementation of a decentralized + counter and modifies the implementation of ETS so that + ETS tables of type <c>ordered_set</c> with + <c>write_concurrency</c> enabled use the decentralized + counter. Experiments indicate that this change + substantially improves the scalability of ETS + <c>ordered_set</c> tables with <c>write_concurrency</c> + enabled in scenarios with frequent <c>ets:insert/2</c> + and <c>ets:delete/2</c> calls.</p> + <p> + Own Id: OTP-15623 Aux Id: PR-2190 </p> + </item> + <item> + <p>The <c>iolist_size/1</c> function is now yielding + which means that an Erlang/OTP system will be responsive + even if the applications running on the system frequently + call <c>iolist_size/1</c> with large iolists.</p> + <p> + Own Id: OTP-15631</p> + </item> + <item> + <p> + A simple test suite for the net module has been added.</p> + <p> + Own Id: OTP-15635</p> + </item> + <item> + <p>Added the NIF function <c>enif_term_type</c>, which + helps avoid long sequences of <c>enif_is_xyz</c> by + returning the type of the given term. This is especially + helpful for NIFs that serialize terms, such as JSON + encoders, where it can improve both performance and + readability.</p> + <p> + Own Id: OTP-15640</p> + </item> + <item> + <p>The last call optimization is now applied to BIFs. + When calling a BIF in the tail position of a function, + the return address and stack frame will now be discarded + before calling the BIF. As a consequence of this change, + the immediate caller of a tail-called BIF will no longer + be available in stack backtraces.</p> + <p> + Own Id: OTP-15674 Aux Id: PR-2177 </p> + </item> + <item> + <p> + Fix GC bug where distributed messages in a processes + mailbox would cause extra GCs. This can be very expensive + if there many messages in the mailbox.</p> + <p> + Own Id: OTP-15703</p> + </item> + <item> + <p>Internal documentation has now been added to the + <em>Erts</em> and <em>Compiler</em> applications.</p> + <p>The internal documents for <em>Erts</em> describe + miscellaneous interesting implementation details. Those + details can change at any time.</p> + <p>The internal documentation for <em>Compiler</em> + documents the API for the Core Erlang modules. While we + will not change those APIs without good reason, we don't + give the same guarantees about backward compatibility as + for the rest of the APIs in OTP.</p> + <p> + Own Id: OTP-15715</p> + </item> + <item> + <p>The performance of non-bignum integer arithmetic has + been improved.</p> + <p> + Own Id: OTP-15740</p> + </item> + <item> + <p> + The <c>-remsh</c> option to <c>erl</c> now automatically + adds the local systems hostname to the target node if no + nodename is given. e.g.</p> + <p> + <c> erl -name foo -remsh bar </c><br/> <c> erl -sname foo + -remsh bar </c></p> + <p> + Own Id: OTP-15794 Aux Id: PR-2219 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.3.5.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + If you set <c>{linger,{true,0}}</c> on a <c>gen_tcp</c> + listen socket, accept a connection on that socket, and + then close the accepted socket, now the linger zero + setting is transferred to the accepted socket. Before + this correction that information was lost and the close + behaviour on the accepted socket incorrect.</p> + <p> + Own Id: OTP-15370 Aux Id: ERIERL-353 </p> + </item> + <item> + <p> + Fixed <c>process_info(Pid,reductions)</c> to not + categorically increase reduction count of the measured + process <c>Pid</c>. Repeated reduction measure of an idle + process will most often (but not guaranteed) return the + same value, like it behaved before OTP 21.3.8.</p> + <p> + Own Id: OTP-15865 Aux Id: ERL-964 </p> + </item> + <item> + <p> + The runtime system disconnected a connection if it + received an <c>exit/2</c> signal where the recipient was + a process on an old incarnation of the current node. That + is, the receiving node had the same node name, but + another "creation" number. The signal will now just be + dropped since the receiving process no longer exists.</p> + <p> + Own Id: OTP-15867 Aux Id: ERIERL-373 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The possibility to send ancillary data, in particular the + TOS field, has been added to <c>gen_udp:send/4,5</c>.</p> + <p> + Own Id: OTP-15747 Aux Id: ERIERL-294 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.3.5.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>In nested use of <c>try</c>/<c>catch</c>, rethrowing + an exception using <c>erlang:raise/3</c> with a different + class would not always be able to change the class of the + exception.</p> + <p> + Own Id: OTP-15834 Aux Id: ERIERL-367 </p> + </item> + <item> + <p> + Fixed bug in <c>seq_trace:set_token(label,Term)</c> which + could cause VM crash if <c>Term</c> was heap allocated + (not an atom, small integer, local pid or port). Bug + exists since OTP 21.0 when terms other than small + integers were first allowed as labels.</p> + <p> + Own Id: OTP-15849 Aux Id: ERL-700 </p> + </item> + <item> + <p> + Fix <c>seq_trace:print/2</c> not to raise <c>badarg</c> + exception if label is not a small integer. Bug exists + since OTP 21.0.</p> + <p> + Own Id: OTP-15859 Aux Id: ERL-700 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.3.5.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a buffer overflow when + <c>binary_to_existing_atom/2</c> and + <c>list_to_existing_atom/2</c> was used with the + <c>latin1</c> encoding.</p> + <p> + Own Id: OTP-15819 Aux Id: ERL-944 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.3.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed more bugs in <c>process_info(reductions)</c> + causing it to sometimes behave non-monotonic. That is, a + subsequent call toward the same process could return a + lower reduction value.</p> + <p> + Own Id: OTP-15793 Aux Id: ERIERL-337, OTP-15709 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.3.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Add missing documentation of new external tags + <c>NEW_PID</c>, <c>NEW_PORT</c> and + <c>NEWER_REFERENCE</c> introduced in OTP 19.</p> <p>These + new tags are planned to be "activated" in OTP 23 when + distribution capability flag <c>DFLAG_BIG_CREATION</c> + becomes mandatory. Older nodes (>= 19) are able to decode + these new tags and send them back to the new node. Nodes + older than OTP 23 will however never encode their own + local pids, ports and references using the new tags.</p> + <p> + Own Id: OTP-15766</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.3.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix <c>erlang:open_port/2</c> with the <c>fd</c> option + to correctly cleanup the pollset when the port is closed. + Before this fix there would be error printouts sent to + logger when the same fd was reused in a new port.</p> + <p> + Own Id: OTP-15753 Aux Id: ERL-900 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.3.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a bug in <c>seq_trace:reset_trace/0</c> that + could crash the emulator.</p> + <p> + Own Id: OTP-15704</p> + </item> + <item> + <p> + Fixed bug in <c>process_info(reductions)</c> causing it + to sometimes return invalid results.</p> + <p> + Own Id: OTP-15709 Aux Id: ERIERL-337 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>If a suspend/resume signal pair was sent to a process + while it was executing dirty, the receiving process could + later end up in a suspended state indefinitely. This bug + was introduced in ERTS version 10.0 (OTP 21.0).</p> + <p>Suspend/resume signals are sent from <seealso + marker="erts:erlang#suspend_process/1"><c>erlang:suspend_process()</c></seealso>/<seealso + marker="erts:erlang#resume_process/1"><c>erlang:resume_process()</c></seealso>. + The <seealso + marker="runtime_tools:dbg"><c>dbg</c></seealso> trace + tool utilize this functionality and could thus trigger + this bug.</p> + <p> + Own Id: OTP-15688</p> + </item> + <item> + <p> + Fix a possible deadlock when terminating the ERTS caused + by a dirty scheduler not releasing it's run-queue lock + when terminating.</p> + <p> + Own Id: OTP-15690 Aux Id: PR-2172 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>When multiplying a number by itself, a word beyond the + number on the heap could be read (and ignored). This bug + was extremely unlikely to actually cause a real + problem.</p> + <p> + Own Id: OTP-15484</p> + </item> + <item> + <p> + Fix bug where doing <c>seq_trace:reset_trace()</c> while + another process was doing a garbage collection could + cause the run-time system to segfault.</p> + <p> + Own Id: OTP-15490</p> + </item> + <item> + <p> + Fix reading of ancillary data from packet oriented + sockets on old Linux kernel versions. Without this fix, + getting the data would cause the port to enter an + infinite loop.</p> + <p> + Own Id: OTP-15494</p> + </item> + <item> + <p> + Fix bug where crash dumping or doing + <c>erlang:system_info(procs)</c> while another process + was doing a garbage collection could cause the run-time + system to segfault.</p> + <p> + Own Id: OTP-15527</p> + </item> + <item> + <p> + Fix <c>erlang:system_info(kernel_poll)</c> to return + correct value. Before this fix, the call always returned + <c>false</c>.</p> + <p> + Own Id: OTP-15556</p> + </item> + <item> + <p> + Fix bug in <c>enif_make_map_from_arrays</c> that would + produce broken maps when number of keys were 32. Bug + exists since OTP 21.0.</p> + <p> + Own Id: OTP-15567</p> + </item> + <item> + <p> + Fix a bug in <c>binary:encode_unsigned</c> that may cause + a read of uninitialized memory.</p> + <p> + The bug existed since the function was added (OTP + R16B02).</p> + <p> + Own Id: OTP-15583 Aux Id: PR-2118 </p> + </item> + <item> + <p> + Fixed a bug that could cause <c>heart</c> to kill an + exiting node before it had time to flush all buffered + writes. If environment variable + <c>HEART_KILL_SIGNAL=SIGABRT</c> was set a superfluous + core dump could also be generated.</p> + <p> + Own Id: OTP-15599 Aux Id: ERIERL-298 </p> + </item> + <item> + <p> + Fix <c>enif_consume_timeslice</c> to be a no-op on dirty + scheduler and not crash debug compiled emulator.</p> + <p> + Own Id: OTP-15604</p> + </item> + <item> + <p> + Fixed macro redefinition warnings.</p> + <p> + Own Id: OTP-15629</p> + </item> + <item> + <p> + <c>to_erl</c> fixed to not garble terminal input beyond + 7-bit ASCII.</p> + <p> + Own Id: OTP-15650 Aux Id: ERL-854, PR-2161 </p> + </item> + <item> + <p> + Minor fixes for <c>make clean</c>.</p> + <p> + Own Id: OTP-15657</p> + </item> + <item> + <p> + Fixed a bug in all <c>ets:select*</c> and + <c>ets:match*</c> functions that could in some rare cases + lead to very poor performance.</p> + <p> + Own Id: OTP-15660 Aux Id: ERL-869 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Add <c>erlang:system_flag(system_logger, Pid)</c> and + <c>erlang:system_info(system_logger)</c>. This + system_flag can be used to set the process that will + receive the logging messages generated by ERTS.</p> + <p> + Own Id: OTP-15375</p> + </item> + <item> + <p><c>integer_to_list/2</c> and + <c>integer_to_binary/2</c> are now implemented in C, + improving their performance.</p> + <p> + Own Id: OTP-15503 Aux Id: PR-2052 </p> + </item> + <item> + <p> + Improved <c>term_to_binary</c> to do more fair reduction + count and yielding when encoding large byte lists + (strings).</p> + <p> + Own Id: OTP-15514 Aux Id: ERL-774 </p> + </item> + <item> + <p> + Made internal port drivers more robust against + <c>erlang:port_control</c> with invalid arguments and + added documentation warnings about such abuse.</p> + <p> + Own Id: OTP-15555 Aux Id: ERIERL-231 </p> + </item> + <item> + <p> + Fix bug on NetBSD where the <c>exit_status</c> from a + port program would never be sent.</p> + <p> + Own Id: OTP-15558 Aux Id: ERL-725 </p> + </item> + <item> + <p>There is a new function <c>persistent:term(Key, + Default)</c> to allow specifying a default when looking + up a persistent term.</p> + <p> + Own Id: OTP-15576 Aux Id: ERL-843 </p> + </item> + <item> + <p>A transitory emulator option '<c>+ztma true</c>' has + been added to allow running existing BEAM code that + relies on "tuple calls" (dispatch on parameterized + modules) which has been compiled under OTP 20 or earlier. + This option will be removed in OTP 22, so such modules + should eventually be recompiled with the + <c>+tuple_calls</c> option.</p> + <p> + Own Id: OTP-15580 Aux Id: PR-2113 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.2.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixes of install/release phase in build system.</p> + <list> <item>The source tree was modified when + installing/releasing and/or applying a patch.</item> + <item>Some files were installed with wrong access + rights.</item> <item>If applying a patch (using + <c>otp_patch_apply</c>) as another user (except root) + than the user that built the source, the documentation + was not properly updated.</item> </list> + <p> + Own Id: OTP-15551</p> + </item> + <item> + <p> + Setting the <c>recbuf</c> size of an inet socket the + <c>buffer</c> is also automatically increased. Fix a bug + where the auto adjustment of inet buffer size would be + triggered even if an explicit inet buffer size had + already been set.</p> + <p> + Own Id: OTP-15651 Aux Id: ERIERL-304 </p> + </item> + <item> + <p> + Reading from UDP using active <c>true</c> or active + <c>N</c> mode has been optimized when more packets than + specified by <c>read_packets</c> are available on the + socket.</p> + <p> + Own Id: OTP-15652 Aux Id: ERIERL-304 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.2.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + When using the <c>{linger,{true,T}}</c> option; + <c>gen_tcp:listen/2</c> used the full linger time before + returning for example <c>eaddrinuse</c>. This bug has now + been corrected.</p> + <p> + Own Id: OTP-14728 Aux Id: ERIERL-303 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.2.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix bug where doing a <c>gen_tcp:send</c> on a socket + with <c>delay_send</c> set to true could cause a segfault + if the other side closes the connection.</p> + <p> + Bug was introduced in erts-10.2 (OTP-21.2).</p> + <p> + Own Id: OTP-15536 Aux Id: ERL-827 </p> + </item> + <item> + <p> + Fix a race condition when a port program closes that + could result in the next started port to hang during + startup.</p> + <p> + When this fault happens the following error is normally + (but not always) logged:</p> + <p> + <c> =ERROR REPORT==== 14-Jan-2019::10:45:52.868246 + ===</c><br/><c> Bad input fd in erts_poll()! fd=11, + port=#Port<0.505>, driver=spawn, name=/bin/sh -s + unix:cmd </c></p> + <p> + Bug was introduced in erts-10.0 (OTP-21.0).</p> + <p> + Own Id: OTP-15537</p> + </item> + <item> + <p> + Fix a bug where polling for external events could be + delayed for a very long time if all active schedulers + were 100% loaded.</p> + <p> + Bug was introduced in erts-10.2 (OTP-21.2).</p> + <p> + Own Id: OTP-15538 Aux Id: ERIERL-229 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.2.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a crash when dangling files were closed after + <c>init:restart/0</c>.</p> + <p> + Own Id: OTP-15495 Aux Id: ERL-821 </p> + </item> + <item> + <p> + A bug that could cause dirty schedulers to become + unresponsive has been fixed.</p> + <p> + Own Id: OTP-15509 Aux Id: PR-2027, PR-2093 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.2.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed bug on big endian architectures when changing file + permissions or ownership with <c>file:change_mode</c>, + <c>change_owner</c>, <c>change_group</c> or + <c>write_file_info</c>. Bug exists since OTP-21.0.</p> + <p> + Own Id: OTP-15485</p> + </item> + <item> + <p> + Fixed bug in <c>atomics</c> with option + <c>{signed,false}</c> when returned values are <c>(1 bsl + 63)</c> or larger. Could cause heap corruption leading to + VM crash or other unpleasant symptoms. Bug exists since + OTP-21.2 when module <c>atomics</c> was introduced.</p> + <p> + Own Id: OTP-15486 Aux Id: PR-2061 </p> + </item> + <item> + <p> + Fixed bug in operator <c>band</c> of two negative + operands causing erroneous result if the absolute value + of one of the operands have the lowest <c>N*W</c> bits as + zero and the other absolute value is not larger than + <c>N*W</c> bits. <c>N</c> is an integer of 1 or larger + and <c>W</c> is 32 or 64 depending on word size.</p> + <p> + Own Id: OTP-15487 Aux Id: ERL-804 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + When a process was waiting for a TCP socket send + operation to complete, and another process closed the + socket during that send, the sending process could hang. + This bug has now been corrected.</p> + <p> + Own Id: OTP-12242 Aux Id: ERL-561 </p> + </item> + <item> + <p> + Document <c>bit_size</c> in match specifications and + allow it in <c>ets:fun2ms</c>.</p> + <p> + Own Id: OTP-15343 Aux Id: PR-1962 </p> + </item> + <item> + <p> + Fixed bug in <c>ets:select_replace</c> when called with a + fully bound key could cause a following call to + <c>ets:next</c> or <c>ets:prev</c> to crash the emulator + or return invalid result.</p> + <p> + Own Id: OTP-15346</p> + </item> + <item> + <p>When a module has been purged from memory, any + literals belonging to that module will be copied to all + processes that hold references to them. The max heap size + limit would be ignored in the garbage collection + initiated when copying literals to a process. If the max + heap size was exceeded, the process would typically be + terminated in the following garbage collection. Corrected + to terminate the process directly if copying a literal + would exceed the max heap size.</p> + <p> + Own Id: OTP-15360</p> + </item> + <item> + <p> + Fix compilation of run_erl on Solaris 11.4 and later.</p> + <p> + Own Id: OTP-15389</p> + </item> + <item> + <p>Fixed a bug where <c>lists:reverse/1-2</c> could use + far too many reductions. This bug was introduced in + <c>OTP 21.1</c>.</p> + <p> + Own Id: OTP-15436</p> + </item> + <item> + <p>Fixed a bug where a dirty scheduler could stay awake + forever if a distribution entry was removed as part of a + dirty GC.</p> + <p> + Own Id: OTP-15446 Aux Id: PR-2024 </p> + </item> + <item> + <p> + Fix microstate accounting handing in various places. Most + importantly the GC states when the GC is run on a dirty + scheduler are now managed correctly.</p> + <p> + Own Id: OTP-15450 Aux Id: ERIERL-229 </p> + </item> + <item> + <p> + Fixed bug in <c>file:sendfile</c> when the send operation + failed. For sockets in <c>active</c> modes it could cause + emulator crash or a hanging call. For sockets with + <c>{active,false}</c> an unexpected <c>{inet_reply, _, + _}</c> message could be sent to the calling process. The + bug exists since OTP-21.0.</p> + <p> + Own Id: OTP-15461 Aux Id: ERL-784 </p> + </item> + <item> + <p> + The erts configure script has been updated to reject any + CFLAGS that does not have <c>-O</c>. This in order to + prevent the common mistake of forgetting to add + <c>-O2</c> to custom CFLAGS.</p> + <p> + Own Id: OTP-15465</p> + </item> + <item> + <p> + Fix reduction count in lists:member/2</p> + <p> + Own Id: OTP-15474 Aux Id: ERIERL-229 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + New <c>counters</c> and <c>atomics</c> modules supplies + access to highly efficient operations on mutable fixed + word sized variables.</p> + <p> + Own Id: OTP-13468</p> + </item> + <item> + <p>There is a new module <c>persistent_term</c> that + implements a term storage suitable for terms that are + frequently used but never or infrequently updated. + Lookups are done in constant time without copying the + terms.</p> + <p> + Own Id: OTP-14669 Aux Id: PR-1989 </p> + </item> + <item> + <p> + A function <c>inet:getifaddrs/1</c> that takes a list + with a namespace option has been added, for platforms + that support that feature, for example Linux (only?).</p> + <p> + Own Id: OTP-15121 Aux Id: ERIERL-189, PR-1974 </p> + </item> + <item> + <p>Added the <c>nopush</c> option for TCP sockets, which + corresponds to <c>TCP_NOPUSH</c> on *BSD and + <c>TCP_CORK</c> on Linux.</p> + <p>This is also used internally in <c>file:sendfile</c> + to reduce latency on subsequent send operations.</p> + <p> + Own Id: OTP-15357 Aux Id: ERL-698 </p> + </item> + <item> + <p>List subtraction (The <c>--</c> operator) will now + yield properly on large inputs.</p> + <p> + Own Id: OTP-15371</p> + </item> + <item> + <p> + Optimize handling of send_delay for tcp sockes to better + work with the new pollthread implementation introduced in + OTP-21.</p> + <p> + Own Id: OTP-15471 Aux Id: ERIERL-229 </p> + </item> + <item> + <p> + Optimize driver_set_timer with a zero timeout to + short-circuit and not create any timer structure, but + instead schedule the timer immediately.</p> + <p> + Own Id: OTP-15472 Aux Id: ERIERL-229 </p> + </item> + <item> + <p> + Add <c>erl_xcomp_code_model_small</c> as a cross + configure variable in order to let the emulator be build + with the assumption that a small code model will be used + on the target machine.</p> + <p> + Own Id: OTP-15473 Aux Id: ERIERL-229 </p> + </item> + <item> + <p> + Add a new pollset that is made to handle sockets that use + <c>{active, true}</c> or <c>{active, N}</c>. The new + pollset will not be polled by a pollthread, but instead + polled by a normal scheduler.</p> + <p> + This change was made because of the overhead associated + with constantly having to re-apply the ONESHOT mechanism + on fds that all input events were interesting.</p> + <p> + The new pollset is only active on platforms that support + concurrent kernel poll updates, i.e. Linux and BSD.</p> + <p> + Own Id: OTP-15475 Aux Id: ERIERL-229 </p> + </item> + <item> + <p> + Fix bug where emulator would segfault if a literal + message was sent when sequence tracing was enabled.</p> + <p> + Own Id: OTP-15478 Aux Id: ERL-741 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.1.3</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>Added an optional <c>./configure</c> flag to compile + the emulator with spectre mitigation: + <c>--with-spectre-mitigation</c></p> + <p>Note that this requires a recent version of GCC with + support for spectre mitigation and the + <c>--mindirect-branch=thunk</c> flag, such as + <c>8.1</c>.</p> + <p> + Own Id: OTP-15430 Aux Id: ERIERL-237 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.1.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a rare bug where files could be closed on a + normal instead of an IO scheduler, resulting in system + instability if the operation blocked.</p> + <p> + Own Id: OTP-15421</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.1.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A bug where the socket option 'pktoptions' caused a read + of uninitialized memory has been fixed. Would cause + malfunction on FreeBSD.</p> + <p> + Own Id: OTP-14297 Aux Id: OTP-15141 </p> + </item> + <item> + <p>Fixed a memory leak on errors when reading files.</p> + <p> + Own Id: OTP-15318</p> + </item> + <item> + <p>File access through UNC paths works again on Windows. + This regression was introduced in OTP 21.</p> + <p> + Own Id: OTP-15333 Aux Id: ERL-737 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix the seq_trace token to not be cleared when a process + receives messages sent by erts. Some examples of when + this could happen is all port BIFs, i.e. + <c>open_port</c>, <c>port_command</c> etc etc.</p> + <p> + Fix so that messages sent by nifs can be traced using + normal and <c>seq_trace</c> tracing.</p> + <p> + Own Id: OTP-15038 Aux Id: ERL-602 </p> + </item> + <item> + <p> + Fixed specs and documentation for <c>process_info</c> + item <c>monitored_by</c> to include port identifiers and + nif resources as possible types.</p> + <p> + Own Id: OTP-15180 Aux Id: ERL-648 </p> + </item> + <item> + <p> + Fix bug in generation of erl_crash.dump, which could + cause VM to crash.</p> + <p> + Bug exist since erts-9.2 (OTP-20.2).</p> + <p> + Own Id: OTP-15181</p> + </item> + <item> + <p> + Fix bug where ctrl-break or ctrl-c would not trigger the + break mode properly on Windows. This bug was introduced + in erts-10.0 (OTP-21).</p> + <p> + Own Id: OTP-15205</p> + </item> + <item> + <p> + Fix a performance bug for reception of UDP packages, + where a memory buffer would be reallocated when it should + not have been.</p> + <p> + Introduce a limit on the maximum automatic increase of + the UDP user-space buffer to the theoretical max of the + network PATH, i.e. 65535.</p> + <p> + Own Id: OTP-15206</p> + </item> + <item> + <p> + Fix alignment of erts allocator state internally in erts. + With the improper alignment the emulator would refuse to + start when compiled with clang on 32-bit systems.</p> + <p> + Own Id: OTP-15208 Aux Id: PR-1897 ERL-677 </p> + </item> + <item> + <p> + Fix bug where too many concurrent calls to + <c>erlang:open_port({spawn,"cmd"},...)</c> would result + in the emulator terminating with the reason "Failed to + write to erl_child_setup: ". After this fix the + <c>open_port</c> call will throw an <c>emfile</c> + exception instead.</p> + <p> + Own Id: OTP-15210</p> + </item> + <item> + <p> + Upgraded the ERTS internal PCRE library from version 8.41 + to version 8.42. See <url + href="http://pcre.org/original/changelog.txt">http://pcre.org/original/changelog.txt</url> + for information about changes made to PCRE. This library + implements major parts of the <seealso + marker="stdlib:re"><c>re</c></seealso> regular + expressions module.</p> + <p> + Own Id: OTP-15217</p> + </item> + <item> + <p> + Fix <c>open_port({fd,X,Y}, ...)</c> to release the file + descriptors from the pollset when closing the port. + Without this fix the same file descriptor number could + not be reused when doing multiple open_port and + port_close sequences.</p> + <p> + Own Id: OTP-15236 Aux Id: ERL-692 </p> + </item> + <item> + <p> + Fixed bug in <c>float_to_list/2</c> and + <c>float_to_binary/2</c> with options + <c>[{decimals,0},compact]</c> causing totally wrong + results. Bug exists since OTP-21.0.</p> + <p> + Own Id: OTP-15276 Aux Id: PR-1920 </p> + </item> + <item> + <p> + Fixed bug in <c>erlang:memory</c> causing <c>ets</c> to + report too much. This small false memory leak (16 bytes + each time) can only happen when a specific race condition + occurs between scheduler threads on a table with option + <c>write_concurrency</c>.</p> + <p> + Own Id: OTP-15278</p> + </item> + <item> + <p> + Minor <c>configure</c> test fixes</p> + <p> + Own Id: OTP-15282</p> + </item> + <item> + <p> + Improved robustness of distribution connection setup. In + OTP-21.0 a truly asynchronous connection setup was + introduced. This is further improvement on that work to + make the emulator more robust and also be able to recover + in cases when involved Erlang processes misbehave.</p> + <p> + Own Id: OTP-15297 Aux Id: OTP-15279, OTP-15280 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The socket options <c>recvtos</c>, <c>recvttl</c>, + <c>recvtclass</c> and <c>pktoptions</c> have been + implemented in the socket modules. See the documentation + for the <c>gen_tcp</c>, <c>gen_udp</c> and <c>inet</c> + modules. Note that support for these in the runtime + system is platform dependent. Especially for + <c>pktoptions</c> which is very Linux specific and + obsoleted by the RFCs that defined it.</p> + <p> + Own Id: OTP-15145 Aux Id: ERIERL-187 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + As of ERTS version 10.0 (OTP 21.0) the + <c>erl_child_setup</c> program, which creates port + programs, ignores <c>TERM</c> signals. This setting was + unintentionally inherited by port programs. Handling of + <c>TERM</c> signals in port programs has now been + restored to the default behavior. That is, terminate the + process.</p> + <p> + Own Id: OTP-15289 Aux Id: ERIERL-235, OTP-14943, ERL-576 </p> + </item> + <item> + <p> + The fix made for OTP-15279 in erts-10.07 (OTP-21.0.8) was + not complete. It could cause a new connection attempt to + be incorrectly aborted in certain cases. This fix will + amend that flaw.</p> + <p> + Own Id: OTP-15296 Aux Id: OTP-15279, ERIERL-226 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A process could get stuck in an infinite rescheduling + loop between normal and dirty schedulers. This bug was + introduced in ERTS version 10.0.</p> + <p> + Thanks to Maxim Fedorov for finding and fixing this + issue.</p> + <p> + Own Id: OTP-15275 Aux Id: PR-1943 </p> + </item> + <item> + <p> + Garbage collection of a distribution entry could cause an + emulator crash if <c>net_kernel</c> had not brought + previous connection attempts on it down properly.</p> + <p> + Own Id: OTP-15279 Aux Id: ERIERL-226 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A race between termination of a process and resume of the + same process via <c>erlang:resume_process/1</c> could + cause the VM to crash. This bug was introduced in erts + version 10.0 (OTP 21.0).</p> + <p> + Own Id: OTP-15237</p> + </item> + <item> + <p> + When tracing on <c>running</c>, <c>in</c> trace events + could be lost when a process was rescheduled between a + dirty and a normal scheduler.</p> + <p> + Own Id: OTP-15269 Aux Id: ERL-713 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed a bug which caused an emulator crash when + <c>enif_send()</c> was called by a NIF that executed on a + dirty scheduler. The bug was either triggered when the + NIF called <c>enif_send()</c> without a message + environment, or when the process executing the NIF was + <c>send</c> traced.</p> + <p> + Own Id: OTP-15223</p> + </item> + <item> + <p> + Fixed a bug causing some Erlang references to be + inconsistently ordered. This could for example cause + failure to look up certain elements with references as + keys in search data structures. This bug was introduced + in R13B02.</p> + <p> + Thanks to Simon Cornish for finding the bug and supplying + a fix.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-15225</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a bug that prevented the <c>noshell</c> option + from working correctly on Mac OS X and BSD.</p> + <p> + Own Id: OTP-15169</p> + </item> + <item> + <p>Fixed a crash when matching directly against a literal + map using a single key that had been saved on the + stack.</p> + <p> + Own Id: OTP-15184</p> + </item> + <item> + <p>Fix node crash when passing a bad time option to + <c>file:read_file_info/2</c>.</p> + <p> + Own Id: OTP-15196</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a scheduler bug that caused normal schedulers to + run dirty code.</p> + <p> + Own Id: OTP-15154</p> + </item> + <item> + <p> + Fixed a bug in <c>erlang:trace_info/2</c> which caused + the emulator to crash when a bad argument was passed. The + bug was introduced in ERTS version 10.0.</p> + <p> + Own Id: OTP-15183 Aux Id: ERL-670 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a rare bug that could cause processes to be + scheduled after they had been freed.</p> + <p> + Own Id: OTP-15067 Aux Id: ERL-573 </p> + </item> + <item> + <p>Fixed a race condition in the inet driver that could + cause receive to hang when the emulator was compiled with + gcc 8.</p> + <p> + Own Id: OTP-15158 Aux Id: ERL-654 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>The keys used in <c>os:getenv</c> and <c>os:putenv</c> + are case-insensitive again on Windows.</p> + <p> + Own Id: OTP-15147 Aux Id: ERL-644 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 10.0</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -967,6 +2707,267 @@ </section> +<section><title>Erts 9.3.3.11</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a buffer overflow when + <c>binary_to_existing_atom/2</c> and + <c>list_to_existing_atom/2</c> was used with the + <c>latin1</c> encoding.</p> + <p> + Own Id: OTP-15819 Aux Id: ERL-944 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 9.3.3.10</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixes of install/release phase in build system.</p> + <list> <item>The source tree was modified when + installing/releasing and/or applying a patch.</item> + <item>Some files were installed with wrong access + rights.</item> <item>If applying a patch (using + <c>otp_patch_apply</c>) as another user (except root) + than the user that built the source, the documentation + was not properly updated.</item> </list> + <p> + Own Id: OTP-15551</p> + </item> + <item> + <p> + Minor fixes for <c>make clean</c>.</p> + <p> + Own Id: OTP-15657</p> + </item> + <item> + <p> + Fixed a bug in all <c>ets:select*</c> and + <c>ets:match*</c> functions that could in some rare cases + lead to very poor performance.</p> + <p> + Own Id: OTP-15660 Aux Id: ERL-869 </p> + </item> + <item> + <p> + Fix a possible deadlock when terminating the ERTS caused + by a dirty scheduler not releasing it's run-queue lock + when terminating.</p> + <p> + Own Id: OTP-15690 Aux Id: PR-2172 </p> + </item> + <item> + <p>Add missing documentation of new external tags + <c>NEW_PID</c>, <c>NEW_PORT</c> and + <c>NEWER_REFERENCE</c> introduced in OTP 19.</p> <p>These + new tags are planned to be "activated" in OTP 23 when + distribution capability flag <c>DFLAG_BIG_CREATION</c> + becomes mandatory. Older nodes (>= 19) are able to decode + these new tags and send them back to the new node. Nodes + older than OTP 23 will however never encode their own + local pids, ports and references using the new tags.</p> + <p> + Own Id: OTP-15766</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 9.3.3.9</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>Added an optional <c>./configure</c> flag to compile + the emulator with spectre mitigation: + <c>--with-spectre-mitigation</c></p> + <p>Note that this requires a recent version of GCC with + support for spectre mitigation and the + <c>--mindirect-branch=thunk</c> flag, such as + <c>8.1</c>.</p> + <p> + Own Id: OTP-15430 Aux Id: ERIERL-237 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 9.3.3.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A bug that could cause dirty schedulers to become + unresponsive has been fixed.</p> + <p> + Own Id: OTP-15509 Aux Id: PR-2027, PR-2093 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 9.3.3.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed bug in operator <c>band</c> of two negative + operands causing erroneous result if the absolute value + of one of the operands have the lowest <c>N*W</c> bits as + zero and the other absolute value is not larger than + <c>N*W</c> bits. <c>N</c> is an integer of 1 or larger + and <c>W</c> is 32 or 64 depending on word size.</p> + <p> + Own Id: OTP-15487 Aux Id: ERL-804 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 9.3.3.6</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>List subtraction (The <c>--</c> operator) will now + yield properly on large inputs.</p> + <p> + Own Id: OTP-15371</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 9.3.3.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + ERTS internal trees of monitor structures could get into + an inconsistent state. This could cause <c>'DOWN'</c> + messages not to be delivered when they should, as well as + delivery of <c>'DOWN'</c> messages that should not be + delivered.</p> + <p> + This bug was introduced in ERTS version 9.0 (OTP 20.0) + and was fixed in ERTS version 10.0 (OTP 21.0) due to a + rewrite of the monitor code. That is, this bug only exist + in the OTP 20 release.</p> + <p> + Own Id: OTP-15399 Aux Id: ERL-751, ERIERL-262, OTP-14205 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 9.3.3.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed bug in <c>ets:select_replace</c> when called with a + fully bound key could cause a following call to + <c>ets:next</c> or <c>ets:prev</c> to crash the emulator + or return invalid result.</p> + <p> + Own Id: OTP-15346</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 9.3.3.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed a bug which caused an emulator crash when + <c>enif_send()</c> was called by a NIF that executed on a + dirty scheduler. The bug was either triggered when the + NIF called <c>enif_send()</c> without a message + environment, or when the process executing the NIF was + <c>send</c> traced.</p> + <p> + Own Id: OTP-15223</p> + </item> + <item> + <p> + Fixed a bug causing some Erlang references to be + inconsistently ordered. This could for example cause + failure to look up certain elements with references as + keys in search data structures. This bug was introduced + in R13B02.</p> + <p> + Thanks to Simon Cornish for finding the bug and supplying + a fix.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-15225</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 9.3.3.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a race condition in the inet driver that could + cause receive to hang when the emulator was compiled with + gcc 8.</p> + <p> + Own Id: OTP-15158 Aux Id: ERL-654 </p> + </item> + <item> + <p> + Fix bug in generation of erl_crash.dump, which could + cause VM to crash.</p> + <p> + Bug exist since erts-9.2 (OTP-20.2).</p> + <p> + Own Id: OTP-15181</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 9.3.3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a rare bug that could cause processes to be + scheduled after they had been freed.</p> + <p> + Own Id: OTP-15067 Aux Id: ERL-573 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 9.3.3</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -1196,6 +3197,22 @@ </section> +<section><title>Erts 9.2.0.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Extra internal consistency checks wrt communication with + erl_child_setup process.</p> + <p> + Own Id: OTP-15488 Aux Id: ERIERL-231 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 9.2</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -2394,6 +4411,116 @@ </section> +<section><title>Erts 8.3.5.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed bug in operator <c>band</c> of two negative + operands causing erroneous result if the absolute value + of one of the operands have the lowest <c>N*W</c> bits as + zero and the other absolute value is not larger than + <c>N*W</c> bits. <c>N</c> is an integer of 1 or larger + and <c>W</c> is 32 or 64 depending on word size.</p> + <p> + Own Id: OTP-15487 Aux Id: ERL-804 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>Added an optional <c>./configure</c> flag to compile + the emulator with spectre mitigation: + <c>--with-spectre-mitigation</c></p> + <p>Note that this requires a recent version of GCC with + support for spectre mitigation and the + <c>--mindirect-branch=thunk</c> flag, such as + <c>8.1</c>.</p> + <p> + Own Id: OTP-15430 Aux Id: ERIERL-237 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 8.3.5.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed small memory leak that could occur when sending to + a terminating port.</p> + <p> + Own Id: OTP-14609 Aux Id: ERIERL-238 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 8.3.5.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a race condition in the inet driver that could + cause receive to hang when the emulator was compiled with + gcc 8.</p> + <p> + Own Id: OTP-15158 Aux Id: ERL-654 </p> + </item> + <item> + <p> + Fixed a bug causing some Erlang references to be + inconsistently ordered. This could for example cause + failure to look up certain elements with references as + keys in search data structures. This bug was introduced + in R13B02.</p> + <p> + Thanks to Simon Cornish for finding the bug and supplying + a fix.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-15225</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 8.3.5.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a bug in file closure on Unix; close(2) was + retried on EINTR which could cause a different (recently + opened) file to be closed as well.</p> + <p> + Own Id: OTP-14775</p> + </item> + <item> + <p> + A race-condition when tearing down a connection with + active node monitors could cause the runtime system to + crash.</p> + <p> + This bug was introduced in ERTS version 8.0 (OTP 19.0).</p> + <p> + Own Id: OTP-14781 Aux Id: OTP-13047 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 8.3.5.3</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -4221,6 +6348,37 @@ </section> +<section><title>Erts 7.3.1.6</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>List subtraction (The <c>--</c> operator) will now + yield properly on large inputs.</p> + <p> + Own Id: OTP-15371</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 7.3.1.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed small memory leak that could occur when sending to + a terminating port.</p> + <p> + Own Id: OTP-14609 Aux Id: ERIERL-238 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 7.3.1.4</title> <section><title>Fixed Bugs and Malfunctions</title> <list> @@ -5713,6 +7871,103 @@ </section> +<section><title>Erts 6.4.1.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A process communicating with a port via one of the + <c>erlang:port_*</c> BIFs could potentially end up in an + inconsistent state if the port terminated during the + communication. When this occurred the process could later + block in a <c>receive</c> even though it had messages + matching in its message queue.</p> + <p> + This bug was introduced in erts version 5.10 (OTP R16A).</p> + <p> + Own Id: OTP-13424 Aux Id: OTP-10336 </p> + </item> + <item> + <p> + Calls to <c>erl_drv_send_term()</c> or + <c>erl_drv_output_term()</c> from a non-scheduler thread + while the corresponding port was invalid caused the + emulator to enter an inconsistent state which eventually + caused an emulator crash.</p> + <p> + Own Id: OTP-13866</p> + </item> + <item> + <p>Driver and NIF operations accessing processes or ports + could cause an emulator crash when used from + non-scheduler threads. Those operations are:</p> <list> + <item><c>erl_drv_send_term()</c></item> + <item><c>driver_send_term()</c></item> + <item><c>erl_drv_output_term()</c></item> + <item><c>driver_output_term()</c></item> + <item><c>enif_send()</c></item> + <item><c>enif_port_command()</c></item> </list> + <p> + Own Id: OTP-13869</p> + </item> + <item> + <p> + Fix bug in <c>binary_to_term</c> for binaries created by + <c>term_to_binary </c> with option <c>compressed</c>. The + bug can cause <c>badarg</c> exception for a valid binary + when Erlang VM is linked against a <c>zlib</c> library of + version 1.2.9 or newer. Bug exists since OTP 17.0.</p> + <p> + Own Id: OTP-14159 Aux Id: ERL-340 </p> + </item> + <item> + <p> + Fixed bug in operator <c>bxor</c> causing erroneuos + result when one operand is a big <em>negative</em> + integer with the lowest <c>N*W</c> bits as zero and the + other operand not larger than <c>N*W</c> bits. <c>N</c> + is an integer of 1 or larger and <c>W</c> is 32 or 64 + depending on word size.</p> + <p> + Own Id: OTP-14514</p> + </item> + <item> + <p> + Fixed bug in <c>binary_to_term</c> and + <c>binary_to_atom</c> that could cause VM crash. + Typically happens when the last character of an UTF8 + string is in the range 128 to 255, but truncated to only + one byte. Bug exists in <c>binary_to_term</c> since ERTS + version 5.10.2 (OTP_R16B01) and <c>binary_to_atom</c> + since ERTS version 9.0 (OTP-20.0).</p> + <p> + Own Id: OTP-14590 Aux Id: ERL-474 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 6.4.1.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + When calling <c>garbage_collect/[1,2]</c> or + <c>check_process_code/[2,3]</c> from a process with a + higher priority than the priority of the process operated + on, the run queues could end up in an inconsistent state. + This bug has now been fixed.</p> + <p> + Own Id: OTP-13298 Aux Id: OTP-11388 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 6.4.1.5</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -6906,8 +9161,7 @@ Erlang/OTP has been ported to the realtime operating system OSE. The port supports both smp and non-smp emulator. For details around the port and how to started - see the User's Guide in the <seealso - marker="ose:ose_intro">ose</seealso> application. </p> + see the User's Guide in the <em>ose</em> application.</p> <p> Note that not all parts of Erlang/OTP has been ported. </p> <p> @@ -8013,9 +10267,9 @@ <c>fix_alloc</c> allocator, a different strategy for management of fix blocks will be used.</item> <item>The information returned from <seealso - marker="erlang:system_info_allocator_tuple"><c>erlang:system_info({allocator, + marker="erlang#system_info_allocator_tuple"><c>erlang:system_info({allocator, A})</c></seealso>, and <seealso - marker="erlang:system_info_allocator_sizes"><c>erlang:system_info({allocator_sizes, + marker="erlang#system_info_allocator_sizes"><c>erlang:system_info({allocator_sizes, A})</c></seealso> will be slightly different when this feature has been enabled. An <c>mbcs_pool</c> tuple will be present giving information about abandoned carriers, @@ -8824,8 +11078,7 @@ information about signal ordering guarantees, see the chapter on <seealso marker="erts:communication">communication</seealso> in - the ERTS user's guide. The <seealso - marker="erts:erl#+n">+n</seealso> command line flag of + the ERTS user's guide. The <c>+n</c> command line flag of <seealso marker="erts:erl">erl(1)</seealso> can be helpful when trying to find signaling order bugs in Erlang code that have been exposed by these @@ -9804,7 +12057,7 @@ you use erlang:halt/2 with an integer first argument and an option list containing {flush,false} as the second argument. Note that now is flushing not dependant of the - exit code, and you can not only flush async threads + exit code, and you cannot only flush async threads operations which we deemed as a strange behaviour anyway. </p> <p>Also, erlang:halt/1,2 has gotten a new feature: If the @@ -18539,4 +20792,3 @@ </section> </section> </chapter> - diff --git a/erts/doc/src/part.xml b/erts/doc/src/part.xml index 05e9a24af8..f0b8a00b90 100644 --- a/erts/doc/src/part.xml +++ b/erts/doc/src/part.xml @@ -42,6 +42,7 @@ <xi:include href="tty.xml"/> <xi:include href="driver.xml"/> <xi:include href="inet_cfg.xml"/> + <xi:include href="socket_usage.xml"/> <xi:include href="erl_ext_dist.xml"/> <xi:include href="erl_dist_protocol.xml"/> </part> diff --git a/erts/doc/src/persistent_term.xml b/erts/doc/src/persistent_term.xml new file mode 100644 index 0000000000..672b00a83a --- /dev/null +++ b/erts/doc/src/persistent_term.xml @@ -0,0 +1,293 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2018</year><year>2018</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>persistent_term</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + <file>persistent_term.xml</file> + </header> + <module since="OTP 21.2">persistent_term</module> + <modulesummary>Persistent terms.</modulesummary> + <description> + <p>This module is similar to <seealso + marker="stdlib:ets"><c>ets</c></seealso> in that it provides a + storage for Erlang terms that can be accessed in constant time, + but with the difference that <c>persistent_term</c> has been + highly optimized for reading terms at the expense of writing and + updating terms. When a persistent term is updated or deleted, a + global garbage collection pass is run to scan all processes for + the deleted term, and to copy it into each process that still uses + it. Therefore, <c>persistent_term</c> is suitable for storing + Erlang terms that are frequently accessed but never or + infrequently updated.</p> + + <warning><p>Persistent terms is an advanced feature and is not a + general replacement for ETS tables. Before using persistent terms, + make sure to fully understand the consequence to system + performance when updating or deleting persistent terms.</p></warning> + + <p>Term lookup (using <seealso + marker="#get/1"><c>get/1</c></seealso>), is done in constant time + and without taking any locks, and the term is <strong>not</strong> + copied to the heap (as is the case with terms stored in ETS + tables).</p> + + <p>Storing or updating a term (using <seealso + marker="#put/2"><c>put/2</c></seealso>) is proportional to the + number of already created persistent terms because the hash table + holding the keys will be copied. In addition, the term itself will + be copied.</p> + + <p>When a (complex) term is deleted (using <seealso + marker="#erase/1"><c>erase/1</c></seealso>) or replaced by another + (using <seealso marker="#put/2"><c>put/2</c></seealso>), a global + garbage collection is initiated. It works like this:</p> + + <list> + <item><p>All processes in the system will be scheduled to run a + scan of their heaps for the term that has been deleted. While + such scan is relatively light-weight, if there are many + processes, the system can become less responsive until all + process have scanned their heaps.</p></item> + + <item><p>If the deleted term (or any part of it) is still used + by a process, that process will do a major (fullsweep) garbage + collection and copy the term into the process. However, at most + two processes at a time will be scheduled to do that kind of + garbage collection.</p></item> + </list> + + <p>Deletion of atoms and other terms that fit in one machine word + is specially optimized to avoid doing a global GC. It is still not + recommended to update persistent terms with such values too + frequently because the hash table holding the keys is copied every + time a persistent term is updated.</p> + + <p>Some examples are suitable uses for persistent terms are:</p> + + <list> + <item><p>Storing of configuration data that must be easily + accessible by all processes.</p></item> + + <item><p>Storing of references for NIF resources.</p></item> + + <item><p>Storing of references for efficient counters.</p></item> + + <item><p>Storing an atom to indicate a logging level or whether debugging + is turned on.</p></item> + </list> + + </description> + + <section> + <title>Storing Huge Persistent Terms</title> + <p>The current implementation of persistent terms uses the literal + <seealso marker="erts_alloc">allocator</seealso> also used for + literals (constant terms) in BEAM code. By default, 1 GB of + virtual address space is reserved for literals in BEAM code and + persistent terms. The amount of virtual address space reserved for + literals can be changed by using the <seealso + marker="erts_alloc#MIscs"><c>+MIscs option</c></seealso> when + starting the emulator.</p> + + <p>Here is an example how the reserved virtual address space for literals + can be raised to 2 GB (2048 MB):</p> + + <pre> + erl +MIscs 2048</pre> + </section> + + <section> + <title>Best Practices for Using Persistent Terms</title> + + <p>It is recommended to use keys like <c>?MODULE</c> or + <c>{?MODULE,SubKey}</c> to avoid name collisions.</p> + + <p>Prefer creating a few large persistent terms to creating many + small persistent terms. The execution time for storing a + persistent term is proportional to the number of already existing + terms.</p> + + <p>Updating a persistent term with the same value as it already + has is specially optimized to do nothing quickly; thus, there is + no need compare the old and new values and avoid calling + <seealso marker="#put/2"><c>put/2</c></seealso> if the values + are equal.</p> + + <p>When atoms or other terms that fit in one machine word are + deleted, no global GC is needed. Therefore, persistent terms that + have atoms as their values can be updated more frequently, but + note that updating such persistent terms is still much more + expensive than reading them.</p> + + <p>Updating or deleting a persistent term will trigger a global GC + if the term does not fit in one machine word. Processes will be + scheduled as usual, but all processes will be made runnable at + once, which will make the system less responsive until all process + have run and scanned their heaps for the deleted terms. One way to + minimize the effects on responsiveness could be to minimize the + number of processes on the node before updating or deleting a + persistent term. It would also be wise to avoid updating terms + when the system is at peak load.</p> + + <p>Avoid storing a retrieved persistent term in a process if that + persistent term could be deleted or updated in the future. If a + process holds a reference to a persistent term when the term is + deleted, the process will be garbage collected and the term copied + to process.</p> + + <p>Avoid updating or deleting more than one persistent term at a + time. Each deleted term will trigger its own global GC. That + means that deleting N terms will make the system less responsive N + times longer than deleting a single persistent term. Therefore, + terms that are to be updated at the same time should be collected + into a larger term, for example, a map or a tuple.</p> + </section> + + <section> + <title>Example</title> + + <p>The following example shows how lock contention for ETS tables + can be minimized by having one ETS table for each scheduler. The + table identifiers for the ETS tables are stored as a single + persistent term:</p> + +<pre> + %% There is one ETS table for each scheduler. + Sid = erlang:system_info(scheduler_id), + Tid = element(Sid, persistent_term:get(?MODULE)), + ets:update_counter(Tid, Key, 1).</pre> + + </section> + + <datatypes> + <datatype> + <name name="key"/> + <desc> + <p>Any Erlang term.</p> + </desc> + </datatype> + <datatype> + <name name="value"/> + <desc> + <p>Any Erlang term.</p> + </desc> + </datatype> + </datatypes> + + <funcs> + <func> + <name name="erase" arity="1" since="OTP 21.2"/> + <fsummary>Erase the name for a persistent term.</fsummary> + <desc> + <p>Erase the name for the persistent term with key + <c><anno>Key</anno></c>. The return value will be <c>true</c> + if there was a persistent term with the key + <c><anno>Key</anno></c>, and <c>false</c> if there was no + persistent term associated with the key.</p> + <p>If there existed a previous persistent term associated with + key <c><anno>Key</anno></c>, a global GC has been initiated + when <c>erase/1</c> returns. See <seealso + marker="#description">Description</seealso>.</p> + </desc> + </func> + + <func> + <name name="get" arity="0" since="OTP 21.2"/> + <fsummary>Get all persistent terms.</fsummary> + <desc> + <p>Retrieve the keys and values for all persistent terms. + The keys will be copied to the heap for the process calling + <c>get/0</c>, but the values will not.</p> + </desc> + </func> + + <func> + <name name="get" arity="1" since="OTP 21.2"/> + <fsummary>Get the value for a persistent term.</fsummary> + <desc> + <p>Retrieve the value for the persistent term associated with + the key <c><anno>Key</anno></c>. The lookup will be made in + constant time and the value will not be copied to the heap + of the calling process.</p> + <p>This function fails with a <c>badarg</c> exception if no + term has been stored with the key + <c><anno>Key</anno></c>.</p> + <p>If the calling process holds on to the value of the + persistent term and the persistent term is deleted in the future, + the term will be copied to the process.</p> + </desc> + </func> + + <func> + <name name="get" arity="2" since="OTP 21.3"/> + <fsummary>Get the value for a persistent term.</fsummary> + <desc> + <p>Retrieve the value for the persistent term associated with + the key <c><anno>Key</anno></c>. The lookup will be made in + constant time and the value will not be copied to the heap + of the calling process.</p> + <p>This function returns <c><anno>Default</anno></c> if no + term has been stored with the key <c><anno>Key</anno></c>.</p> + <p>If the calling process holds on to the value of the + persistent term and the persistent term is deleted in the future, + the term will be copied to the process.</p> + </desc> + </func> + + <func> + <name name="info" arity="0" since="OTP 21.2"/> + <fsummary>Get information about persistent terms.</fsummary> + <desc> + <p>Return information about persistent terms in a map. The map + has the following keys:</p> + <taglist> + <tag><c>count</c></tag> + <item><p>The number of persistent terms.</p></item> + <tag><c>memory</c></tag> + <item><p>The total amount of memory (measured in bytes) + used by all persistent terms.</p></item> + </taglist> + </desc> + </func> + + <func> + <name name="put" arity="2" since="OTP 21.2"/> + <fsummary>Store a term.</fsummary> + <desc> + <p>Store the value <c><anno>Value</anno></c> as a persistent term and + associate it with the key <c><anno>Key</anno></c>.</p> + <p>If the value <c><anno>Value</anno></c> is equal to the value + previously stored for the key, <c>put/2</c> will do nothing and return + quickly.</p> + <p>If there existed a previous persistent term associated with + key <c><anno>Key</anno></c>, a global GC has been initiated + when <c>put/2</c> returns. See <seealso + marker="#description">Description</seealso>.</p> + </desc> + </func> + </funcs> +</erlref> diff --git a/erts/doc/src/ref_man.xml b/erts/doc/src/ref_man.xml index 0617463a7b..80cdcf9145 100644 --- a/erts/doc/src/ref_man.xml +++ b/erts/doc/src/ref_man.xml @@ -4,7 +4,7 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1996</year><year>2016</year> + <year>1996</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -31,23 +31,28 @@ </header> <description> </description> - <xi:include href="erl_prim_loader.xml"/> - <xi:include href="erlang.xml"/> - <xi:include href="init.xml"/> - <xi:include href="zlib.xml"/> + <xi:include href="atomics.xml"/> + <xi:include href="counters.xml"/> + <xi:include href="driver_entry.xml"/> <xi:include href="epmd.xml"/> <xi:include href="erl.xml"/> + <xi:include href="erlang.xml"/> <xi:include href="erlc.xml"/> - <xi:include href="werl.xml"/> - <xi:include href="escript.xml"/> - <xi:include href="erlsrv.xml"/> - <xi:include href="start_erl.xml"/> - <xi:include href="run_erl.xml"/> - <xi:include href="start.xml"/> <xi:include href="erl_driver.xml"/> - <xi:include href="driver_entry.xml"/> - <xi:include href="erts_alloc.xml"/> <xi:include href="erl_nif.xml"/> + <xi:include href="erl_prim_loader.xml"/> + <xi:include href="erlsrv.xml"/> <xi:include href="erl_tracer.xml"/> + <xi:include href="erts_alloc.xml"/> + <xi:include href="escript.xml"/> + <xi:include href="init.xml"/> + <xi:include href="net.xml"/> + <xi:include href="persistent_term.xml"/> + <xi:include href="run_erl.xml"/> + <xi:include href="socket.xml"/> + <xi:include href="start.xml"/> + <xi:include href="start_erl.xml"/> + <xi:include href="werl.xml"/> + <xi:include href="zlib.xml"/> </application> diff --git a/erts/doc/src/socket.xml b/erts/doc/src/socket.xml new file mode 100644 index 0000000000..b4e22e86a8 --- /dev/null +++ b/erts/doc/src/socket.xml @@ -0,0 +1,915 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2018</year><year>2019</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>socket</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + <file>socket.xml</file> + </header> + <module since="OTP 22.0">socket</module> + <modulesummary>Socket interface.</modulesummary> + <description> + <p>This module provides an API for the socket interface. + It is used to create, delete and manipulate sockets, + send and receive data.</p> + <p>The idea is that it shall be as "close as possible" to the OS + level socket interface. The only significant addition is that some of + the functions, + e.g. <seealso marker="#recv/3"><c>recv/3</c></seealso>, + has a timeout argument. </p> + <note> + <p>Some functions allow for an <i>asynchronous</i> call. + This is achieved by setting the <c>Timeout</c> argument to + <c>nowait</c>. For instance, if calling the + <seealso marker="#recv_async"><c>recv/3</c></seealso> + function with Timeout set to <c>nowait</c> (<c>recv(Sock, 0, nowait)</c>) + when there is actually nothing to read, it will return with + <c>{ok, </c> + <seealso marker="#type-select_info"><c>SelectInfo</c></seealso><c>}</c>. + When data eventually arrives a 'select' message + will be sent to the caller: </p> + <taglist> + <!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL --> + <tag></tag> + <item><c>{'$socket', socket(), select, select_ref()}</c></item> + </taglist> + <p>The caller can now make another + call to the recv function and now expect data.</p> + <p>Note that all other users are <em>locked out</em> until the + 'current user' has called the function (recv in this case).</p> + <p>Another message the user must be prepared for (when making asynchronous + calls) is the <c>abort</c> message:</p> + <taglist> + <!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL --> + <tag></tag> + <item><c>{'$socket', socket(), abort, Info}</c></item> + </taglist> + <p>This message indicates + that the (asynchronous) operation has been aborted. + If, for instance, the socket has been closed (by another process), + <c>Info</c> will be <c>{select_ref(), closed}</c>. </p> + </note> + <note> + <p>There is currently <em>no</em> support for Windows. </p> + <p>Support for IPv6 has been implemented but <em>not</em> tested. </p> + <p>SCTP has only been partly implemented (and not tested). </p> + </note> + </description> + + <datatypes> + <datatype> + <name name="domain"/> + </datatype> + <datatype> + <name name="type"/> + </datatype> + <datatype> + <name name="protocol"/> + </datatype> + <datatype> + <name>socket()</name> + <desc><p>As returned by + <seealso marker="#open/2"><c>open/2,3,4</c></seealso> and + <seealso marker="#accept/1"><c>accept/1,2</c></seealso>.</p> + </desc> + </datatype> + <datatype> + <name name="select_tag"/> + <desc> + <p>A tag that describes the (select) operation.</p> + </desc> + </datatype> + <datatype> + <name name="select_ref"/> + <desc> + <p>A reference that uniquely identifies the (select) operation.</p> + </desc> + </datatype> + <datatype> + <name name="select_info"/> + </datatype> + <datatype> + <name name="ip4_address"/> + </datatype> + <datatype> + <name name="ip6_address"/> + </datatype> + <datatype> + <name name="ip_address"/> + </datatype> + <datatype> + <name name="sockaddr"/> + </datatype> + <datatype> + <name name="sockaddr_in4"/> + </datatype> + <datatype> + <name name="sockaddr_in6"/> + </datatype> + <datatype> + <name name="sockaddr_un"/> + </datatype> + <datatype> + <name name="port_number"/> + </datatype> + <datatype> + <name name="in6_flow_info"/> + </datatype> + <datatype> + <name name="in6_scope_id"/> + </datatype> + <datatype> + <name name="accept_flags"/> + </datatype> + <datatype> + <name name="accept_flag"/> + </datatype> + <datatype> + <name name="send_flags"/> + </datatype> + <datatype> + <name name="send_flag"/> + </datatype> + <datatype> + <name name="recv_flags"/> + </datatype> + <datatype> + <name name="recv_flag"/> + </datatype> + <datatype> + <name name="shutdown_how"/> + </datatype> + <datatype> + <name name="sockopt_level"/> + </datatype> + <datatype> + <name name="otp_socket_option"/> + </datatype> + <datatype> + <name name="socket_option"/> + </datatype> + <datatype> + <name name="ip_socket_option"/> + </datatype> + <datatype> + <name name="ipv6_socket_option"/> + </datatype> + <datatype> + <name name="tcp_socket_option"/> + </datatype> + <datatype> + <name name="udp_socket_option"/> + </datatype> + <datatype> + <name name="sctp_socket_option"/> + </datatype> + <datatype> + <name name="timeval"/> + </datatype> + <datatype> + <name name="ip_tos"/> + </datatype> + <datatype> + <name name="ip_mreq"/> + </datatype> + <datatype> + <name name="ip_mreq_source"/> + </datatype> + <datatype> + <name name="ip_pmtudisc"/> + </datatype> + <datatype> + <name name="ip_msfilter_mode"/> + </datatype> + <datatype> + <name name="ip_msfilter"/> + </datatype> + <datatype> + <name name="ip_pktinfo"/> + </datatype> + <datatype> + <name name="ipv6_mreq"/> + </datatype> + <datatype> + <name name="ipv6_pmtudisc"/> + </datatype> + <datatype> + <name name="ipv6_pktinfo"/> + </datatype> + <datatype> + <name name="sctp_assoc_id"/> + </datatype> + <datatype> + <name name="sctp_sndrcvinfo"/> + </datatype> + <datatype> + <name name="sctp_event_subscribe"/> + </datatype> + <datatype> + <name name="sctp_assocparams"/> + </datatype> + <datatype> + <name name="sctp_initmsg"/> + </datatype> + <datatype> + <name name="sctp_rtoinfo"/> + </datatype> + <datatype> + <name name="msghdr_flag"/> + </datatype> + <datatype> + <name name="msghdr_flags"/> + </datatype> + <datatype> + <name name="msghdr"/> + </datatype> + <datatype> + <name name="cmsghdr_level"/> + </datatype> + <datatype> + <name name="cmsghdr_type"/> + </datatype> + <!-- + <datatype> + <name name="cmsghdr_data"/> + </datatype> + --> + <datatype> + <name name="cmsghdr_recv"/> + </datatype> + <datatype> + <name name="cmsghdr_send"/> + </datatype> + <datatype> + <name name="uint8"/> + </datatype> + <datatype> + <name name="uint16"/> + </datatype> + <datatype> + <name name="uint20"/> + </datatype> + <datatype> + <name name="uint32"/> + </datatype> + <datatype> + <name name="int32"/> + </datatype> + <datatype> + <name name="supports_options_socket"/> + </datatype> + <datatype> + <name name="supports_options_ip"/> + </datatype> + <datatype> + <name name="supports_options_ipv6"/> + </datatype> + <datatype> + <name name="supports_options_tcp"/> + </datatype> + <datatype> + <name name="supports_options_udp"/> + </datatype> + <datatype> + <name name="supports_options_sctp"/> + </datatype> + <datatype> + <name name="supports_options"/> + </datatype> + </datatypes> + + <funcs> + <func> + <name name="accept" arity="1" since="OTP 22.0"/> + <name name="accept" arity="2" clause_i="2" since="OTP 22.0"/> + <fsummary>Accept a connection on a socket.</fsummary> + <desc> + <p>Accept a connection on a socket.</p> + <p>This call is used with connection-based socket types + (<c>stream</c> or <c>seqpacket</c>). It extracs the first pending + connection request for the listen socket and returns the (newly) + connected socket.</p> + </desc> + </func> + + <func> + <name name="accept" arity="2" clause_i="1" anchor="accept_async" since="OTP @OTP-15731@"/> + <fsummary>Accept a connection on a socket.</fsummary> + <desc> + <p>Accept a connection on a socket.</p> + + <p>This call is used with connection-based socket types + (<c>stream</c> or <c>seqpacket</c>). It extracs the first pending + connection request for the listen socket and returns the (newly) + connected socket.</p> + + <p>In the case when there is no connections waiting, the function + will return with the <c>SelectInfo</c>. The caller can then await a + select message, <c>{'$socket', Socket, select, Info}</c> (where + <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>), + when a client connects (a subsequent call to accept will then return + the socket). </p> + </desc> + </func> + + <func> + <name name="bind" arity="2" since="OTP 22.0"/> + <fsummary>Bind a name to a socket.</fsummary> + <desc> + <p>Bind a name to a socket.</p> + <p>When a socket is created + (with <seealso marker="#open/2"><c>open</c></seealso>), + it has no address assigned to it. <c>bind</c> assigns the + address specified by the <c>Addr</c> argument.</p> + <p>The rules used for name binding vary between domains.</p> + </desc> + </func> + + <func> + <name name="cancel" arity="2" since="OTP @OTP-15731@"/> + <fsummary>Cancel an asynchronous request.</fsummary> + <desc> + <p>Cancel an asynchronous request.</p> + + <p>Call this function in order to cancel a previous + asynchronous call to, e.g. + <seealso marker="#recv/3"><c>recv/3</c></seealso>. </p> + </desc> + </func> + + <func> + <name name="close" arity="1" since="OTP 22.0"/> + <fsummary>Close a socket.</fsummary> + <desc> + <p>Closes the socket.</p> + + <note> + <p>Note that for e.g. <c>protocol</c> = <c>tcp</c>, most implementations + doing a close does not guarantee that any data sent is delivered to + the recipient before the close is detected at the remote side. </p> + <p>One way to handle this is to use the + <seealso marker="#shutdown/2"><c>shutdown</c></seealso> + function + (<c>socket:shutdown(Socket, write)</c>) to signal that no more data is + to be sent and then wait for the read side of the socket to be closed.</p> + </note> + </desc> + </func> + + <func> + <name name="connect" arity="2" since="OTP 22.0"/> + <name name="connect" arity="3" clause_i="2" since="OTP 22.0"/> + <fsummary>Initiate a connection on a socket.</fsummary> + <desc> + <p>This function connects the socket to the address + specied by the <c>SockAddr</c> argument.</p> + </desc> + </func> + + <func> + <name name="connect" arity="3" clause_i="1" anchor="connect_async" since="OTP @OTP-15731@"/> + <fsummary>Initiate a connection on a socket.</fsummary> + <desc> + <p>This function connects the socket to the address + specied by the <c>SockAddr</c> argument.</p> + + <p>In the case when its not possible to immediately establish a + connection, the function will return with the + <seealso marker="#type-select_info"><c>SelectInfo</c></seealso>. + The caller can then await a + select message, <c>{'$socket', Socket, select, Info}</c> (where + <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>, + a subsequent call to connect will then + establish the connection). </p> + </desc> + </func> + + <func> + <name name="getopt" arity="3" clause_i="1" since="OTP 22.0"/> + <name name="getopt" arity="3" clause_i="2" since="OTP 22.0"/> + <name name="getopt" arity="3" clause_i="3" since="OTP 22.0"/> + <name name="getopt" arity="3" clause_i="4" since="OTP 22.0"/> + <name name="getopt" arity="3" clause_i="5" since="OTP 22.0"/> + <name name="getopt" arity="3" clause_i="6" since="OTP 22.0"/> + <name name="getopt" arity="3" clause_i="7" since="OTP 22.0"/> + <fsummary>Get an option on a socket.</fsummary> + <desc> + <p>Get an option on a socket.</p> + <p>What properties are valid depend both on <c>Level</c> and + on what kind of socket it is (<c>domain</c>, <c>type</c> and + <c>protocol</c>).</p> + + <p>See the + <seealso marker="socket_usage#socket_options">socket options</seealso> + chapter of the users guide for more info. </p> + + <note><p>Not all options are valid on all platforms. That is, + even if "we" support an option, that does not mean that the + underlying OS does.</p></note> + + </desc> + </func> + + <func> + <name name="getopt" arity="3" clause_i="8" since="OTP 22.0"/> + <fsummary>Get an option on a socket.</fsummary> + <desc> + <p>Get an option on a socket.</p> + <p>What properties are valid depend both on <c>Level</c> and + on what kind of socket it is (<c>domain</c>, <c>type</c> and + <c>protocol</c>).</p> + <p>When specifying <c>Level</c> as an integer, and therefor + using "native mode", it is *currently* up to the caller to + know how to interpret the result.</p> + + <p>See the + <seealso marker="socket_usage#socket_options">socket options</seealso> + chapter of the users guide for more info. </p> + + <note><p>Not all options are valid on all platforms. That is, + even if "we" support an option, that does not mean that the + underlying OS does.</p></note> + </desc> + </func> + + <func> + <name name="listen" arity="1" since="OTP 22.0"/> + <name name="listen" arity="2" since="OTP 22.0"/> + <fsummary>Listen for connections on a socket.</fsummary> + <desc> + <p>Listen for connections on a socket.</p> + </desc> + </func> + + <func> + <name name="open" arity="2" since="OTP 22.0"/> + <name name="open" arity="3" since="OTP 22.0"/> + <name name="open" arity="4" since="OTP 22.0"/> + <fsummary>Create an endpoint for communication.</fsummary> + <desc> + <p>Creates an endpoint (socket) for communication.</p> + + <p>For some <c>types</c> there is a default protocol, + indicated by <c>default</c>, which it <em>may</em> be + possible to specify. + And for <c>Domain = local</c>, if a protocol <em>is</em> pecified, + it <em>must</em> be <c>default</c>. </p> + + <p>The <c>Extra</c> argument is intended for "obscure" options. + Currently the only supported option is <c>netns</c>, which + is only supported on the linux platform.</p> + + <note> + <p>It may not be possible to specify the default protocol (except + when <c>Domain = local</c>). We need to be able to retreive + the resulting protocol, which is <em>not</em> possble on all + platforms. </p> + </note> + </desc> + </func> + + <func> + <name name="peername" arity="1" since="OTP 22.0"/> + <fsummary>Get name of connected socket peer.</fsummary> + <desc> + <p>Returns the address of the peer connected to the socket.</p> + </desc> + </func> + + <func> + <name name="recv" arity="1" since="OTP 22.0"/> + <name name="recv" arity="2" since="OTP 22.0"/> + <name name="recv" arity="3" clause_i="1" since="OTP 22.0"/> + <name name="recv" arity="3" clause_i="3" since="OTP 22.0"/> + <name name="recv" arity="4" clause_i="2" since="OTP 22.0"/> + <fsummary>Receive a message from a socket.</fsummary> + <desc> + <p>Receive a message from a socket.</p> + <p>There is a special case for the argument <c>Length</c>. + If it is set to zero (0), it means "give me everything you + currently have".</p> + </desc> + </func> + + <func> + <name name="recv" arity="3" clause_i="2" anchor="recv_async" since="OTP @OTP-15731@"/> + <name name="recv" arity="4" clause_i="1" since="OTP @OTP-15731@"/> + <fsummary>Receive a message from a socket.</fsummary> + <desc> + <p>Receive a message from a socket.</p> + + <p>There is a special case for the argument <c>Length</c>. + If it is set to zero (0), it means "give me everything you + currently have".</p> + + <p>In the case when there is no data waiting, the function + will return with the <c>SelectInfo</c>. The caller can then await a + select message, <c>{'$socket', Socket, select, Info}</c> (where + <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>), + when data has arrived (a subsequent call to recv will then return + the data). </p> + <p>Note that if a length (<c>> 0</c>) is specified, and only part + of that amount of data is available, the function will return with + that data <em>and</em> the <c>SelectInfo</c> (if the caller don't + want to wait for the remaining data, it must immediately call + the <seealso marker="#cancel/2"><c>cancel/2</c></seealso> function.)</p> + </desc> + </func> + + <func> + <name name="recvfrom" arity="1" since="OTP 22.0"/> + <name name="recvfrom" arity="2" since="OTP 22.0"/> + <name name="recvfrom" arity="3" clause_i="2" since="OTP 22.0"/> + <name name="recvfrom" arity="3" clause_i="3" since="OTP 22.0"/> + <name name="recvfrom" arity="3" clause_i="5" since="OTP 22.0"/> + <name name="recvfrom" arity="4" clause_i="2" since="OTP 22.0"/> + <fsummary>Receive a message from a socket.</fsummary> + <desc> + <p>Receive a message from a socket.</p> + <p>This function reads "messages", which means that regardless of + how much we want to read, it returns when we get a message + (if the buffer size is to small, the message will be truncated).</p> + <p>The <c>BufSz</c> argument basically defines the size of the + receive buffer. By setting the value to zero (0), the configured + size (setopt with <c>Level</c> = <c>otp</c> and + <c>Key</c> = <c>rcvbuf</c>) is used.</p> + <p>It may be impossible to know what (buffer) size is appropriate + "in advance", and in those cases it may be convenient to use the + (recv) 'peek' flag. When this flag is provided, the message is *not* + "consumed" from the underlying buffers, so another recvfrom call + is needed, possibly with a then adjusted buffer size.</p> + </desc> + </func> + + <func> + <name name="recvfrom" arity="3" clause_i="1" anchor="recvfrom_async" since="OTP @OTP-15731@"/> + <name name="recvfrom" arity="3" clause_i="4" since="OTP @OTP-15731@"/> + <name name="recvfrom" arity="4" clause_i="1" since="OTP @OTP-15731@"/> + <fsummary>Receive a message from a socket.</fsummary> + <desc> + <p>Receive a message from a socket.</p> + <p>This function reads "messages", which means that regardless of + how much we want to read, it returns when we get a message + (if the buffer size is to small, the message will be truncated).</p> + <p>The <c>BufSz</c> argument basically defines the size of the + receive buffer. By setting the value to zero (0), the configured + size (setopt with <c>Level</c> = <c>otp</c> and + <c>Key</c> = <c>rcvbuf</c>) is used.</p> + <p>It may be impossible to know what (buffer) size is appropriate + "in advance", and in those cases it may be convenient to use the + (recv) 'peek' flag. When this flag is provided, the message is *not* + "consumed" from the underlying buffers, so another recvfrom call + is needed, possibly with a then adjusted buffer size.</p> + + <p>In the case when there is no data waiting, the function + will return with the <c>SelectInfo</c>. The caller can then await a + select message, <c>{'$socket', Socket, select, Info}</c> (where + <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>), + when data has arrived (a subsequent call to recvfrom will then return + the data). </p> + </desc> + </func> + + <func> + <name name="recvmsg" arity="1" since="OTP 22.0"/> + <name name="recvmsg" arity="2" clause_i="1" since="OTP 22.0"/> + <name name="recvmsg" arity="2" clause_i="3" since="OTP 22.0"/> + <name name="recvmsg" arity="3" clause_i="2" since="OTP 22.0"/> + <name name="recvmsg" arity="3" clause_i="3" since="OTP 22.0"/> + <name name="recvmsg" arity="5" clause_i="2" since="OTP 22.0"/> + <fsummary>Receive a message from a socket.</fsummary> + <desc> + <p>Receive a message from a socket.</p> + <p>This function reads "messages", which means that regardless of + how much we want to read, it returns when we get a message.</p> + <p>The message will be delivered in the form of a <c>msghdr()</c>, + which may contain the source address (if socket not connected), + a list of <c>cmsghdr_recv()</c> (depends on what socket options have + been set and what the protocol and platform supports) and + also a set of flags, providing further info about the read. </p> + + <p>The <c>BufSz</c> argument basically defines the size of the + receive buffer. By setting the value to zero (0), the configured + size (setopt with <c>Level</c> = <c>otp</c> and + <c>Key</c> = <c>rcvbuf</c>) is used.</p> + + <p>The <c>CtrlSz</c> argument basically defines the size of the + receive buffer for the control messages. + By setting the value to zero (0), the configured size (setopt + with <c>Level</c> = <c>otp</c>) is used.</p> + + <p>It may be impossible to know what (buffer) size is appropriate + "in advance", and in those cases it may be convenient to use the + (recv) 'peek' flag. When this flag is provided, the message is *not* + "consumed" from the underlying buffers, so another recvmsg call + is needed, possibly with a then adjusted buffer size.</p> + </desc> + </func> + + <func> + <name name="recvmsg" arity="2" clause_i="2" anchor="recvmsg_async" since="OTP @OTP-15731@"/> + <name name="recvmsg" arity="3" clause_i="1" since="OTP @OTP-15731@"/> + <name name="recvmsg" arity="5" clause_i="1" since="OTP @OTP-15731@"/> + <fsummary>Receive a message from a socket.</fsummary> + <desc> + <p>Receive a message from a socket.</p> + <p>This function reads "messages", which means that regardless of + how much we want to read, it returns when we get a message.</p> + <p>The message will be delivered in the form of a <c>msghdr()</c>, + which may contain the source address (if socket not connected), + a list of <c>cmsghdr_recv()</c> (depends on what socket options have + been set and what the protocol and platform supports) and + also a set of flags, providing further info about the read. </p> + + <p>The <c>BufSz</c> argument basically defines the size of the + receive buffer. By setting the value to zero (0), the configured + size (setopt with <c>Level</c> = <c>otp</c> and + <c>Key</c> = <c>rcvbuf</c>) is used.</p> + + <p>The <c>CtrlSz</c> argument basically defines the size of the + receive buffer for the control messages. + By setting the value to zero (0), the configured size (setopt + with <c>Level</c> = <c>otp</c>) is used.</p> + + <p>It may be impossible to know what (buffer) size is appropriate + "in advance", and in those cases it may be convenient to use the + (recv) 'peek' flag. When this flag is provided, the message is *not* + "consumed" from the underlying buffers, so another recvmsg call + is needed, possibly with a then adjusted buffer size.</p> + + <p>In the case when there is no data waiting, the function + will return with the <c>SelectInfo</c>. The caller can then await a + select message, <c>{'$socket', Socket, select, Info}</c> (where + <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>), + when data has arrived (a subsequent call to recvmsg will then return + the data). </p> + </desc> + </func> + + <func> + <name name="send" arity="2" since="OTP 22.0"/> + <name name="send" arity="3" clause_i="1" since="OTP 22.0"/> + <name name="send" arity="3" clause_i="3" since="OTP 22.0"/> + <name name="send" arity="4" clause_i="2" since="OTP 22.0"/> + <fsummary>Send a message on a socket.</fsummary> + <desc> + <p>Send a message on a connected socket.</p> + </desc> + </func> + + <func> + <name name="send" arity="3" clause_i="2" anchor="send_async" since="OTP @OTP-15731@"/> + <name name="send" arity="4" clause_i="1" since="OTP @OTP-15731@"/> + <fsummary>Send a message on a socket.</fsummary> + <desc> + <p>Send a message on a connected socket.</p> + + <p>In the case when there is no room in the (system-) buffers, + the function will return with the <c>SelectInfo</c>. The caller + can then await a select message, + <c>{'$socket', Socket, select, Info}</c> + (where <c>Info</c> is the <c>select_ref()</c> from the + <c>SelectInfo</c>), when there is room for more data (a subsequent + call to send will then send the data). </p> + <p>Note that if not all the data was sent, the function will return + with the remaining data <em>and</em> the <c>SelectInfo</c> + (if the caller don't + want to wait to be able to send the rest, it should immediately call + the <seealso marker="#cancel/2"><c>cancel/2</c></seealso> function.)</p> + </desc> + </func> + + <func> + <name name="sendmsg" arity="2" since="OTP 22.0"/> + <name name="sendmsg" arity="3" clause_i="1" since="OTP 22.0"/> + <name name="sendmsg" arity="3" clause_i="3" since="OTP 22.0"/> + <name name="sendmsg" arity="4" clause_i="2" since="OTP 22.0"/> + <fsummary>Send a message on a socket.</fsummary> + <desc> + <p>Send a message on a socket. The destination, if needed + (socket <em>not</em> connected) is provided in the <c>MsgHdr</c>, + which also contains the message to send, + The <c>MsgHdr</c> may also contain an list of optional <c>cmsghdr_send()</c> + (depends on what the protocol and platform supports).</p> + + <p>Unlike the <seealso marker="#send/2"><c>send</c></seealso> function, + this one sends <em>one message</em>. + This means that if, for whatever reason, its not possible to send the + message in one go, the function will instead return with the + <em>remaining</em> data (<c>{ok, Remaining}</c>). Thereby leaving it + up to the caller to decide what to do (retry with the remaining data + of give up). </p> + + </desc> + </func> + + <func> + <name name="sendmsg" arity="3" clause_i="2" anchor="sendmsg_async" since="OTP @OTP-15731@"/> + <name name="sendmsg" arity="4" clause_i="1" since="OTP @OTP-15731@"/> + <fsummary>Send a message on a socket.</fsummary> + <desc> + <p>Send a message on a socket. The destination, if needed + (socket <em>not</em> connected) is provided in the <c>MsgHdr</c>, + which also contains the message to send, + The <c>MsgHdr</c> may also contain an list of optional <c>cmsghdr_send()</c> + (depends on what the protocol and platform supports).</p> + + <p>Unlike the <seealso marker="#send/2"><c>send</c></seealso> function, + this one sends <em>one message</em>. + This means that if, for whatever reason, its not possible to send the + message in one go, the function will instead return with the + <em>remaining</em> data (<c>{ok, Remaining}</c>). Thereby leaving it + up to the caller to decide what to do (retry with the remaining data + of give up). </p> + + <p>In the case when there is no room in the (system-) buffers, + the function will return with the <c>SelectInfo</c>. The caller + can then await a select message, + <c>{'$socket', Socket, select, Info}</c> + (where <c>Info</c> is the <c>select_ref()</c> from the + <c>SelectInfo</c>), when there is room for more data (a subsequent + call to sendmsg will then send the data). </p> + </desc> + </func> + + <func> + <name name="sendto" arity="3" since="OTP 22.0"/> + <name name="sendto" arity="4" clause_i="1" since="OTP 22.0"/> + <name name="sendto" arity="4" clause_i="3" since="OTP 22.0"/> + <name name="sendto" arity="5" clause_i="2" since="OTP 22.0"/> + <fsummary>Send a message on a socket.</fsummary> + <desc> + <p>Send a message on a socket, to the specified destination.</p> + </desc> + </func> + + <func> + <name name="sendto" arity="4" clause_i="2" anchor="sendto_async" since="OTP @OTP-15731@"/> + <name name="sendto" arity="5" clause_i="1" since="OTP @OTP-15731@"/> + <fsummary>Send a message on a socket.</fsummary> + <desc> + <p>Send a message on a socket, to the specified destination.</p> + + <p>In the case when there is no room in the (system-) buffers, + the function will return with the <c>SelectInfo</c>. The caller + can then await a select message, + <c>{'$socket', Socket, select, Info}</c> + (where <c>Info</c> is the <c>select_ref()</c> from the + <c>SelectInfo</c>), when there is room for more data (a subsequent + call to sendto will then send the data). </p> + </desc> + </func> + + <func> + <name name="setopt" arity="4" clause_i="1" since="OTP 22.0"/> + <name name="setopt" arity="4" clause_i="2" since="OTP 22.0"/> + <name name="setopt" arity="4" clause_i="3" since="OTP 22.0"/> + <name name="setopt" arity="4" clause_i="4" since="OTP 22.0"/> + <name name="setopt" arity="4" clause_i="5" since="OTP 22.0"/> + <name name="setopt" arity="4" clause_i="6" since="OTP 22.0"/> + <name name="setopt" arity="4" clause_i="7" since="OTP 22.0"/> + <fsummary>Set options on a socket.</fsummary> + <desc> + <p>Set options on a socket.</p> + <p>What properties are valid depend both on <c>Level</c> and on + what kind of socket it is (<c>domain</c>, <c>type</c> and + <c>protocol</c>).</p> + + <p>See the + <seealso marker="socket_usage#socket_options">socket options</seealso> + chapter of the users guide for more info. </p> + + <note><p>Not all options are valid on all platforms. That is, + even if "we" support an option, that does not mean that the + underlying OS does.</p></note> + + <note><p>Sockets are set 'non-blocking' when created, so this option + is *not* available (as it would adversely effect the Erlang VM + to set a socket 'blocking').</p></note> + </desc> + </func> + + <func> + <name name="setopt" arity="4" clause_i="8" since="OTP 22.0"/> + <fsummary>Set options on a socket.</fsummary> + <desc> + <p>Set options on a socket.</p> + <p>What properties are valid depend both on <c>Level</c> and on + what kind of socket it is (<c>domain</c>, <c>type</c> and + <c>protocol</c>).</p> + + <p>See the + <seealso marker="socket_usage#socket_options">socket options</seealso> + chapter of the users guide for more info. </p> + + <note><p>Not all options are valid on all platforms. That is, + even if "we" support an option, that does not mean that the + underlying OS does.</p></note> + + <note><p>Sockets are set 'non-blocking' when created, so this option + is *not* available (as it would adversely effect the Erlang VM + to set a socket 'blocking').</p></note> + </desc> + </func> + + <func> + <name name="shutdown" arity="2" since="OTP 22.0"/> + <fsummary>Shut down part of a full-duplex connection.</fsummary> + <desc> + <p>Shut down all or part of a full-duplex connection.</p> + </desc> + </func> + + <func> + <name name="sockname" arity="1" since="OTP 22.0"/> + <fsummary>Get socket name.</fsummary> + <desc> + <p>Returns the current address to which the socket is bound.</p> + </desc> + </func> + + <func> + <name name="supports" arity="0" since="OTP 22.0"/> + <name name="supports" arity="1" clause_i="1" since="OTP 22.0"/> + <name name="supports" arity="1" clause_i="2" since="OTP 22.0"/> + <name name="supports" arity="1" clause_i="3" since="OTP 22.0"/> + <name name="supports" arity="1" clause_i="4" since="OTP 22.0"/> + <name name="supports" arity="2" clause_i="1" since="OTP 22.0"/> + <name name="supports" arity="2" clause_i="2" since="OTP 22.0"/> + <name name="supports" arity="2" clause_i="3" since="OTP 22.0"/> + <name name="supports" arity="2" clause_i="4" since="OTP 22.0"/> + <name name="supports" arity="2" clause_i="5" since="OTP 22.0"/> + <name name="supports" arity="2" clause_i="6" since="OTP 22.0"/> + <name name="supports" arity="2" clause_i="7" since="OTP 22.0"/> + <name name="supports" arity="3" clause_i="1" since="OTP 22.0"/> + <name name="supports" arity="3" clause_i="2" since="OTP 22.0"/> + <name name="supports" arity="3" clause_i="3" since="OTP 22.0"/> + <name name="supports" arity="3" clause_i="4" since="OTP 22.0"/> + <name name="supports" arity="3" clause_i="5" since="OTP 22.0"/> + <name name="supports" arity="3" clause_i="6" since="OTP 22.0"/> + <name name="supports" arity="3" clause_i="7" since="OTP 22.0"/> + <fsummary>Report info about what the platform supports.</fsummary> + <desc> + <p>This function intends to retreive information about what the + platform supports. Such as if SCTP is supported. Or which socket + options are supported. </p> + </desc> + </func> + + </funcs> + <section> + <title>Examples</title> + <marker id="examples"></marker> + <code type="none"> +client(Addr, SAddr, SPort) -> + {ok, Sock} = socket:open(inet, stream, tcp), + {ok, _} = socket:bind(Sock, #{family => inet, + addr => Addr}), + ok = socket:connect(Sock, #{family => inet, + addr => SAddr, + port => SPort}), + Msg = list_to_binary("hello"), + ok = socket:send(Sock, Msg), + ok = socket:shutdown(Sock, write), + {ok, Msg} = socket:recv(Sock), + ok = socket:close(Sock). + +server(Addr, Port) -> + {ok, LSock} = socket:open(inet, stream, tcp), + {ok, _} = socket:bind(LSock, #{family => inet, + port => Port, + addr => Addr}), + ok = socket:listen(LSock), + {ok, Sock} = socket:accept(LSock), + {ok, Msg} = socket:recv(Sock), + ok = socket:send(Sock, Msg), + ok = socket:shutdown(Sock, write), + ok = socket:close(Sock), + ok = socket:close(LSock). + </code> + </section> +</erlref> + diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml new file mode 100644 index 0000000000..7e65bcbf70 --- /dev/null +++ b/erts/doc/src/socket_usage.xml @@ -0,0 +1,846 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2018</year><year>2019</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>Socket Usage</title> + <prepared>Micael Karlberg</prepared> + <docno></docno> + <date>2018-07-17</date> + <rev>PA1</rev> + <file>socket_usage.xml</file> + </header> + + <section> + <title>Introduction</title> + <p>The socket interface (module) is basically an "thin" layer on top of + the OS socket interface. It is assumed that, unless you have special needs, + gen_[tcp|udp|sctp] should be sufficent (when they become available). </p> + <p>Note that just because we have a documented and described option, + it does <em>not</em> mean that the OS supports it. So its recommended + that the user reads the platform specific documentation for the + option used. </p> + <section> + <title>Asynchronous calls</title> + <p>Some functions allow for an <i>asynchronous</i> call + (<seealso marker="socket#accept_async"><c>accept/2</c></seealso>, + <seealso marker="socket#connect_async"><c>connect/3</c></seealso>, + <seealso marker="socket#recv_async"><c>recv/3,4</c></seealso>, + <seealso marker="socket#recvfrom_async"><c>recvfrom/3,4</c></seealso>, + <seealso marker="socket#recvmsg_async"><c>recvmsg/2,3,5</c></seealso>, + <seealso marker="socket#send_async"><c>send/3,4</c></seealso>, + <seealso marker="socket#sendmsg_async"><c>sendmsg/3,4</c></seealso> and + <seealso marker="socket#sendto_async"><c>sendto/4,5</c></seealso>). + This is achieved by setting the <c>Timeout</c> argument to + <c>nowait</c>. For instance, if calling the + <seealso marker="socket#recv_async"><c>recv/3</c></seealso> + function with Timeout set to <c>nowait</c> (i.e. + <c>recv(Sock, 0, nowait)</c>) + when there is actually nothing to read, it will return with + <c>{ok, </c> + <seealso marker="socket#type-select_info"><c>SelectInfo</c></seealso><c>}</c>. + When data eventually arrives a 'select message' + will be sent to the caller:</p> + <taglist> + <!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL --> + <tag></tag> + <item><c>{'$socket', socket(), select, select_ref()}</c></item> + </taglist> + <p>The caller can then make another + call to the recv function and now expect data.</p> + <p>The user must also be prepared to receive an abort message: </p> + <!-- + <list type="ordered"> + <item><c>{'$socket', Sock, abort, Info}</c></item> + </list> + --> + <taglist> + <!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL --> + <tag></tag> + <item><c>{'$socket', socket(), abort, Info}</c></item> + </taglist> + <p>If the operation is aborted + for whatever reason (e.g. if the socket is closed "by someone else"). + The <c>Info</c> part contains the abort reason (in this case that + the socket has been closed <c>Info = {select_ref(), closed}</c>). </p> + <p>Note that all other users are <em>locked out</em> until the + 'current user' has called the function (recv in this case). So either + immediately call the function or + <seealso marker="socket#cancel/2"><c>cancel</c></seealso>. </p> + + <p>The general form of the 'socket' message is: </p> + <taglist> + <!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL --> + <tag></tag> + <item><c>{'$socket', Sock :: socket(), Tag :: atom(), Info :: term()}</c></item> + </taglist> + <p>Where the format of <c>Info</c> is a function of <c>Tag</c>:</p> + <table> + <row> + <cell><em>Tag</em></cell> + <cell><em>Info value type</em></cell> + </row> + <row> + <cell>select</cell> + <cell>select_ref()</cell> + </row> + <row> + <cell>abort</cell> + <cell>{select_ref(), Reason :: term()}</cell> + </row> + <tcaption>socket message info value type</tcaption> + </table> + <p>The <c>select_ref()</c> is the same as was received in the + <seealso marker="socket#type-select_info"><c>SelectInfo</c></seealso>. </p> + </section> + </section> + + <section> + <marker id="socket_options"></marker> + <title>Socket Options</title> + + <p>Options for level <c>otp</c>: </p> + <table> + <row> + <cell><em>Option Name</em></cell> + <cell><em>Value Type</em></cell> + <cell><em>Set</em></cell> + <cell><em>Get</em></cell> + <cell><em>Other Requirements and comments</em></cell> + </row> + <row> + <cell>assoc_id</cell> + <cell>integer()</cell> + <cell>no</cell> + <cell>yes</cell> + <cell>type = seqpacket, protocol = sctp, is an association</cell> + </row> + <row> + <cell>debug</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>iow</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>controlling_process</cell> + <cell>pid()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>rcvbuf</cell> + <cell>default | pos_integer() | {pos_integer(), pos_ineteger()}</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>'default' only valid for set. + The tuple form is only valid for type 'stream' and protocol 'tcp'.</cell> + </row> + <row> + <cell>rcvctrlbuf</cell> + <cell>default | pos_integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>default only valid for set</cell> + </row> + <row> + <cell>sndctrlbuf</cell> + <cell>default | pos_integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>default only valid for set</cell> + </row> + <row> + <cell>fd</cell> + <cell>integer()</cell> + <cell>no</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <tcaption>option levels</tcaption> + </table> + + <p>Options for level <c>socket</c>: </p> + <table> + <row> + <cell><em>Option Name</em></cell> + <cell><em>Value Type</em></cell> + <cell><em>Set</em></cell> + <cell><em>Get</em></cell> + <cell><em>Other Requirements and comments</em></cell> + </row> + <row> + <cell>acceptcon</cell> + <cell>boolean()</cell> + <cell>no</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>bindtodevice</cell> + <cell>string()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>broadcast</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = dgram</cell> + </row> + <row> + <cell>debug</cell> + <cell>integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>requires admin capability</cell> + </row> + <row> + <cell>domain</cell> + <cell>domain()</cell> + <cell>no</cell> + <cell>yes</cell> + <cell><em>Not</em> on FreeBSD (for instance)</cell> + </row> + <row> + <cell>dontroute</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>keepalive</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>linger</cell> + <cell>abort | linger()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>oobinline</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>peek_off</cell> + <cell>integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>domain = local (unix)</cell> + </row> + <row> + <cell>priority</cell> + <cell>integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>protocol</cell> + <cell>protocol()</cell> + <cell>no</cell> + <cell>yes</cell> + <cell><em>Not</em> on (some) Darwin (for instance)</cell> + </row> + <row> + <cell>rcvbuf</cell> + <cell>non_neg_integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>rcvlowat</cell> + <cell>non_neg_integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>rcvtimeo</cell> + <cell>timeval()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>reuseaddr</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>reuseport</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>domain = inet | inet6</cell> + </row> + <row> + <cell>sndbuf</cell> + <cell>non_neg_integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>sndlowat</cell> + <cell>non_neg_integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>not changeable on Linux</cell> + </row> + <row> + <cell>sndtimeo</cell> + <cell>timeval()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>timestamp</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>type</cell> + <cell>type()</cell> + <cell>no</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <tcaption>socket options</tcaption> + </table> + + <p>Options for level <c>ip</c>: </p> + <table> + <row> + <cell><em>Option Name</em></cell> + <cell><em>Value Type</em></cell> + <cell><em>Set</em></cell> + <cell><em>Get</em></cell> + <cell><em>Other Requirements and comments</em></cell> + </row> + <row> + <cell>add_membership</cell> + <cell>ip_mreq()</cell> + <cell>yes</cell> + <cell>no</cell> + <cell>none</cell> + </row> + <row> + <cell>add_source_membership</cell> + <cell>ip_mreq_source()</cell> + <cell>yes</cell> + <cell>no</cell> + <cell>none</cell> + </row> + <row> + <cell>block_source</cell> + <cell>ip_mreq_source()</cell> + <cell>yes</cell> + <cell>no</cell> + <cell>none</cell> + </row> + <row> + <cell>drop_membership</cell> + <cell>ip_mreq()</cell> + <cell>yes</cell> + <cell>no</cell> + <cell>none</cell> + </row> + <row> + <cell>drop_source_membership</cell> + <cell>ip_mreq_source()</cell> + <cell>yes</cell> + <cell>no</cell> + <cell>none</cell> + </row> + <row> + <cell>freebind</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>hdrincl</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = raw</cell> + </row> + <row> + <cell>minttl</cell> + <cell>integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = raw</cell> + </row> + <row> + <cell>msfilter</cell> + <cell>null | ip_msfilter()</cell> + <cell>yes</cell> + <cell>no</cell> + <cell>none</cell> + </row> + <row> + <cell>mtu</cell> + <cell>integer()</cell> + <cell>no</cell> + <cell>yes</cell> + <cell>type = raw</cell> + </row> + <row> + <cell>mtu_discover</cell> + <cell>ip_pmtudisc()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>multicast_all</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>multicast_if</cell> + <cell>any | ip4_address()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>multicast_loop</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>multicast_ttl</cell> + <cell>uint8()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>nodefrag</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = raw</cell> + </row> + <row> + <cell>pktinfo</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = dgram</cell> + </row> + <row> + <cell>recvdstaddr</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = dgram</cell> + </row> + <row> + <cell>recverr</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>recvif</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = dgram | raw</cell> + </row> + <row> + <cell>recvopts</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type =/= stream</cell> + </row> + <row> + <cell>recvorigdstaddr</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>recvttl</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type =/= stream</cell> + </row> + <row> + <cell>retopts</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type =/= stream</cell> + </row> + <row> + <cell>router_alert</cell> + <cell>integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = raw</cell> + </row> + <row> + <cell>sendsrcaddr</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>tos</cell> + <cell>ip_tos()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>some high-priority levels may require superuser capability</cell> + </row> + <row> + <cell>transparent</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>requires admin capability</cell> + </row> + <row> + <cell>ttl</cell> + <cell>integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>unblock_source</cell> + <cell>ip_mreq_source()</cell> + <cell>yes</cell> + <cell>no</cell> + <cell>none</cell> + </row> + <tcaption>ip options</tcaption> + </table> + + <p>Options for level <c>ipv6</c>: </p> + <table> + <row> + <cell><em>Option Name</em></cell> + <cell><em>Value Type</em></cell> + <cell><em>Set</em></cell> + <cell><em>Get</em></cell> + <cell><em>Other Requirements and comments</em></cell> + </row> + <row> + <cell>addrform</cell> + <cell>inet</cell> + <cell>yes</cell> + <cell>no</cell> + <cell>allowed only for IPv6 sockets that are connected and bound to a + v4-mapped-on-v6 address</cell> + </row> + <row> + <cell>add_membership</cell> + <cell>ipv6_mreq()</cell> + <cell>yes</cell> + <cell>no</cell> + <cell>none</cell> + </row> + <row> + <cell>authhdr</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = dgram | raw, obsolete?</cell> + </row> + <row> + <cell>drop_membership</cell> + <cell>ipv6_mreq()</cell> + <cell>yes</cell> + <cell>no</cell> + <cell>none</cell> + </row> + <row> + <cell>dstopts</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = dgram | raw, requires superuser privileges to update</cell> + </row> + <row> + <cell>flowinfo</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = dgram | raw, requires superuser privileges to update</cell> + </row> + <row> + <cell>hoplimit</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = dgram | raw, requires superuser privileges to update</cell> + </row> + <row> + <cell>hopopts</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = dgram | raw, requires superuser privileges to update</cell> + </row> + <row> + <cell>mtu</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>Get: Only after the socket has been connected</cell> + </row> + <row> + <cell>mtu_discover</cell> + <cell>ipv6_pmtudisc()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>multicast_hops</cell> + <cell>default | uint8()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>multicast_if</cell> + <cell>integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = dgram | raw</cell> + </row> + <row> + <cell>multicast_loop</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>recverr</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>recvpktinfo | pktinfo</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = dgram | raw</cell> + </row> + <row> + <cell>router_alert</cell> + <cell>integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = raw</cell> + </row> + <row> + <cell>rthdr</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type = dgram | raw, requires superuser privileges to update</cell> + </row> + <row> + <cell>unicast_hops</cell> + <cell>default | uint8()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>v6only</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>no</cell> + <cell>none</cell> + </row> + <tcaption>ipv6 options</tcaption> + </table> + + <p>Options for level <c>tcp</c>: </p> + <table> + <row> + <cell><em>Option Name</em></cell> + <cell><em>Value Type</em></cell> + <cell><em>Set</em></cell> + <cell><em>Get</em></cell> + <cell><em>Other Requirements and comments</em></cell> + </row> + <row> + <cell>congestion</cell> + <cell>string()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>maxseg</cell> + <cell>integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>nodelay</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <tcaption>tcp options</tcaption> + </table> + + <p>Options for level <c>udp</c>: </p> + <table> + <row> + <cell><em>Option Name</em></cell> + <cell><em>Value Type</em></cell> + <cell><em>Set</em></cell> + <cell><em>Get</em></cell> + <cell><em>Other Requirements and comments</em></cell> + </row> + <row> + <cell>cork</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <tcaption>udp options</tcaption> + </table> + + <p>Options for level <c>sctp</c>: </p> + <table> + <row> + <cell><em>Option Name</em></cell> + <cell><em>Value Type</em></cell> + <cell><em>Set</em></cell> + <cell><em>Get</em></cell> + <cell><em>Other Requirements and comments</em></cell> + </row> + <row> + <cell>associnfo</cell> + <cell>sctp_assocparams()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>autoclose</cell> + <cell>non_neg_integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>disable_fragments</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>events</cell> + <cell>sctp_event_subscribe()</cell> + <cell>yes</cell> + <cell>no</cell> + <cell>none</cell> + </row> + <row> + <cell>initmsg</cell> + <cell>sctp_initmsg()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>maxseg</cell> + <cell>non_neg_integer()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>nodelay</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <row> + <cell>rtoinfo</cell> + <cell>sctp_rtoinfo()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>none</cell> + </row> + <tcaption>sctp options</tcaption> + </table> + + </section> +</chapter> + diff --git a/erts/doc/src/specs.xml b/erts/doc/src/specs.xml index ed6be650e5..68fab5edf1 100644 --- a/erts/doc/src/specs.xml +++ b/erts/doc/src/specs.xml @@ -4,5 +4,10 @@ <xi:include href="../specs/specs_erlang.xml"/> <xi:include href="../specs/specs_erl_tracer.xml"/> <xi:include href="../specs/specs_init.xml"/> + <xi:include href="../specs/specs_persistent_term.xml"/> + <xi:include href="../specs/specs_socket.xml"/> + <xi:include href="../specs/specs_net.xml"/> <xi:include href="../specs/specs_zlib.xml"/> + <xi:include href="../specs/specs_atomics.xml"/> + <xi:include href="../specs/specs_counters.xml"/> </specs> diff --git a/erts/doc/src/time_correction.xml b/erts/doc/src/time_correction.xml index 77e7a40529..a9f06d8a7d 100644 --- a/erts/doc/src/time_correction.xml +++ b/erts/doc/src/time_correction.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1999</year><year>2016</year> + <year>1999</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -940,7 +940,7 @@ EventTag = {Time, UMI}</code> </item> <item> <seealso marker="erlang#system_info_os_system_time_source"> - <c>erlang:system_info(os_system_time_source)</c></seealso>) + <c>erlang:system_info(os_system_time_source)</c></seealso> </item> </list> diff --git a/erts/doc/src/tty.xml b/erts/doc/src/tty.xml index 51db1ba8e2..c33e082f4f 100644 --- a/erts/doc/src/tty.xml +++ b/erts/doc/src/tty.xml @@ -165,6 +165,10 @@ erl</pre> <cell align="left" valign="middle">C-y</cell> <cell align="left" valign="middle">Insert previously killed text</cell> </row> + <row> + <cell align="left" valign="middle">C-]</cell> + <cell align="left" valign="middle">Insert matching closing bracket</cell> + </row> <tcaption>tty Text Editing</tcaption> </table> </section> diff --git a/erts/doc/src/zlib.xml b/erts/doc/src/zlib.xml index 6f4c42da27..8a580c8d7b 100644 --- a/erts/doc/src/zlib.xml +++ b/erts/doc/src/zlib.xml @@ -29,7 +29,7 @@ <rev></rev> <file>zlib.xml</file> </header> - <module>zlib</module> + <module since="">zlib</module> <modulesummary>zlib compression interface.</modulesummary> <description> <p>This module provides an API for the zlib library @@ -120,7 +120,7 @@ list_to_binary([Compressed|Last])</pre> <funcs> <func> - <name name="adler32" arity="2"/> + <name name="adler32" arity="2" since=""/> <fsummary>Calculate the Adler checksum.</fsummary> <desc> <p>Calculates the Adler-32 checksum for <c><anno>Data</anno></c>.</p> @@ -133,7 +133,7 @@ list_to_binary([Compressed|Last])</pre> </func> <func> - <name name="adler32" arity="3"/> + <name name="adler32" arity="3" since=""/> <fsummary>Calculate the Adler checksum.</fsummary> <desc> <p>Updates a running Adler-32 checksum for <c><anno>Data</anno></c>. @@ -153,7 +153,7 @@ Crc = lists:foldl(fun(Data,Crc0) -> </func> <func> - <name name="adler32_combine" arity="4"/> + <name name="adler32_combine" arity="4" since=""/> <fsummary>Combine two Adler-32 checksums.</fsummary> <desc> <p>Combines two Adler-32 checksums into one. For two binaries or @@ -172,7 +172,7 @@ Crc = lists:foldl(fun(Data,Crc0) -> </func> <func> - <name name="close" arity="1"/> + <name name="close" arity="1" since=""/> <fsummary>Close a stream.</fsummary> <desc> <p>Closes the stream referenced by <c><anno>Z</anno></c>.</p> @@ -180,7 +180,7 @@ Crc = lists:foldl(fun(Data,Crc0) -> </func> <func> - <name name="compress" arity="1"/> + <name name="compress" arity="1" since=""/> <fsummary>Compress data with standard zlib functionality.</fsummary> <desc> <p>Compresses data with zlib headers and checksum.</p> @@ -188,7 +188,7 @@ Crc = lists:foldl(fun(Data,Crc0) -> </func> <func> - <name name="crc32" arity="1"/> + <name name="crc32" arity="1" since=""/> <fsummary>Get current CRC.</fsummary> <desc> <p>Gets the current calculated CRC checksum.</p> @@ -202,7 +202,7 @@ Crc = lists:foldl(fun(Data,Crc0) -> </func> <func> - <name name="crc32" arity="2"/> + <name name="crc32" arity="2" since=""/> <fsummary>Calculate CRC.</fsummary> <desc> <p>Calculates the CRC checksum for <c><anno>Data</anno></c>.</p> @@ -215,7 +215,7 @@ Crc = lists:foldl(fun(Data,Crc0) -> </func> <func> - <name name="crc32" arity="3"/> + <name name="crc32" arity="3" since=""/> <fsummary>Calculate CRC.</fsummary> <desc> <p>Updates a running CRC checksum for <c><anno>Data</anno></c>. @@ -235,7 +235,7 @@ Crc = lists:foldl(fun(Data,Crc0) -> </func> <func> - <name name="crc32_combine" arity="4"/> + <name name="crc32_combine" arity="4" since=""/> <fsummary>Combine two CRCs.</fsummary> <desc> <p>Combines two CRC checksums into one. For two binaries or iolists, @@ -254,7 +254,7 @@ Crc = lists:foldl(fun(Data,Crc0) -> </func> <func> - <name name="deflate" arity="2"/> + <name name="deflate" arity="2" since=""/> <fsummary>Compress data.</fsummary> <desc> <p>Same as <c>deflate(<anno>Z</anno>, <anno>Data</anno>, none)</c>.</p> @@ -262,7 +262,7 @@ Crc = lists:foldl(fun(Data,Crc0) -> </func> <func> - <name name="deflate" arity="3"/> + <name name="deflate" arity="3" since=""/> <fsummary>Compress data.</fsummary> <desc> <p>Compresses as much data as possible, and @@ -300,7 +300,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="deflateEnd" arity="1"/> + <name name="deflateEnd" arity="1" since=""/> <fsummary>End deflate session.</fsummary> <desc> <p>Ends the deflate session and cleans all data used. Notice that this @@ -311,7 +311,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="deflateInit" arity="1"/> + <name name="deflateInit" arity="1" since=""/> <fsummary>Initialize a session for compression.</fsummary> <desc> <p>Same as <c>zlib:deflateInit(<anno>Z</anno>, default)</c>.</p> @@ -319,7 +319,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="deflateInit" arity="2"/> + <name name="deflateInit" arity="2" since=""/> <fsummary>Initialize a session for compression.</fsummary> <desc> <p>Initializes a zlib stream for compression.</p> @@ -334,7 +334,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="deflateInit" arity="6"/> + <name name="deflateInit" arity="6" since=""/> <fsummary>Initialize a session for compression.</fsummary> <desc> <p>Initiates a zlib stream for compression.</p> @@ -410,8 +410,8 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="deflateParams" arity="3"/> - <fsummary>Dynamicly update deflate parameters.</fsummary> + <name name="deflateParams" arity="3" since=""/> + <fsummary>Dynamically update deflate parameters.</fsummary> <desc> <p>Dynamically updates the compression level and compression strategy. The interpretation of <c><anno>Level</anno></c> and @@ -432,7 +432,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="deflateReset" arity="1"/> + <name name="deflateReset" arity="1" since=""/> <fsummary>Reset the deflate session.</fsummary> <desc> <p>Equivalent to @@ -446,7 +446,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="deflateSetDictionary" arity="2"/> + <name name="deflateSetDictionary" arity="2" since=""/> <fsummary>Initialize the compression dictionary.</fsummary> <desc> <p>Initializes the compression dictionary from the specified byte @@ -464,7 +464,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="getBufSize" arity="1"/> + <name name="getBufSize" arity="1" since=""/> <fsummary>Get buffer size.</fsummary> <desc> <p>Gets the size of the intermediate buffer.</p> @@ -476,7 +476,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="gunzip" arity="1"/> + <name name="gunzip" arity="1" since=""/> <fsummary>Uncompress data with gz header.</fsummary> <desc> <p>Uncompresses data with gz headers and checksum.</p> @@ -484,7 +484,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="gzip" arity="1"/> + <name name="gzip" arity="1" since=""/> <fsummary>Compress data with gz header.</fsummary> <desc> <p>Compresses data with gz headers and checksum.</p> @@ -492,7 +492,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="inflate" arity="2"/> + <name name="inflate" arity="2" since=""/> <fsummary>Decompress data.</fsummary> <desc> <p>Equivalent to @@ -502,7 +502,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="inflate" arity="3"/> + <name name="inflate" arity="3" since="OTP 20.1"/> <fsummary>Decompress data.</fsummary> <desc> <p>Decompresses as much data as possible. It can introduce some output @@ -524,7 +524,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="inflateChunk" arity="1"/> + <name name="inflateChunk" arity="1" since="OTP 18.0"/> <fsummary>Read next uncompressed chunk.</fsummary> <desc> <warning> @@ -540,7 +540,7 @@ list_to_binary([B1,B2])</pre> </func> <func> - <name name="inflateChunk" arity="2"/> + <name name="inflateChunk" arity="2" since="OTP 18.0"/> <fsummary>Decompress data with limited output size.</fsummary> <desc> <warning> @@ -584,7 +584,7 @@ loop(Z, Handler, Uncompressed) -> </func> <func> - <name name="inflateEnd" arity="1"/> + <name name="inflateEnd" arity="1" since=""/> <fsummary>End inflate session.</fsummary> <desc> <p>Ends the inflate session and cleans all data used. Notice @@ -595,7 +595,7 @@ loop(Z, Handler, Uncompressed) -> </func> <func> - <name name="inflateGetDictionary" arity="1"/> + <name name="inflateGetDictionary" arity="1" since="OTP 20.0"/> <fsummary>Return the decompression dictionary.</fsummary> <desc> <p>Returns the decompression dictionary currently in use @@ -607,7 +607,7 @@ loop(Z, Handler, Uncompressed) -> </func> <func> - <name name="inflateInit" arity="1"/> + <name name="inflateInit" arity="1" since=""/> <fsummary>Initialize a session for decompression.</fsummary> <desc> <p>Initializes a zlib stream for decompression.</p> @@ -615,7 +615,7 @@ loop(Z, Handler, Uncompressed) -> </func> <func> - <name name="inflateInit" arity="2"/> + <name name="inflateInit" arity="2" since=""/> <fsummary>Initialize a session for decompression.</fsummary> <desc> <p>Initializes a decompression session on zlib stream.</p> @@ -634,7 +634,7 @@ loop(Z, Handler, Uncompressed) -> </func> <func> - <name name="inflateReset" arity="1"/> + <name name="inflateReset" arity="1" since=""/> <fsummary>>Reset the inflate session.</fsummary> <desc> <p>Equivalent to @@ -648,7 +648,7 @@ loop(Z, Handler, Uncompressed) -> </func> <func> - <name name="inflateSetDictionary" arity="2"/> + <name name="inflateSetDictionary" arity="2" since=""/> <fsummary>Initialize the decompression dictionary.</fsummary> <desc> <p>Initializes the decompression dictionary from the specified @@ -688,7 +688,7 @@ new_unpack(Z, Compressed, Dict) -> </func> <func> - <name name="open" arity="0"/> + <name name="open" arity="0" since=""/> <fsummary>Open a stream and return a stream reference.</fsummary> <desc> <p>Opens a zlib stream.</p> @@ -696,7 +696,7 @@ new_unpack(Z, Compressed, Dict) -> </func> <func> - <name name="safeInflate" arity="2"/> + <name name="safeInflate" arity="2" since="OTP 20.1"/> <fsummary>Decompress data with limited output size.</fsummary> <desc> <p>Like <seealso marker="#inflate/2"><c>inflate/2</c></seealso>, @@ -733,7 +733,7 @@ loop(Z, Handler, {finished, Output}) -> </func> <func> - <name name="setBufSize" arity="2"/> + <name name="setBufSize" arity="2" since=""/> <fsummary>Set buffer size.</fsummary> <desc> <p>Sets the intermediate buffer size.</p> @@ -745,7 +745,7 @@ loop(Z, Handler, {finished, Output}) -> </func> <func> - <name name="set_controlling_process" arity="2"/> + <name name="set_controlling_process" arity="2" since="OTP 20.1.3"/> <fsummary>Transfers ownership of a zlib stream.</fsummary> <desc> <p>Changes the controlling process of <c><anno>Z</anno></c> to @@ -754,7 +754,7 @@ loop(Z, Handler, {finished, Output}) -> </func> <func> - <name name="uncompress" arity="1"/> + <name name="uncompress" arity="1" since=""/> <fsummary>Uncompress data with standard zlib functionality.</fsummary> <desc> <p>Uncompresses data with zlib headers and checksum.</p> @@ -762,7 +762,7 @@ loop(Z, Handler, {finished, Output}) -> </func> <func> - <name name="unzip" arity="1"/> + <name name="unzip" arity="1" since=""/> <fsummary>Uncompress data without the zlib headers.</fsummary> <desc> <p>Uncompresses data without zlib headers and checksum.</p> @@ -770,7 +770,7 @@ loop(Z, Handler, {finished, Output}) -> </func> <func> - <name name="zip" arity="1"/> + <name name="zip" arity="1" since=""/> <fsummary>Compress data without the zlib headers.</fsummary> <desc> <p>Compresses data without zlib headers and checksum.</p> |