.TH proc_lib 3erl "stdlib 4.2" "Ericsson AB" "Erlang Module Definition"
.SH NAME
proc_lib \- Functions for asynchronous and synchronous start of processes
    adhering to the OTP design principles.
.SH DESCRIPTION
.LP
This module is used to start processes adhering to the  OTP Design Principles\&. Specifically, the functions in this module are used by the OTP standard behaviors (for example, \fIgen_server\fR\& and \fIgen_statem\fR\&) when starting new processes\&. The functions can also be used to start \fIspecial processes\fR\&, user-defined processes that comply to the OTP design principles\&. For an example, see section  sys and proc_lib in OTP Design Principles\&.
.LP
Some useful information is initialized when a process starts\&. The registered names, or the process identifiers, of the parent process, and the parent ancestors, are stored together with information about the function initially called in the process\&.
.LP
While in "plain Erlang", a process is said to terminate normally only for exit reason \fInormal\fR\&, a process started using \fIproc_lib\fR\& is also said to terminate normally if it exits with reason \fIshutdown\fR\& or \fI{shutdown,Term}\fR\&\&. \fIshutdown\fR\& is the reason used when an application (supervision tree) is stopped\&.
.LP
When a process that is started using \fIproc_lib\fR\& terminates abnormally (that is, with another exit reason than \fInormal\fR\&, \fIshutdown\fR\&, or \fI{shutdown,Term}\fR\&), a \fIcrash report\fR\& is generated, which is written to terminal by the default logger handler setup by Kernel\&. For more information about how crash reports were logged prior to Erlang/OTP 21\&.0, see SASL Error Logging in the SASL User\&'s Guide\&.
.LP
Unlike in "plain Erlang", \fIproc_lib\fR\& processes will not generate \fIerror reports\fR\&, which are written to the terminal by the emulator\&. All exceptions are converted to \fIexits\fR\& which are ignored by the default \fIlogger\fR\& handler\&.
.LP
The crash report contains the previously stored information, such as ancestors and initial function, the termination reason, and information about other processes that terminate as a result of this process terminating\&.
.SH DATA TYPES
.nf

\fBspawn_option()\fR\& = erlang:spawn_opt_option()
.br
.fi
.RS
.LP
See \fIerlang:spawn_opt/2,3,4,5\fR\&\&.
.RE

.nf

\fBstart_spawn_option()\fR\& = 
.br
    link |
.br
    {priority, erlang:priority_level()} |
.br
    {fullsweep_after, integer() >= 0} |
.br
    {min_heap_size, integer() >= 0} |
.br
    {min_bin_vheap_size, integer() >= 0} |
.br
    {max_heap_size, erlang:max_heap_size()} |
.br
    {message_queue_data, erlang:message_queue_data()}
.br
.fi
.RS
.LP
A restricted set of spawn options\&. Most notably \fImonitor\fR\& is \fInot\fR\& part of these options\&.
.RE

.nf

\fBdict_or_pid()\fR\& = 
.br
    pid() |
.br
    (ProcInfo :: [term()]) |
.br
    {X :: integer(), Y :: integer(), Z :: integer()}
.br
.fi
.SH EXPORTS
.LP
.nf

.B
format(CrashReport) -> string()
.br
.fi
.br
.RS
.LP
Types:

.RS 3
CrashReport = [term()]
.br
.RE
.RE
.RS
.LP
Equivalent to \fIformat(CrashReport, latin1)\fR\&\&.
.RE

.LP
.nf

.B
format(CrashReport, Encoding) -> string()
.br
.fi
.br
.RS
.LP
Types:

.RS 3
CrashReport = [term()]
.br
Encoding = latin1 | unicode | utf8
.br
.RE
.RE
.RS
.LP

.RS -4
.B
Note:
.RE
This function is deprecated in the sense that the \fIerror_logger\fR\& is no longer the preferred interface for logging in Erlang/OTP\&. A new logging API was added in Erlang/OTP 21\&.0, but legacy \fIerror_logger\fR\& handlers can still be used\&. New Logger handlers do not need to use this function, since the formatting callback (\fIreport_cb\fR\&) is included as metadata in the log event\&.

