File 1079-stdlib-Fix-proc_lib-stop-when-exit-reason-is-expecte.patch of Package erlang

From 3f2d85a5ee3a80c7540c19919506cbad3dc7eb85 Mon Sep 17 00:00:00 2001
From: Lukas Larsson <lukas@erlang.org>
Date: Fri, 16 Aug 2024 08:55:43 +0200
Subject: [PATCH] stdlib: Fix proc_lib:stop when exit reason is expected reason

---
 lib/stdlib/src/proc_lib.erl        | 12 ++++++++----
 lib/stdlib/test/proc_lib_SUITE.erl | 12 ++++++++++++
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/lib/stdlib/src/proc_lib.erl b/lib/stdlib/src/proc_lib.erl
index 80909fb2c2..1a5dbd2169 100644
--- a/lib/stdlib/src/proc_lib.erl
+++ b/lib/stdlib/src/proc_lib.erl
@@ -1573,13 +1573,15 @@ about system messages, see `m:sys` and section
 stop(Process, Reason, Timeout) ->
     Mref = erlang:monitor(process, Process),
     T0 = erlang:monotonic_time(millisecond),
+
+    StopTimeout = fun(infinity) -> infinity;
+                     (T1) -> T1 - (((erlang:monotonic_time(microsecond) + 999) div 1000) - T0)
+                end,
+
     RemainingTimeout = try
 	sys:terminate(Process, Reason, Timeout)
     of
-	ok when Timeout =:= infinity ->
-	    infinity;
-	ok ->
-	    Timeout - (((erlang:monotonic_time(microsecond) + 999) div 1000) - T0)
+	ok -> StopTimeout(Timeout)
     catch
 	exit:{noproc, {sys, terminate, _}} ->
 	    demonitor(Mref, [flush]),
@@ -1587,6 +1589,8 @@ stop(Process, Reason, Timeout) ->
 	exit:{timeout, {sys, terminate, _}} ->
 	    demonitor(Mref, [flush]),
 	    exit(timeout);
+        exit:{Reason, {sys, terminate, _}} ->
+            StopTimeout(Timeout);
 	exit:Reason1 ->
 	    demonitor(Mref, [flush]),
 	    exit(Reason1)
diff --git a/lib/stdlib/test/proc_lib_SUITE.erl b/lib/stdlib/test/proc_lib_SUITE.erl
index 6683fd7d2a..59c08e17bf 100644
--- a/lib/stdlib/test/proc_lib_SUITE.erl
+++ b/lib/stdlib/test/proc_lib_SUITE.erl
@@ -695,6 +695,18 @@ stop(_Config) ->
 	timeout
     end,
 
+    %% Ensure that if process stops with same reason just as stop is called,
+    %% stop does not throw an exception.
+    PidNormalStop = proc_lib:spawn(fun() -> timer:sleep(1000) end),
+    ok = proc_lib:stop(PidNormalStop,normal,2000),
+    false = erlang:is_process_alive(PidNormalStop),
+    PidDieStop = proc_lib:spawn(fun() -> timer:sleep(1000), exit(die) end),
+    ok = proc_lib:stop(PidDieStop,die,2000),
+    false = erlang:is_process_alive(PidDieStop),
+    PidDieStopCrash = proc_lib:spawn(fun() -> timer:sleep(1000), exit(die) end),
+    {'EXIT', {die, _}} = catch (proc_lib:stop(PidDieStopCrash,normal,2000)),
+    false = erlang:is_process_alive(PidDieStopCrash),
+
     %% Success case with other reason than 'normal'
     Pid5 = proc_lib:spawn(SysMsgProc),
     ok = proc_lib:stop(Pid5,other_reason,infinity),
-- 
2.43.0

openSUSE Build Service is sponsored by