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