1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
use rayon::prelude::*;
use std::panic;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use std::sync::Mutex;
#[test]
fn collect_drop_on_unwind() {
struct Recorddrop<'a>(i64, &'a Mutex<Vec<i64>>);
impl<'a> Drop for Recorddrop<'a> {
fn drop(&mut self) {
self.1.lock().unwrap().push(self.0);
}
}
let test_collect_panic = |will_panic: bool| {
let test_vec_len = 1024;
let panic_point = 740;
let mut inserts = Mutex::new(Vec::new());
let mut drops = Mutex::new(Vec::new());
let mut a = (0..test_vec_len).collect::<Vec<_>>();
let b = (0..test_vec_len).collect::<Vec<_>>();
let _result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
let mut result = Vec::new();
a.par_iter_mut()
.zip(&b)
.map(|(&mut a, &b)| {
if a > panic_point && will_panic {
panic!("unwinding for test");
}
let elt = a + b;
inserts.lock().unwrap().push(elt);
Recorddrop(elt, &drops)
})
.collect_into_vec(&mut result);
// If we reach this point, this must pass
assert_eq!(a.len(), result.len());
}));
let inserts = inserts.get_mut().unwrap();
let drops = drops.get_mut().unwrap();
println!("{:?}", inserts);
println!("{:?}", drops);
assert_eq!(inserts.len(), drops.len(), "Incorrect number of drops");
// sort to normalize order
inserts.sort();
drops.sort();
assert_eq!(inserts, drops, "Incorrect elements were dropped");
};
for &should_panic in &[true, false] {
test_collect_panic(should_panic);
}
}
#[test]
fn collect_drop_on_unwind_zst() {
static INSERTS: AtomicUsize = AtomicUsize::new(0);
static DROPS: AtomicUsize = AtomicUsize::new(0);
struct RecorddropZst;
impl Drop for RecorddropZst {
fn drop(&mut self) {
DROPS.fetch_add(1, Ordering::SeqCst);
}
}
let test_collect_panic = |will_panic: bool| {
INSERTS.store(0, Ordering::SeqCst);
DROPS.store(0, Ordering::SeqCst);
let test_vec_len = 1024;
let panic_point = 740;
let a = (0..test_vec_len).collect::<Vec<_>>();
let _result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
let mut result = Vec::new();
a.par_iter()
.map(|&a| {
if a > panic_point && will_panic {
panic!("unwinding for test");
}
INSERTS.fetch_add(1, Ordering::SeqCst);
RecorddropZst
})
.collect_into_vec(&mut result);
// If we reach this point, this must pass
assert_eq!(a.len(), result.len());
}));
let inserts = INSERTS.load(Ordering::SeqCst);
let drops = DROPS.load(Ordering::SeqCst);
assert_eq!(inserts, drops, "Incorrect number of drops");
assert!(will_panic || drops == test_vec_len)
};
for &should_panic in &[true, false] {
test_collect_panic(should_panic);
}
}
|