summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRickard Green <rickard@erlang.org>2021-05-27 15:49:24 +0200
committerRickard Green <rickard@erlang.org>2021-05-27 15:49:24 +0200
commit24bc811738ff86d3177638b9409e37e5f19de207 (patch)
treec31908d47ed7a6ec3b7cada3297704a8a4ac4076
parentfd2e6b7c55a82731fe6e4f0314c720290ccdc8ae (diff)
parentcd4d45fbdd8b6f3e0085d3d61f2dd5f7805f7d82 (diff)
downloaderlang-24bc811738ff86d3177638b9409e37e5f19de207.tar.gz
Merge branch 'rickard/busy-port-fix/GH-4898/OTP-17448' into rickard/busy-port-fix/21/GH-4898/OTP-17448
* rickard/busy-port-fix/GH-4898/OTP-17448: Fix busy port handling in port_command()
-rw-r--r--erts/emulator/beam/erl_bif_port.c4
-rw-r--r--erts/emulator/test/busy_port_SUITE.erl47
2 files changed, 44 insertions, 7 deletions
diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c
index 40a2fb96d6..5f1efcba6c 100644
--- a/erts/emulator/beam/erl_bif_port.c
+++ b/erts/emulator/beam/erl_bif_port.c
@@ -211,8 +211,8 @@ BIF_RETTYPE erts_internal_port_command_3(BIF_ALIST_3)
ERTS_BIF_PREP_RET(res, am_false);
else {
erts_suspend(BIF_P, ERTS_PROC_LOCK_MAIN, prt);
- ERTS_BIF_PREP_YIELD3(res, bif_export[BIF_erts_internal_port_command_3],
- BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3);
+ ERTS_BIF_YIELD3(bif_export[BIF_erts_internal_port_command_3],
+ BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3);
}
break;
case ERTS_PORT_OP_BUSY_SCHEDULED:
diff --git a/erts/emulator/test/busy_port_SUITE.erl b/erts/emulator/test/busy_port_SUITE.erl
index 4e7004a424..6f80885641 100644
--- a/erts/emulator/test/busy_port_SUITE.erl
+++ b/erts/emulator/test/busy_port_SUITE.erl
@@ -27,7 +27,8 @@
hard_busy_driver/1, soft_busy_driver/1,
scheduling_delay_busy/1,
scheduling_delay_busy_nosuspend/1,
- scheduling_busy_link/1]).
+ scheduling_busy_link/1,
+ busy_with_signals/1]).
-include_lib("common_test/include/ct.hrl").
@@ -43,7 +44,7 @@ all() ->
no_trap_exit, no_trap_exit_unlinked, trap_exit,
multiple_writers, hard_busy_driver, soft_busy_driver,
scheduling_delay_busy,scheduling_delay_busy_nosuspend,
- scheduling_busy_link].
+ scheduling_busy_link, busy_with_signals].
init_per_testcase(_Case, Config) when is_list(Config) ->
Killer = spawn(fun() -> killer_loop([]) end),
@@ -806,13 +807,49 @@ replace_args(Tuple,Vars) when is_tuple(Tuple) ->
replace_args(Else,_Vars) ->
Else.
+busy_with_signals(Config) when is_list(Config) ->
+ ct:timetrap({seconds, 30}),
+
+ start_busy_driver(Config),
+ {_Owner, Port} = get_slave(),
+ Self = self(),
+
+ process_flag(scheduler, 1),
+ process_flag(priority, high),
+
+ {Pid, Mon} = spawn_opt(fun () ->
+ process_flag(trap_exit, true),
+ Self ! prepared,
+ receive go -> ok end,
+ port_command(Port, "plong")
+ end,
+ [monitor,
+ {scheduler, 1},
+ {priority, normal}]),
+ receive prepared -> ok end,
+ ok = command(lock),
+ Pid ! go,
+ flood_with_exit_signals(Pid, 1000000),
+ ok = command(unlock),
+ receive
+ {'DOWN', Mon, process, Pid, Reason} ->
+ normal = Reason
+ end,
+ ok = command(stop),
+ ok.
+
+flood_with_exit_signals(_Pid, 0) ->
+ ok;
+flood_with_exit_signals(Pid, N) ->
+ exit(Pid, pling),
+ flood_with_exit_signals(Pid, N-1).
+
+%%% Utilities.
+
pal(_F,_A) -> ok.
%pal(Format,Args) ->
% ct:pal("~p "++Format,[self()|Args]).
% erlang:display(lists:flatten(io_lib:format("~p "++Format,[self()|Args]))).
-
-
-%%% Utilities.
chk_range(Min, Val, Max) when Min =< Val, Val =< Max ->
ok;