File 2801-ref-more-readable-checks-on-timeout-hibernate-and-co.patch of Package erlang
From 4e9dd571545f6ccf6fae7b2b6817f42cbcb7101e Mon Sep 17 00:00:00 2001
From: Pouriya Jahanbakhsh <pouriya.jahanbakhsh@gmail.com>
Date: Sat, 5 Feb 2022 02:51:56 +0330
Subject: [PATCH 1/3] ref: more readable checks on timeout, hibernate, and
{continue, _} in returned value of callback and enter_loop functions
---
lib/stdlib/src/gen_server.erl | 119 ++++++++++++++++++++++++----------
1 file changed, 86 insertions(+), 33 deletions(-)
diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl
index 6e26d5270a..509857d775 100644
--- a/lib/stdlib/src/gen_server.erl
+++ b/lib/stdlib/src/gen_server.erl
@@ -137,6 +137,11 @@
STACKTRACE(),
element(2, erlang:process_info(self(), current_stacktrace))).
+-define(
+ is_timeout(X),
+ ( (X) =:= infinity orelse ( is_integer(X) andalso (X) >= 0 ) )
+).
+
%%%=========================================================================
%%% API
%%%=========================================================================
@@ -557,7 +562,7 @@ multi_call(Nodes, Name, Request, Timeout)
) ->
no_return().
%%
-enter_loop(Mod, Options, State) ->
+enter_loop(Mod, Options, State) when is_atom(Mod) andalso is_list(Options) ->
enter_loop(Mod, Options, State, self(), infinity).
-spec enter_loop(
@@ -572,34 +577,82 @@ enter_loop(Mod, Options, State) ->
Options :: [enter_loop_opt()],
State :: term(),
Timeout :: timeout()
+ ) ->
+ no_return();
+ (
+ Module :: module(),
+ Options :: [enter_loop_opt()],
+ State :: term(),
+ Hibernate :: hibernate
+ ) ->
+ no_return();
+ (
+ Module :: module(),
+ Options :: [enter_loop_opt()],
+ State :: term(),
+ Continue :: {continue, term()}
) ->
no_return().
%%
enter_loop(Mod, Options, State, ServerName = {Scope, _})
- when Scope == local; Scope == global ->
+ when is_atom(Mod) andalso
+ is_list(Options) andalso
+ (Scope == local orelse Scope == global) ->
enter_loop(Mod, Options, State, ServerName, infinity);
%%
-enter_loop(Mod, Options, State, ServerName = {via, _, _}) ->
+enter_loop(Mod, Options, State, ServerName = {via, _, _}) when is_atom(Mod) andalso is_list(Options) ->
enter_loop(Mod, Options, State, ServerName, infinity);
%%
-enter_loop(Mod, Options, State, Timeout) ->
- enter_loop(Mod, Options, State, self(), Timeout).
+enter_loop(Mod, Options, State, TimeoutOrHibernate)
+ when is_atom(Mod) andalso
+ is_list(Options) andalso
+ (?is_timeout(TimeoutOrHibernate) orelse TimeoutOrHibernate =:= hibernate) ->
+ enter_loop(Mod, Options, State, self(), TimeoutOrHibernate);
+%%
+enter_loop(Mod, Options, State, {continue, _}=Continue) when is_atom(Mod) andalso is_list(Options) ->
+ enter_loop(Mod, Options, State, self(), Continue).
-spec enter_loop(
Module :: module(),
Options :: [enter_loop_opt()],
State :: term(),
ServerName :: server_name() | pid(),
- Timeout :: timeout()
+ Timeout :: timeout() | hibernate | {continue, term()}
+ ) ->
+ no_return();
+ (
+ Module :: module(),
+ Options :: [enter_loop_opt()],
+ State :: term(),
+ ServerName :: server_name() | pid(),
+ Hibernate :: hibernate
+ ) ->
+ no_return();
+ (
+ Module :: module(),
+ Options :: [enter_loop_opt()],
+ State :: term(),
+ ServerName :: server_name() | pid(),
+ Continue :: {continue, term()}
) ->
no_return().
%%
-enter_loop(Mod, Options, State, ServerName, Timeout) ->
+enter_loop(Mod, Options, State, ServerName, TimeoutOrHibernate)
+ when is_atom(Mod) andalso
+ is_list(Options) andalso
+ (?is_timeout(TimeoutOrHibernate) orelse TimeoutOrHibernate =:= hibernate) ->
Name = gen:get_proc_name(ServerName),
Parent = gen:get_parent(),
Debug = gen:debug_options(Name, Options),
HibernateAfterTimeout = gen:hibernate_after(Options),
- loop(Parent, Name, State, Mod, Timeout, HibernateAfterTimeout, Debug).
+ loop(Parent, Name, State, Mod, TimeoutOrHibernate, HibernateAfterTimeout, Debug);
+%%
+enter_loop(Mod, Options, State, ServerName, {continue, _}=Continue) when is_atom(Mod) andalso is_list(Options) ->
+ Name = gen:get_proc_name(ServerName),
+ Parent = gen:get_parent(),
+ Debug = gen:debug_options(Name, Options),
+ HibernateAfterTimeout = gen:hibernate_after(Options),
+ loop(Parent, Name, State, Mod, Continue, HibernateAfterTimeout, Debug).
%%%========================================================================
%%% Gen-callback functions
@@ -623,10 +676,12 @@ init_it(Starter, Parent, Name0, Mod, Args, Options) ->
{ok, {ok, State}} ->
proc_lib:init_ack(Starter, {ok, self()}),
loop(Parent, Name, State, Mod, infinity, HibernateAfterTimeout, Debug);
- {ok, {ok, State, TimeoutHibernateOrContinue}} ->
+ {ok, {ok, State, TimeoutOrHibernate}} when ?is_timeout(TimeoutOrHibernate) orelse TimeoutOrHibernate =:= hibernate ->
+ proc_lib:init_ack(Starter, {ok, self()}),
+ loop(Parent, Name, State, Mod, TimeoutOrHibernate, HibernateAfterTimeout, Debug);
+ {ok, {ok, State, {continue, _}=Continue}} ->
proc_lib:init_ack(Starter, {ok, self()}),
- loop(Parent, Name, State, Mod, TimeoutHibernateOrContinue,
- HibernateAfterTimeout, Debug);
+ loop(Parent, Name, State, Mod, Continue, HibernateAfterTimeout, Debug);
{ok, {stop, Reason}} ->
%% For consistency, we must make sure that the
%% registered name (if any) is unregistered before
@@ -984,13 +1039,12 @@ handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, HibernateAfterTim
{ok, {reply, Reply, NState}} ->
reply(From, Reply),
loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, []);
- {ok, {reply, Reply, NState, Time1}} ->
+ {ok, {reply, Reply, NState, TimeoutOrHibernate}} when ?is_timeout(TimeoutOrHibernate) orelse TimeoutOrHibernate =:= hibernate ->
reply(From, Reply),
- loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, []);
- {ok, {noreply, NState}} ->
- loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, []);
- {ok, {noreply, NState, Time1}} ->
- loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, []);
+ loop(Parent, Name, NState, Mod, TimeoutOrHibernate, HibernateAfterTimeout, []);
+ {ok, {reply, Reply, NState, {continue, _}=Continue}} ->
+ reply(From, Reply),
+ loop(Parent, Name, NState, Mod, Continue, HibernateAfterTimeout, []);
{ok, {stop, Reason, Reply, NState}} ->
try
terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, [])
@@ -1009,17 +1063,12 @@ handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, HibernateAfterTim
{ok, {reply, Reply, NState}} ->
Debug1 = reply(Name, From, Reply, NState, Debug),
loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, Debug1);
- {ok, {reply, Reply, NState, Time1}} ->
+ {ok, {reply, Reply, NState, TimeoutOrHibernate}} when ?is_timeout(TimeoutOrHibernate) orelse TimeoutOrHibernate =:= hibernate ->
Debug1 = reply(Name, From, Reply, NState, Debug),
- loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, Debug1);
- {ok, {noreply, NState}} ->
- Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
- {noreply, NState}),
- loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, Debug1);
- {ok, {noreply, NState, Time1}} ->
- Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
- {noreply, NState}),
- loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, Debug1);
+ loop(Parent, Name, NState, Mod, TimeoutOrHibernate, HibernateAfterTimeout, Debug1);
+ {ok, {reply, Reply, NState, {continue, _}=Continue}} ->
+ Debug1 = reply(Name, From, Reply, NState, Debug),
+ loop(Parent, Name, NState, Mod, Continue, HibernateAfterTimeout, Debug1);
{ok, {stop, Reason, Reply, NState}} ->
try
terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, Debug)
@@ -1037,8 +1086,10 @@ handle_common_reply(Reply, Parent, Name, From, Msg, Mod, HibernateAfterTimeout,
case Reply of
{ok, {noreply, NState}} ->
loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, []);
- {ok, {noreply, NState, Time1}} ->
- loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, []);
+ {ok, {noreply, NState, TimeoutOrHibernate}} when ?is_timeout(TimeoutOrHibernate) orelse TimeoutOrHibernate =:= hibernate ->
+ loop(Parent, Name, NState, Mod, TimeoutOrHibernate, HibernateAfterTimeout, []);
+ {ok, {noreply, NState, {continue, _}=Continue}} ->
+ loop(Parent, Name, NState, Mod, Continue, HibernateAfterTimeout, []);
{ok, {stop, Reason, NState}} ->
terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, []);
{'EXIT', Class, Reason, Stacktrace} ->
@@ -1053,10 +1104,12 @@ handle_common_reply(Reply, Parent, Name, From, Msg, Mod, HibernateAfterTimeout,
Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
{noreply, NState}),
loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, Debug1);
- {ok, {noreply, NState, Time1}} ->
- Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
- {noreply, NState}),
- loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, Debug1);
+ {ok, {noreply, NState, TimeoutOrHibernate}} when ?is_timeout(TimeoutOrHibernate) orelse TimeoutOrHibernate =:= hibernate ->
+ Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, {noreply, NState}),
+ loop(Parent, Name, NState, Mod, TimeoutOrHibernate, HibernateAfterTimeout, Debug1);
+ {ok, {noreply, NState, {continue, _}=Continue}} ->
+ Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, {noreply, NState}),
+ loop(Parent, Name, NState, Mod, Continue, HibernateAfterTimeout, Debug1);
{ok, {stop, Reason, NState}} ->
terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, Debug);
{'EXIT', Class, Reason, Stacktrace} ->
--
2.34.1