.LP
This function can be used by a user-defined legacy \fIerror_logger\fR\& event handler to format a crash report\&. The crash report is sent using \fIlogger(3erl)\fR\&, and the event to be handled is of the format \fI{error_report, GL, {Pid, crash_report, CrashReport}}\fR\&, where \fIGL\fR\& is the group leader pid of process \fIPid\fR\& that sent the crash report\&.
.RE

.LP
.nf

.B
format(CrashReport, Encoding, Depth) -> string()
.br
.fi
.br
.RS
.LP
Types:

.RS 3
CrashReport = [term()]
.br
Encoding = latin1 | unicode | utf8
.br
Depth = unlimited | integer() >= 1
.br
.RE
.RE
.RS
.LP

.RS -4
.B
Note:
.RE
This function is deprecated in the sense that the \fIerror_logger\fR\& is no longer the preferred interface for logging in Erlang/OTP\&. A new logging API was added in Erlang/OTP 21\&.0, but legacy \fIerror_logger\fR\& handlers can still be used\&. New Logger handlers do not need to used this function, since the formatting callback (\fIreport_cb\fR\&) is included as metadata in the log event\&.

.LP
This function can be used by a user-defined legacy \fIerror_logger\fR\& event handler to format a crash report\&. When Depth is specified as a positive integer, it is used in the format string to limit the output as follows: \fIio_lib:format("~P", [Term,Depth])\fR\&\&.
.RE

.LP
.nf

.B
hibernate(Module, Function, Args) -> no_return()
.br
.fi
.br
.RS
.LP
Types:

.RS 3
Module = module()
.br
Function = atom()
.br
Args = [term()]
.br
.RE
.RE
.RS
.LP
This function does the same as (and does call) the \fIhibernate/3\fR\& BIF, but ensures that exception handling and logging continues to work as expected when the process wakes up\&.
.LP
Always use this function instead of the BIF for processes started using \fIproc_lib\fR\& functions\&.
.RE

.LP
.nf

.B
init_ack(Ret) -> ok
.br
.fi
.br
.nf

.B
init_ack(Parent, Ret) -> ok
.br
.fi
.br
.RS
.LP
Types:

.RS 3
Parent = pid()
.br
Ret = term()
.br
.RE
.RE
.RS
.LP
This function must be used by a process that has been started by a \fIstart[_link]/3,4,5\fR\& function\&. It tells \fIParent\fR\& that the process has initialized itself, has started, or has failed to initialize itself\&.
.LP
Function \fIinit_ack/1\fR\& uses the parent value previously stored by the start function used\&.
.LP
If this function is not called, the start function returns an error tuple (if a link and/or a time-out is used) or hang otherwise\&.
.LP
The following example illustrates how this function and \fIproc_lib:start_link/3\fR\& are used:
.LP
.nf

-module(my_proc).
-export([start_link/0]).
-export([init/1]).

start_link() ->
    proc_lib:start_link(my_proc, init, [self()]).

init(Parent) ->
    case do_initialization() of
        ok ->
            proc_lib:init_ack(Parent, {ok, self()});
        {error, Reason} ->
            exit(Reason)
    end,
    loop().

\&...
.fi
.RE

.LP
.nf

.B
initial_call(Process) -> {Module, Function, Args} | false
.br
.fi
.br
.RS
.LP
Types:

.RS 3
Process = dict_or_pid()
.br
Module = module()
.br
Function = atom()
.br
Args = [atom()]
.br
.RE
.RE
.RS
.LP
Extracts the initial call of a process that was started using one of the spawn or start functions in this module\&. \fIProcess\fR\& can either be a pid, an integer tuple (from which a pid can be created), or the process information of a process \fIPid\fR\& fetched through an \fIerlang:process_info(Pid)\fR\& function call\&.
.LP

