aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/test')
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_receive.erl89
1 files changed, 89 insertions, 0 deletions
diff --git a/lib/hipe/test/basic_SUITE_data/basic_receive.erl b/lib/hipe/test/basic_SUITE_data/basic_receive.erl
index 5f865d7b7a..20e3f350e8 100644
--- a/lib/hipe/test/basic_SUITE_data/basic_receive.erl
+++ b/lib/hipe/test/basic_SUITE_data/basic_receive.erl
@@ -12,6 +12,7 @@ test() ->
ok = test_wait_timeout(),
ok = test_double_timeout(),
ok = test_reschedule(),
+ ok = test_recv_mark(),
ok.
%%--------------------------------------------------------------------
@@ -54,3 +55,91 @@ doit(First) ->
erts_debug:set_internal_state(hipe_test_reschedule_suspend, 1).
%%--------------------------------------------------------------------
+%% Check that we cannot cause a recv_mark,recv_set pair to misbehave and
+%% deadlock the process.
+
+test_recv_mark() ->
+ ok = test_recv_mark(fun disturber_nop/0),
+ ok = test_recv_mark(fun disturber_receive/0),
+ ok = test_recv_mark(fun disturber_other/0),
+ ok = test_recv_mark(fun disturber_recurse/0),
+ ok = test_recv_mark_after(self(), fun disturber_after_recurse/0, false),
+ ok = test_recv_mark(fun disturber_other_recurse/0),
+ ok = test_recv_mark(fun disturber_other_after/0),
+ ok = test_recv_mark_nested().
+
+test_recv_mark(Disturber) ->
+ Ref = make_ref(),
+ self() ! Ref,
+ Disturber(),
+ receive Ref -> ok
+ after 0 -> error(failure)
+ end.
+
+disturber_nop() -> ok.
+
+disturber_receive() ->
+ self() ! message,
+ receive message -> ok end.
+
+disturber_other() ->
+ Ref = make_ref(),
+ self() ! Ref,
+ receive Ref -> ok end.
+
+disturber_recurse() ->
+ aborted = (catch test_recv_mark(fun() -> throw(aborted) end)),
+ ok.
+
+test_recv_mark_after(Recipient, Disturber, IsInner) ->
+ Ref = make_ref(),
+ Recipient ! Ref,
+ Disturber(),
+ receive
+ Ref -> ok
+ after 0 ->
+ case IsInner of
+ true -> expected;
+ false -> error(failure)
+ end
+ end.
+
+disturber_after_recurse() ->
+ NoOp = fun() -> ok end,
+ BlackHole = spawn(NoOp),
+ expected = test_recv_mark_after(BlackHole, NoOp, true),
+ ok.
+
+disturber_other_recurse() ->
+ aborted = (catch disturber_other_recurse(fun() -> throw(aborted) end)),
+ ok.
+
+disturber_other_recurse(InnerD) ->
+ Ref = make_ref(),
+ self() ! Ref,
+ InnerD(),
+ receive Ref -> ok
+ after 0 -> error(failure)
+ end.
+
+disturber_other_after() ->
+ BlackHole = spawn(fun() -> ok end),
+ Ref = make_ref(),
+ BlackHole ! Ref,
+ receive Ref -> error(imposible)
+ after 0 -> ok
+ end.
+
+test_recv_mark_nested() ->
+ Ref1 = make_ref(),
+ self() ! Ref1,
+ begin
+ Ref2 = make_ref(),
+ self() ! Ref2,
+ receive Ref2 -> ok end
+ end,
+ receive Ref1 -> ok
+ after 0 -> error(failure)
+ end.
+
+%%--------------------------------------------------------------------