Skip to content
This repository was archived by the owner on Jun 10, 2024. It is now read-only.

Commit 152ebd1

Browse files
committed
demonitor/1
Resolves #169
1 parent 92f71d9 commit 152ebd1

File tree

6 files changed

+195
-1
lines changed

6 files changed

+195
-1
lines changed

lumen_runtime/src/otp/erlang.rs

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub mod ceil_1;
3939
pub mod concatenate_2;
4040
pub mod convert_time_unit_3;
4141
pub mod delete_element_2;
42+
pub mod demonitor_1;
4243
pub mod demonitor_2;
4344
pub mod div_2;
4445
pub mod divide_2;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// wasm32 proptest cannot be compiled at the same time as non-wasm32 proptest, so disable tests that
2+
// use proptest completely for wasm32
3+
//
4+
// See https://github.com/rust-lang/cargo/issues/4866
5+
#[cfg(all(not(target_arch = "wasm32"), test))]
6+
mod test;
7+
8+
use std::convert::TryInto;
9+
10+
use liblumen_alloc::erts::exception;
11+
use liblumen_alloc::erts::process::Process;
12+
use liblumen_alloc::erts::term::{Boxed, Reference, Term};
13+
14+
use lumen_runtime_macros::native_implemented_function;
15+
16+
use crate::otp::erlang::demonitor_2::demonitor;
17+
18+
#[native_implemented_function(demonitor/1)]
19+
pub fn native(process: &Process, reference: Term) -> exception::Result {
20+
let reference_reference: Boxed<Reference> = reference.try_into()?;
21+
22+
demonitor(process, &reference_reference, Default::default())
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
mod with_reference;
2+
3+
use proptest::prop_assert_eq;
4+
use proptest::test_runner::{Config, TestRunner};
5+
6+
use liblumen_alloc::badarg;
7+
use liblumen_alloc::erts::term::Term;
8+
9+
use crate::otp::erlang::demonitor_1::native;
10+
use crate::scheduler::with_process_arc;
11+
use crate::test::strategy;
12+
13+
#[test]
14+
fn without_reference_errors_badarg() {
15+
with_process_arc(|arc_process| {
16+
TestRunner::new(Config::with_source_file(file!()))
17+
.run(
18+
&strategy::term::is_not_reference(arc_process.clone()),
19+
|reference| {
20+
prop_assert_eq!(native(&arc_process, reference), Err(badarg!().into()));
21+
22+
Ok(())
23+
},
24+
)
25+
.unwrap();
26+
});
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
mod with_monitor;
2+
3+
use super::*;
4+
5+
use liblumen_alloc::erts::process::code::stack::frame::Placement;
6+
use liblumen_alloc::erts::term::atom_unchecked;
7+
8+
use crate::otp::erlang::exit_1;
9+
use crate::otp::erlang::monitor_2;
10+
use crate::process;
11+
use crate::process::SchedulerDependentAlloc;
12+
use crate::scheduler::Scheduler;
13+
use crate::test::{has_message, monitor_count, monitored_count};
14+
15+
#[test]
16+
fn without_monitor_returns_true() {
17+
with_process_arc(|monitoring_arc_process| {
18+
let reference = monitoring_arc_process.next_reference().unwrap();
19+
20+
assert_eq!(native(&monitoring_arc_process, reference), Ok(true.into()))
21+
});
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
use super::*;
2+
3+
#[test]
4+
fn returns_true() {
5+
with_process_arc(|monitoring_arc_process| {
6+
let monitored_arc_process = process::test(&monitoring_arc_process);
7+
8+
let monitor_reference = monitor_2::native(
9+
&monitoring_arc_process,
10+
r#type(),
11+
monitored_arc_process.pid_term(),
12+
)
13+
.unwrap();
14+
15+
let monitored_monitor_count_before = monitor_count(&monitored_arc_process);
16+
let monitoring_monitored_count_before = monitored_count(&monitoring_arc_process);
17+
18+
assert_eq!(
19+
native(&monitoring_arc_process, monitor_reference),
20+
Ok(true.into())
21+
);
22+
23+
let monitored_monitor_count_after = monitor_count(&monitored_arc_process);
24+
let monitoring_monitored_count_after = monitored_count(&monitoring_arc_process);
25+
26+
assert_eq!(
27+
monitored_monitor_count_after,
28+
monitored_monitor_count_before - 1
29+
);
30+
assert_eq!(
31+
monitoring_monitored_count_after,
32+
monitoring_monitored_count_before - 1
33+
);
34+
});
35+
}
36+
37+
#[test]
38+
fn does_not_flush_existing_message() {
39+
with_process_arc(|monitoring_arc_process| {
40+
let monitored_arc_process = process::test(&monitoring_arc_process);
41+
let monitored_pid_term = monitored_arc_process.pid_term();
42+
43+
let monitor_reference =
44+
monitor_2::native(&monitoring_arc_process, r#type(), monitored_pid_term).unwrap();
45+
46+
let reason = atom_unchecked("normal");
47+
exit_1::place_frame_with_arguments(&monitored_arc_process, Placement::Replace, reason)
48+
.unwrap();
49+
50+
assert!(Scheduler::current().run_through(&monitored_arc_process));
51+
52+
assert!(monitored_arc_process.is_exiting());
53+
assert!(!monitoring_arc_process.is_exiting());
54+
55+
let tag = atom_unchecked("DOWN");
56+
57+
assert!(has_message(
58+
&monitoring_arc_process,
59+
monitoring_arc_process
60+
.tuple_from_slice(&[tag, monitor_reference, r#type(), monitored_pid_term, reason])
61+
.unwrap()
62+
));
63+
64+
assert_eq!(
65+
native(&monitoring_arc_process, monitor_reference),
66+
Ok(true.into())
67+
);
68+
69+
assert!(has_message(
70+
&monitoring_arc_process,
71+
monitoring_arc_process
72+
.tuple_from_slice(&[tag, monitor_reference, r#type(), monitored_pid_term, reason])
73+
.unwrap()
74+
));
75+
});
76+
}
77+
78+
#[test]
79+
fn prevents_future_messages() {
80+
with_process_arc(|monitoring_arc_process| {
81+
let monitored_arc_process = process::test(&monitoring_arc_process);
82+
let monitored_pid_term = monitored_arc_process.pid_term();
83+
84+
let monitor_reference =
85+
monitor_2::native(&monitoring_arc_process, r#type(), monitored_pid_term).unwrap();
86+
87+
let reason = atom_unchecked("normal");
88+
let tag = atom_unchecked("DOWN");
89+
90+
assert!(!has_message(
91+
&monitoring_arc_process,
92+
monitoring_arc_process
93+
.tuple_from_slice(&[tag, monitor_reference, r#type(), monitored_pid_term, reason])
94+
.unwrap()
95+
));
96+
97+
assert_eq!(
98+
native(&monitoring_arc_process, monitor_reference),
99+
Ok(true.into())
100+
);
101+
102+
exit_1::place_frame_with_arguments(&monitored_arc_process, Placement::Replace, reason)
103+
.unwrap();
104+
105+
assert!(Scheduler::current().run_through(&monitored_arc_process));
106+
107+
assert!(monitored_arc_process.is_exiting());
108+
assert!(!monitoring_arc_process.is_exiting());
109+
110+
assert!(!has_message(
111+
&monitoring_arc_process,
112+
monitoring_arc_process
113+
.tuple_from_slice(&[tag, monitor_reference, r#type(), monitored_pid_term, reason])
114+
.unwrap()
115+
));
116+
});
117+
}
118+
119+
fn r#type() -> Term {
120+
atom_unchecked("process")
121+
}

lumen_runtime/src/otp/erlang/demonitor_2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub fn native(process: &Process, reference: Term, options: Term) -> exception::R
2929

3030
// Private
3131

32-
fn demonitor(
32+
pub(in crate::otp::erlang) fn demonitor(
3333
monitoring_process: &Process,
3434
reference: &Reference,
3535
Options { flush, info }: Options,

0 commit comments

Comments
 (0)