.RS -4
.B
Note:
.RE
The list \fIArgs\fR\& no longer contains the arguments, but the same number of atoms as the number of arguments; the first atom is \fI\&'Argument__1\&'\fR\&, the second \fI\&'Argument__2\&'\fR\&, and so on\&. The reason is that the argument list could waste a significant amount of memory, and if the argument list contained funs, it could be impossible to upgrade the code for the module\&.
.LP
If the process was spawned using a fun, \fIinitial_call/1\fR\& no longer returns the fun, but the module, function for the local function implementing the fun, and the arity, for example, \fI{some_module,-work/3-fun-0-,0}\fR\& (meaning that the fun was created in function \fIsome_module:work/3\fR\&)\&. The reason is that keeping the fun would prevent code upgrade for the module, and that a significant amount of memory could be wasted\&.

.RE

.LP
.nf

.B
spawn(Fun) -> pid()
.br
.fi
.br
.nf

.B
spawn(Node, Fun) -> pid()
.br
.fi
.br
.nf

.B
spawn(Module, Function, Args) -> pid()
.br
.fi
.br
.nf

.B
spawn(Node, Module, Function, Args) -> pid()
.br
.fi
.br
.RS
.LP
Types:

.RS 3
Node = node()
.br
Fun = function()
.br
Module = module()
.br
Function = atom()
.br
Args = [term()]
.br
.RE
.RE
.RS
.LP
Spawns a new process and initializes it as described in the beginning of this manual page\&. The process is spawned using the \fIspawn\fR\& BIFs\&.
.RE

.LP
.nf

.B
spawn_link(Fun) -> pid()
.br
.fi
.br
.nf

.B
spawn_link(Node, Fun) -> pid()
.br
.fi
.br
.nf

.B
spawn_link(Module, Function, Args) -> pid()
.br
.fi
.br
.nf

.B
spawn_link(Node, Module, Function, Args) -> pid()
.br
.fi
.br
.RS
.LP
Types:

.RS 3
Node = node()
.br
Fun = function()
.br
Module = module()
.br
Function = atom()
.br
Args = [term()]
.br
.RE
.RE
.RS
.LP
Spawns a new process and initializes it as described in the beginning of this manual page\&. The process is spawned using the \fIspawn_link\fR\& BIFs\&.
.RE

.LP
.nf

.B
spawn_opt(Fun, SpawnOpts) -> pid() | {pid(), reference()}
.br
.fi
.br
.nf

.B
spawn_opt(Node, Function, SpawnOpts) ->
.B
             pid() | {pid(), reference()}
.br
.fi
.br
.nf

.B
spawn_opt(Module, Function, Args, SpawnOpts) ->
.B
             pid() | {pid(), reference()}
.br
.fi
.br
.nf

.B
spawn_opt(Node, Module, Function, Args, SpawnOpts) ->
.B
             pid() | {pid(), reference()}
.br
.fi
.br
.RS
.LP
Types:

.RS 3
Node = node()
.br
Fun = function()
.br
Module = module()
.br
Function = atom()
.br
Args = [term()]
.br
SpawnOpts = [spawn_option()]
.br
.RE
.RE
.RS
.LP
Spawns a new process and initializes it as described in the beginning of this manual page\&. The process is spawned using the \fIerlang:spawn_opt\fR\& BIFs\&.
.RE

.LP
.nf

.B
start(Module, Function, Args) -> Ret
.br
.fi
.br
.nf

.B
start(Module, Function, Args, Time) -> Ret
.br
.fi
.br
.nf

.B
start(Module, Function, Args, Time, SpawnOpts) -> Ret
.br
.fi
.br
.RS
.LP
Types:

