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

openSUSE Build Service is sponsored by