|
19 | 19 | % |
20 | 20 |
|
21 | 21 | %%----------------------------------------------------------------------------- |
22 | | -%% @doc An implementation of the Erlang/OTP gen_server interface. |
| 22 | +%% @doc An implementation of the Erlang/OTP proc_lib interface. |
23 | 23 | %% |
24 | 24 | %% This module implements a strict subset of the Erlang/OTP proc_lib |
25 | 25 | %% interface. |
| 26 | +%% |
| 27 | +%% When spawning a single function, calling `spawn/1' or `spawn_link/1', |
| 28 | +%% Erlang/OTP proc_lib sets `initial_call' to a tuple with a unique |
| 29 | +%% atom determining where the function was created, for example |
| 30 | +%% ``{some_module, '-work/3-fun-0-', 0}''. AtomVM literaly calls `erlang:apply/2' |
| 31 | +%% and therefore in these cases, `initial_call` is `{erlang, apply, 2}'. |
26 | 32 | %%----------------------------------------------------------------------------- |
27 | 33 |
|
28 | 34 | -module(proc_lib). |
29 | 35 |
|
30 | 36 | %% Public API |
31 | 37 | -export([ |
| 38 | + spawn/1, |
| 39 | + spawn/3, |
| 40 | + spawn_link/1, |
| 41 | + spawn_link/3, |
32 | 42 | start/3, |
33 | 43 | start/4, |
34 | 44 | start/5, |
|
50 | 60 | start_spawn_option/0 |
51 | 61 | ]). |
52 | 62 |
|
| 63 | +-compile({no_auto_import, [spawn/3, spawn_link/3]}). |
| 64 | + |
53 | 65 | -include_lib("kernel/include/logger.hrl"). |
54 | 66 |
|
55 | 67 | %% @doc Restricted set of spawn options. `monitor' is not supported. |
|
59 | 71 | | {atomvm_heap_growth, erlang:atomvm_heap_growth_strategy()} |
60 | 72 | | link. |
61 | 73 |
|
62 | | -%% @equiv start_link(Module, Function, Args, infinity) |
| 74 | +%% @equiv spawn(erlang, apply, [Fun, []]) |
| 75 | +-spec spawn(fun(() -> any())) -> pid(). |
| 76 | +spawn(Fun) -> |
| 77 | + spawn(erlang, apply, [Fun, []]). |
| 78 | + |
| 79 | +%%----------------------------------------------------------------------------- |
| 80 | +%% @param Module of the function to call |
| 81 | +%% @param Function to call |
| 82 | +%% @param Args arguments to pass to the function |
| 83 | +%% @doc Spawn a new process and initialize it. |
| 84 | +%% @end |
| 85 | +%%----------------------------------------------------------------------------- |
| 86 | +-spec spawn(module(), atom(), [any()]) -> pid(). |
| 87 | +spawn(Module, Function, Args) -> |
| 88 | + Parent = self(), |
| 89 | + Ancestors = get_ancestors(), |
| 90 | + erlang:spawn(?MODULE, init_p, [Parent, Ancestors, Module, Function, Args]). |
| 91 | + |
| 92 | +%% @equiv spawn_link(erlang, apply, [Fun, []]) |
| 93 | +-spec spawn_link(fun(() -> any())) -> pid(). |
| 94 | +spawn_link(Fun) -> |
| 95 | + spawn_link(erlang, apply, [Fun, []]). |
| 96 | + |
| 97 | +%%----------------------------------------------------------------------------- |
| 98 | +%% @param Module of the function to call |
| 99 | +%% @param Function to call |
| 100 | +%% @param Args arguments to pass to the function |
| 101 | +%% @doc Spawn and atomically link a new process and initialize it. |
| 102 | +%% @end |
| 103 | +%%----------------------------------------------------------------------------- |
| 104 | +-spec spawn_link(module(), atom(), [any()]) -> pid(). |
| 105 | +spawn_link(Module, Function, Args) -> |
| 106 | + Parent = self(), |
| 107 | + Ancestors = get_ancestors(), |
| 108 | + erlang:spawn_link(?MODULE, init_p, [Parent, Ancestors, Module, Function, Args]). |
| 109 | + |
| 110 | +%% @equiv start(Module, Function, Args, infinity) |
63 | 111 | -spec start(module(), atom(), [any()]) -> any(). |
64 | 112 | start(Module, Function, Args) -> |
65 | 113 | start(Module, Function, Args, infinity). |
@@ -114,11 +162,7 @@ start0(Module, Function, Args, Timeout, SpawnOpts, Link) -> |
114 | 162 | false -> ok |
115 | 163 | end, |
116 | 164 | Parent = self(), |
117 | | - Ancestors = |
118 | | - case get('$ancestors') of |
119 | | - A when is_list(A) -> A; |
120 | | - _ -> [] |
121 | | - end, |
| 165 | + Ancestors = get_ancestors(), |
122 | 166 | {Pid, Monitor} = spawn_opt(?MODULE, init_p, [Parent, Ancestors, Module, Function, Args], [ |
123 | 167 | monitor | SpawnOpts |
124 | 168 | ]), |
@@ -155,6 +199,13 @@ start0(Module, Function, Args, Timeout, SpawnOpts, Link) -> |
155 | 199 | {error, timeout} |
156 | 200 | end. |
157 | 201 |
|
| 202 | +%% @private |
| 203 | +get_ancestors() -> |
| 204 | + case get('$ancestors') of |
| 205 | + A when is_list(A) -> A; |
| 206 | + _ -> [] |
| 207 | + end. |
| 208 | + |
158 | 209 | %%----------------------------------------------------------------------------- |
159 | 210 | %% @param Result result sent back to parent |
160 | 211 | %% @doc Callback to signal that initialization succeeded. |
@@ -237,7 +288,7 @@ crash_report(Class, Reason, MFA, Stacktrace) -> |
237 | 288 | ICA, |
238 | 289 | self(), |
239 | 290 | {Class, Reason}, |
240 | | - get('$ancestors'), |
| 291 | + get_ancestors(), |
241 | 292 | MessageQueueLen, |
242 | 293 | Links, |
243 | 294 | TotalHeapSize, |
|
0 commit comments