.RS 3
Module = module()
.br
Function = atom()
.br
Args = [term()]
.br
Time = timeout()
.br
SpawnOpts = [start_spawn_option()]
.br
Ret = term() | {error, Reason :: term()}
.br
.RE
.RE
.RS
.LP
Starts a new process synchronously\&. Spawns the process and waits for it to start\&. When the process has started, it \fImust\fR\& call \fIinit_ack(Parent, Ret)\fR\& or \fIinit_ack(Ret)\fR\&, where \fIParent\fR\& is the process that evaluates this function\&. At this time, \fIRet\fR\& is returned\&.
.LP
If \fITime\fR\& is specified as an integer, this function waits for \fITime\fR\& milliseconds for the new process to call \fIinit_ack\fR\&, or \fIRet = {error, timeout}\fR\& will be returned, and the process is killed\&.
.LP
Argument \fISpawnOpts\fR\&, if specified, is passed as the last argument to the \fIspawn_opt/2,3,4,5\fR\& BIF\&.
.LP

.RS -4
.B
Note:
.RE
Using spawn option \fImonitor\fR\& is not allowed\&. It causes the function to fail with reason \fIbadarg\fR\&\&.

.RE

.LP
.nf

.B
start_link(Module, Function, Args) -> Ret
.br
.fi
.br
.nf

.B
start_link(Module, Function, Args, Time) -> Ret
.br
.fi
.br
.nf

.B
start_link(Module, Function, Args, Time, SpawnOpts) -> Ret
.br
.fi
.br
.RS
.LP
Types:

.RS 3
Module = module()
.br
Function = atom()
.br
Args = [term()]
.br
Time = timeout()
.br
SpawnOpts = [start_spawn_option()]
.br
Ret = term() | {error, Reason :: term()}
.br
.RE
.RE
.RS
.LP
Starts a new process synchronously\&. Spawns the process and waits for it to start\&. A link is atomically set on the newly spawned process\&. When the process has started, it \fImust\fR\& call \fIinit_ack(Parent, Ret)\fR\& or \fIinit_ack(Ret)\fR\&, where \fIParent\fR\& is the process that evaluates this function\&. At this time, \fIRet\fR\& is returned\&.
.LP
If \fITime\fR\& is specified as an integer, this function waits for \fITime\fR\& milliseconds for the new process to call \fIinit_ack\fR\&, or \fIRet = {error, timeout}\fR\& will be returned, and the process is killed\&.
.LP
If the process crashes before it has called \fIinit_ack/1,2\fR\&, \fIRet = {error, Reason}\fR\& will be returned if the calling process traps exits\&.
.LP
Argument \fISpawnOpts\fR\&, if specified, is passed as the last argument to the \fIspawn_opt/2,3,4,5\fR\& BIF\&.
.LP

.RS -4
.B
Note:
.RE
Using spawn option \fImonitor\fR\& is not allowed\&. It causes the function to fail with reason \fIbadarg\fR\&\&.

.RE

.LP
.nf

.B
start_monitor(Module, Function, Args) -> {Ret, Mon}
.br
.fi
.br
.nf

.B
start_monitor(Module, Function, Args, Time) -> {Ret, Mon}
.br
.fi
.br
.nf

.B
start_monitor(Module, Function, Args, Time, SpawnOpts) ->
.B
                 {Ret, Mon}
.br
.fi
.br
.RS
.LP
Types:

.RS 3
Module = module()
.br
Function = atom()
.br
Args = [term()]
.br
Time = timeout()
.br
SpawnOpts = [start_spawn_option()]
.br
Mon = reference()
.br
Ret = term() | {error, Reason :: term()}
.br
.RE
.RE
.RS
.LP
Starts a new process synchronously\&. Spawns the process and waits for it to start\&. A monitor is atomically set on the newly spawned process\&. When the process has started, it \fImust\fR\& call \fIinit_ack(Parent, Ret)\fR\& or \fIinit_ack(Ret)\fR\&, where \fIParent\fR\& is the process that evaluates this function\&. At this time, \fIRet\fR\& is returned\&.
.LP
If \fITime\fR\& is specified as an integer, this function waits for \fITime\fR\& milliseconds for the new process to call \fIinit_ack\fR\&, or \fIRet = {error, timeout}\fR\& will be returned, and the process is killed\&.
.LP
The return value is \fI{Ret, Mon}\fR\& where \fIRet\fR\& corresponds to the \fIRet\fR\& argument in the call to \fIinit_ack()\fR\&, and \fIMon\fR\& is the monitor reference of the monitor that has been set up\&.
.LP
A \fI\&'DOWN\&'\fR\& message will be delivered to the caller if this function returns, and the spawned process terminates\&. This is true also in the case when the operation times out\&.
.LP
Argument \fISpawnOpts\fR\&, if specified, is passed as the last argument to the \fIspawn_opt/2,3,4,5\fR\& BIF\&.
.LP

