Repository navigation
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
1efb84e to
cd8cac1
Compare
PR re-review:
|
cd8cac1 to
4e6c1f2
Compare
bettio
left a comment
There was a problem hiding this comment.
Few changes required.
Also, libs/exavmlib/lib/GenServer.ex:1045 still carries the ":gen.start is not available" workaround and calls :gen_server.start_link/3,4 and :gen_server.start/3,4 directly, so timeout: and spawn_opt: stay ignored for the bundled Elixir GenServer even though this PR now honours them. Since this PR introduces the entry point, it is the right place to use it: make do_start/4 call :gen.start(:gen_server, link, module, init_arg, opts) and :gen.start(:gen_server, link, {:local, atom}, module, init_arg, opts) as upstream Elixir does, and drop the two case link do blocks and the workaround comment. {:global, _} and {:via, _, _} names stay unsupported, as gen:start/6 only accepts {local, Name}.
| {'DOWN', MonitorRef, process, Pid, _} -> ok | ||
| end, | ||
| flush_exit(Pid, Link), | ||
| flush_exit(Pid), |
There was a problem hiding this comment.
flush_exit/1 now runs before await_down/2 in both nack clauses (lines 219 and 223), so a linked caller is unlinked while the child may still be alive. Whether a non-trapping start_link caller is then killed depends on whether the child's exit signal is already queued when the caller handles the nack.
OTP's gen_server never enters that path: it only nacks with {exit, normal} and exits directly on {stop, Reason}, bad returns and crashes, so the link fires deterministically.
Our gen_server:init_it/4 nacks with {exit, Reason} for all three.
A regression test fits the existing helper: {killed, boom} = isolated(false, fun() -> gen:start(gen_server, link, ?MODULE, {stop, boom}, []) end) plus an init({stop, Reason}) -> {stop, Reason} clause.
| by adding the `elixir_erl_pass` runtime helpers that compiled Elixir code calls | ||
| - Fixed `maps:from_keys/2` (and `sets:from_list/1`, which is built on top of it) not | ||
| deduplicating structurally equal but separately-allocated boxed terms, such as tuples | ||
| - Fixed `gen_server` returning an error instead of `ignore` when `init/1` returns `ignore` |
There was a problem hiding this comment.
Let's move this block to beta.1
The Elixir GenServer implementation calls them. The monitor linkage folds
proc_lib:start_monitor/3's {Result, MonitorRef} into OTP's {ok, {Pid, Mon}}.
A named start no longer spawns a child when the name is taken, and a failed
registration terminates the child through init_fail so no EXIT or DOWN is left
in the caller's mailbox. init/1 returning ignore now yields ignore, and the
timeout and spawn_opt options are honoured.
Forwarding spawn_opt made proc_lib's failure cleanup reachable with a link the
caller did not ask for, so it now unlinks unconditionally like OTP instead of
tracking whether it created the link.
A failed proc_lib:start_monitor now delivers the DOWN for the monitor it returns,
as OTP does. gen:start and gen_server:start_monitor, which hide that monitor on
failure, consume it through gen:monitor_return/1.
Like OTP, a server whose init/1 stops, crashes or returns a bad value now exits
with that reason instead of nacking, so a linked caller deterministically gets the
exit signal and the start returns {error, Reason}. A value thrown by init/1 is
treated as its return value. Only ignore still goes through init_fail.
The bundled Elixir GenServer now starts through gen:start/5,6, as upstream Elixir
does, so its :timeout and :spawn_opt options are honoured.
Signed-off-by: Paul Guyot <pguyot@kallisys.net>
The Elixir GenServer implementation calls them. The monitor linkage folds proc_lib:start_monitor/3's {Result, MonitorRef} into OTP's {ok, {Pid, Mon}}.
These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).
SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later