]>
Commit | Line | Data |
---|---|---|
532ac7d7 XL |
1 | extern crate rayon; |
2 | ||
3 | use rayon::prelude::*; | |
e74abb32 XL |
4 | use rayon::ThreadPoolBuilder; |
5 | use std::ops::Range; | |
6 | use std::panic::{self, UnwindSafe}; | |
7 | use std::sync::atomic::{AtomicUsize, Ordering}; | |
8 | ||
9 | const ITER: Range<i32> = 0..0x1_0000; | |
10 | const PANIC: i32 = 0xC000; | |
11 | ||
12 | fn check(&i: &i32) { | |
13 | if i == PANIC { | |
14 | panic!("boom") | |
15 | } | |
16 | } | |
532ac7d7 XL |
17 | |
18 | #[test] | |
19 | #[should_panic(expected = "boom")] | |
20 | fn iter_panic() { | |
e74abb32 XL |
21 | ITER.into_par_iter().for_each(|i| check(&i)); |
22 | } | |
23 | ||
24 | #[test] | |
25 | fn iter_panic_fuse() { | |
26 | // We only use a single thread in order to make the behavior | |
27 | // of 'panic_fuse' deterministic | |
28 | let pool = ThreadPoolBuilder::new().num_threads(1).build().unwrap(); | |
29 | ||
30 | pool.install(|| { | |
31 | fn count(iter: impl ParallelIterator + UnwindSafe) -> usize { | |
32 | let count = AtomicUsize::new(0); | |
33 | let result = panic::catch_unwind(|| { | |
34 | iter.for_each(|_| { | |
35 | count.fetch_add(1, Ordering::Relaxed); | |
36 | }); | |
37 | }); | |
38 | assert!(result.is_err()); | |
39 | count.into_inner() | |
532ac7d7 | 40 | } |
e74abb32 XL |
41 | |
42 | // Without `panic_fuse()`, we'll reach every item except the panicking one. | |
43 | let expected = ITER.len() - 1; | |
44 | let iter = ITER.into_par_iter().with_max_len(1); | |
45 | assert_eq!(count(iter.clone().inspect(check)), expected); | |
46 | ||
47 | // With `panic_fuse()` anywhere in the chain, we'll reach fewer items. | |
48 | assert!(count(iter.clone().inspect(check).panic_fuse()) < expected); | |
49 | assert!(count(iter.clone().panic_fuse().inspect(check)) < expected); | |
50 | ||
51 | // Try in reverse to be sure we hit the producer case. | |
52 | assert!(count(iter.clone().panic_fuse().inspect(check).rev()) < expected); | |
532ac7d7 XL |
53 | }); |
54 | } |