File 1425-Restore-save-pointer-on-bad-timeout-value-in-receive.patch of Package erlang

From 2be04f53570066031c4fc152aa14798dc38c0403 Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Mon, 27 Sep 2021 14:09:04 +0200
Subject: [PATCH] Restore save pointer on bad timeout value in receive

The message queue save pointer was not restored to the beginning of the
message queue when a bad timeout value was encountered in the receive. If
the timeout_value exception was caught, the following receive would not
be searched from the beginning of the message queue. This potentially
caused the process to hang forever even though a matching message was
present in the message queue.
---
 erts/emulator/beam/msg_instrs.tab    |  2 ++
 erts/emulator/test/receive_SUITE.erl | 32 ++++++++++++++++++++++++++--
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/erts/emulator/beam/msg_instrs.tab b/erts/emulator/beam/msg_instrs.tab
index 10fd5ad48d..7056bbc95b 100644
--- a/erts/emulator/beam/msg_instrs.tab
+++ b/erts/emulator/beam/msg_instrs.tab
@@ -305,6 +305,7 @@ timeout() {
 
 TIMEOUT_VALUE() {
     c_p->freason = EXC_TIMEOUT_VALUE;
+    JOIN_MESSAGE(c_p);
     goto find_func_info;
     //| -no_next
 }
@@ -372,6 +373,7 @@ wait.src(Src) {
             } else { /* Wrong time */
                 erts_proc_unlock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE);
                 c_p->freason = EXC_TIMEOUT_VALUE;
+                JOIN_MESSAGE(c_p);
                 goto find_func_info;
             }
         }
diff --git a/erts/emulator/test/receive_SUITE.erl b/erts/emulator/test/receive_SUITE.erl
index 339507c9d8..d42db517c2 100644
--- a/erts/emulator/test/receive_SUITE.erl
+++ b/erts/emulator/test/receive_SUITE.erl
@@ -26,7 +26,8 @@
 
 -export([all/0, suite/0, init_per_testcase/2, end_per_testcase/2,
 	 call_with_huge_message_queue/1,receive_in_between/1,
-         receive_opt_exception/1,receive_opt_recursion/1]).
+         receive_opt_exception/1,receive_opt_recursion/1,
+         gh_5235_missing_save_reset/1]).
 
 suite() ->
     [{ct_hooks,[ts_install_cth]},
@@ -34,7 +35,9 @@ all() ->
 
 all() ->
     [call_with_huge_message_queue, receive_in_between,
-     receive_opt_exception, receive_opt_recursion].
+     receive_opt_exception,
+     receive_opt_recursion,
+     gh_5235_missing_save_reset].
 
 init_per_testcase(receive_opt_deferred_save, Config) ->
     case erlang:system_info(schedulers_online) of
@@ -183,10 +186,36 @@ erl_1199_flush_blipp() ->
             end
     end.
 
+gh_5235_missing_save_reset(Config) when is_list(Config) ->
+    %%
+    %% Used to hang in the second receive due to save
+    %% pointer not being reset on bad timeout value...
+    %%
+    ct:timetrap({seconds, 10}),
+    id(self()) ! init,
+    try
+        receive blipp -> ok after blupp -> ok end
+    catch _:_ ->
+            ok
+    end,
+    receive init -> ok end,
+
+    %% Try with a timeout value not known in compile
+    %% time as well...
+    id(self()) ! init2,
+    try
+        receive blapp -> ok after id(blepp) -> ok end
+    catch _:_ ->
+            ok
+    end,
+    receive init2 -> ok end.
+
 %%%
 %%% Common helpers.
 %%%
 
+id(X) -> X.
+
 echo_loop() ->
     receive
 	{Ref,{Pid,Msg}} ->
-- 
2.31.1

openSUSE Build Service is sponsored by