Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/check-formatting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ jobs:

erlfmt-check:
runs-on: ubuntu-24.04
container: erlang:27
container: erlang:28
steps:
- uses: actions/checkout@v4

- name: "Check formatting with Erlang fmt"
run: |
cd ..
git clone --depth 1 -b v1.1.0 https://github.com/WhatsApp/erlfmt.git
git clone --depth 1 -b v1.7.0 https://github.com/WhatsApp/erlfmt.git
cd erlfmt
rebar3 as release escriptize
cd ../AtomVM
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added support for big integers in `binary_to_term/1` and `term_to_binary/1,2`
- Added `proc_lib`
- Added gen_server support for timeout tuples in callback return actions introduced in OTP-28.
- Added `sys`

### Changed

Expand Down
11 changes: 3 additions & 8 deletions libs/eavmlib/src/timer_manager.erl
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,9 @@ start() ->

-spec maybe_start() -> {ok, Pod :: pid()}.
maybe_start() ->
case erlang:whereis(?SERVER_NAME) of
undefined ->
case start() of
{ok, _Pid} = R -> R;
{error, {already_started, Pid}} -> {ok, Pid}
end;
Pid when is_pid(Pid) ->
{ok, Pid}
case start() of
{ok, _Pid} = R -> R;
{error, {already_started, Pid}} -> {ok, Pid}
end.

%%-----------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions libs/estdlib/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ set(ERLANG_MODULES
erts_debug
ets
file
gen
gen_event
gen_server
gen_statem
Expand All @@ -58,6 +59,7 @@ set(ERLANG_MODULES
math
net
proc_lib
sys
file
logger
logger_std_h
Expand Down
91 changes: 91 additions & 0 deletions libs/estdlib/src/gen.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
%
% This file is part of AtomVM.
%
% Copyright 2025 Paul Guyot <pguyot@kallisys.net>
%
% 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.
%
% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
%

%%-----------------------------------------------------------------------------
%% This module implements common code in gen_* modules, following what
%% Erlang/OTP does with gen module. However, none of the functions exported
%% here are public interface.
%%-----------------------------------------------------------------------------

-module(gen).
-moduledoc false.

-export([
call/4,
cast/2,
reply/2
]).

-type server_ref() :: atom() | pid().
-type from() :: {pid(), reference()}.

%% @private
-spec call(ServerRef :: server_ref(), Label :: atom(), Request :: term(), Timeout :: timeout()) ->
Reply :: term() | {error, Reason :: term()}.
call(ServerRef, Label, Request, Timeout) ->
MonitorRef = monitor(process, ServerRef),
ok =
try
ServerRef ! {Label, {self(), MonitorRef}, Request},
ok
catch
error:badarg ->
% Process no longer exists, monitor will send a message
ok
end,
receive
{'DOWN', MonitorRef, process, _, {E, []} = _Reason} ->
exit(E);
{'DOWN', MonitorRef, process, _, {_E, _L} = Reason} ->
exit(Reason);
{'DOWN', MonitorRef, process, _, Atom} when is_atom(Atom) ->
exit(Atom);
{MonitorRef, Reply} ->
demonitor(MonitorRef, [flush]),
Reply
Copy link
Contributor

@petermm petermm Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this should be {ok, Reply}
https://github.com/erlang/otp/blob/47995dbaeaf2c54cf2e4e19823f4e94fe52854df/lib/stdlib/src/gen.erl#L247

%% Makes a synchronous call to a generic process.
%% Request is sent to the Pid, and the response must be
%% {Tag, Reply}.

https://github.com/erlang/otp/blob/47995dbaeaf2c54cf2e4e19823f4e94fe52854df/lib/stdlib/src/gen.erl#L208C1-L211C17

I have rebased GenServer.ex to use this call and tests are failing..

after Timeout ->
% If Timeout is small enough (0), the error message might be timeout
% instead of noproc as there could be a race condition with the monitor.
demonitor(MonitorRef, [flush]),
exit(timeout)
end.

%% @private
-spec cast(ServerRef :: server_ref(), Message :: any()) -> ok.
cast(ServerRef, Message) ->
try
ServerRef ! {'$gen_cast', Message},
ok
catch
error:_ ->
% Process does not exist, ignore error
ok
end.

%% @private
-spec reply(From :: from(), Reply :: any()) -> ok.
reply({Pid, Ref}, Reply) ->
try
Pid ! {Ref, Reply},
ok
catch
_:_ ->
ok
end.
Loading
Loading