.RS -4
.B
Note:
.RE
Using spawn option \fImonitor\fR\& is not allowed\&. It causes the function to fail with reason \fIbadarg\fR\&\&.

.RE

.LP
.nf

.B
stop(Process) -> ok
.br
.fi
.br
.RS
.LP
Types:

.RS 3
Process = pid() | RegName | {RegName, node()}
.br
.RE
.RE
.RS
.LP
Equivalent to \fIstop(Process, normal, infinity)\fR\&\&.
.RE

.LP
.nf

.B
stop(Process, Reason, Timeout) -> ok
.br
.fi
.br
.RS
.LP
Types:

.RS 3
Process = pid() | RegName | {RegName, node()}
.br
Reason = term()
.br
Timeout = timeout()
.br
.RE
.RE
.RS
.LP
Orders the process to exit with the specified \fIReason\fR\& and waits for it to terminate\&.
.LP
Returns \fIok\fR\& if the process exits with the specified \fIReason\fR\& within \fITimeout\fR\& milliseconds\&.
.LP
If the call times out, a \fItimeout\fR\& exception is raised\&.
.LP
If the process does not exist, a \fInoproc\fR\& exception is raised\&.
.LP
The implementation of this function is based on the \fIterminate\fR\& system message, and requires that the process handles system messages correctly\&. For information about system messages, see \fIsys(3erl)\fR\& and section  sys and proc_lib in OTP Design Principles\&.
.RE

.LP
.nf

.B
translate_initial_call(Process) -> {Module, Function, Arity}
.br
.fi
.br
.RS
.LP
Types:

.RS 3
Process = dict_or_pid()
.br
Module = module()
.br
Function = atom()
.br
Arity = byte()
.br
.RE
.RE
.RS
.LP
This function is used by functions \fIc:i/0\fR\& and \fIc:regs/0\fR\& to present process information\&.
.LP
This function extracts the initial call of a process that was started using one of the spawn or start functions in this module, and translates it to more useful information\&. \fIProcess\fR\& can either be a pid, an integer tuple (from which a pid can be created), or the process information of a process \fIPid\fR\& fetched through an \fIerlang:process_info(Pid)\fR\& function call\&.
.LP
If the initial call is to one of the system-defined behaviors such as \fIgen_server\fR\& or \fIgen_event\fR\&, it is translated to more useful information\&. If a \fIgen_server\fR\& is spawned, the returned \fIModule\fR\& is the name of the callback module and \fIFunction\fR\& is \fIinit\fR\& (the function that initiates the new server)\&.
.LP
A \fIsupervisor\fR\& and a \fIsupervisor_bridge\fR\& are also \fIgen_server\fR\& processes\&. To return information that this process is a supervisor and the name of the callback module, \fIModule\fR\& is \fIsupervisor\fR\& and \fIFunction\fR\& is the name of the supervisor callback module\&. \fIArity\fR\& is \fI1\fR\&, as the \fIinit/1\fR\& function is called initially in the callback module\&.
.LP
By default, \fI{proc_lib,init_p,5}\fR\& is returned if no information about the initial call can be found\&. It is assumed that the caller knows that the process has been spawned with the \fIproc_lib\fR\& module\&.
.RE

.SH "SEE ALSO"

.LP
\fIerror_logger(3erl)\fR\&
.LP
\fIlogger(3erl)\fR\&