@@ -115,25 +115,25 @@ pub struct ParallelGuard {
115115}
116116
117117impl ParallelGuard {
118- #[ inline]
119- pub fn new ( ) -> Self {
120- ParallelGuard { panic : Mutex :: new ( None ) }
121- }
122-
123118 pub fn run < R > ( & self , f : impl FnOnce ( ) -> R ) -> Option < R > {
124119 catch_unwind ( AssertUnwindSafe ( f) )
125120 . map_err ( |err| {
126121 * self . panic . lock ( ) = Some ( err) ;
127122 } )
128123 . ok ( )
129124 }
125+ }
130126
131- #[ inline]
132- pub fn unwind ( self ) {
133- if let Some ( panic) = self . panic . into_inner ( ) {
134- resume_unwind ( panic) ;
135- }
127+ /// This gives access to a fresh parallel guard in the closure and will unwind any panics
128+ /// caught in it after the closure returns.
129+ #[ inline]
130+ pub fn parallel_guard < R > ( f : impl FnOnce ( & ParallelGuard ) -> R ) -> R {
131+ let guard = ParallelGuard { panic : Mutex :: new ( None ) } ;
132+ let ret = f ( & guard) ;
133+ if let Some ( panic) = guard. panic . into_inner ( ) {
134+ resume_unwind ( panic) ;
136135 }
136+ ret
137137}
138138
139139cfg_if ! {
@@ -231,38 +231,38 @@ cfg_if! {
231231 where A : FnOnce ( ) -> RA ,
232232 B : FnOnce ( ) -> RB
233233 {
234- let guard = ParallelGuard :: new( ) ;
235- let a = guard. run( oper_a) ;
236- let b = guard. run( oper_b) ;
237- guard. unwind( ) ;
234+ let ( a, b) = parallel_guard( |guard| {
235+ let a = guard. run( oper_a) ;
236+ let b = guard. run( oper_b) ;
237+ ( a, b)
238+ } ) ;
238239 ( a. unwrap( ) , b. unwrap( ) )
239240 }
240241
241242 #[ macro_export]
242243 macro_rules! parallel {
243244 ( $( $blocks: block) , * ) => { {
244- let mut guard = $crate :: sync:: ParallelGuard :: new ( ) ;
245- $( guard. run( || $blocks) ; ) *
246- guard . unwind ( ) ;
245+ $crate :: sync:: parallel_guard ( |guard| {
246+ $( guard. run( || $blocks) ; ) *
247+ } ) ;
247248 } }
248249 }
249250
250251 pub fn par_for_each_in<T : IntoIterator >( t: T , mut for_each: impl FnMut ( T :: Item ) + Sync + Send ) {
251- let guard = ParallelGuard :: new ( ) ;
252- t. into_iter( ) . for_each( |i| {
253- guard. run( || for_each( i) ) ;
254- } ) ;
255- guard . unwind ( ) ;
252+ parallel_guard ( | guard| {
253+ t. into_iter( ) . for_each( |i| {
254+ guard. run( || for_each( i) ) ;
255+ } ) ;
256+ } )
256257 }
257258
258259 pub fn par_map<T : IntoIterator , R , C : FromIterator <R >>(
259260 t: T ,
260261 mut map: impl FnMut ( <<T as IntoIterator >:: IntoIter as Iterator >:: Item ) -> R ,
261262 ) -> C {
262- let guard = ParallelGuard :: new( ) ;
263- let r = t. into_iter( ) . filter_map( |i| guard. run( || map( i) ) ) . collect( ) ;
264- guard. unwind( ) ;
265- r
263+ parallel_guard( |guard| {
264+ t. into_iter( ) . filter_map( |i| guard. run( || map( i) ) ) . collect( )
265+ } )
266266 }
267267
268268 pub use std:: rc:: Rc as Lrc ;
@@ -382,10 +382,11 @@ cfg_if! {
382382 let ( a, b) = rayon:: join( move || FromDyn :: from( oper_a. into_inner( ) ( ) ) , move || FromDyn :: from( oper_b. into_inner( ) ( ) ) ) ;
383383 ( a. into_inner( ) , b. into_inner( ) )
384384 } else {
385- let guard = ParallelGuard :: new( ) ;
386- let a = guard. run( oper_a) ;
387- let b = guard. run( oper_b) ;
388- guard. unwind( ) ;
385+ let ( a, b) = parallel_guard( |guard| {
386+ let a = guard. run( oper_a) ;
387+ let b = guard. run( oper_b) ;
388+ ( a, b)
389+ } ) ;
389390 ( a. unwrap( ) , b. unwrap( ) )
390391 }
391392 }
@@ -421,10 +422,10 @@ cfg_if! {
421422 // of a single threaded rustc.
422423 parallel!( impl $fblock [ ] [ $( $blocks) , * ] ) ;
423424 } else {
424- let guard = $crate :: sync:: ParallelGuard :: new ( ) ;
425- guard. run( || $fblock) ;
426- $( guard. run( || $blocks) ; ) *
427- guard . unwind ( ) ;
425+ $crate :: sync:: parallel_guard ( |guard| {
426+ guard. run( || $fblock) ;
427+ $( guard. run( || $blocks) ; ) *
428+ } ) ;
428429 }
429430 } ;
430431 }
@@ -435,20 +436,18 @@ cfg_if! {
435436 t: T ,
436437 for_each: impl Fn ( I ) + DynSync + DynSend
437438 ) {
438- if mode:: is_dyn_thread_safe( ) {
439- let for_each = FromDyn :: from( for_each) ;
440- let guard = ParallelGuard :: new( ) ;
441- t. into_par_iter( ) . for_each( |i| {
442- guard. run( || for_each( i) ) ;
443- } ) ;
444- guard. unwind( ) ;
445- } else {
446- let guard = ParallelGuard :: new( ) ;
447- t. into_iter( ) . for_each( |i| {
448- guard. run( || for_each( i) ) ;
449- } ) ;
450- guard. unwind( ) ;
451- }
439+ parallel_guard( |guard| {
440+ if mode:: is_dyn_thread_safe( ) {
441+ let for_each = FromDyn :: from( for_each) ;
442+ t. into_par_iter( ) . for_each( |i| {
443+ guard. run( || for_each( i) ) ;
444+ } ) ;
445+ } else {
446+ t. into_iter( ) . for_each( |i| {
447+ guard. run( || for_each( i) ) ;
448+ } ) ;
449+ }
450+ } ) ;
452451 }
453452
454453 pub fn par_map<
@@ -460,18 +459,14 @@ cfg_if! {
460459 t: T ,
461460 map: impl Fn ( I ) -> R + DynSync + DynSend
462461 ) -> C {
463- if mode:: is_dyn_thread_safe( ) {
464- let map = FromDyn :: from( map) ;
465- let guard = ParallelGuard :: new( ) ;
466- let r = t. into_par_iter( ) . filter_map( |i| guard. run( || map( i) ) ) . collect( ) ;
467- guard. unwind( ) ;
468- r
469- } else {
470- let guard = ParallelGuard :: new( ) ;
471- let r = t. into_iter( ) . filter_map( |i| guard. run( || map( i) ) ) . collect( ) ;
472- guard. unwind( ) ;
473- r
474- }
462+ parallel_guard( |guard| {
463+ if mode:: is_dyn_thread_safe( ) {
464+ let map = FromDyn :: from( map) ;
465+ t. into_par_iter( ) . filter_map( |i| guard. run( || map( i) ) ) . collect( )
466+ } else {
467+ t. into_iter( ) . filter_map( |i| guard. run( || map( i) ) ) . collect( )
468+ }
469+ } )
475470 }
476471
477472 /// This makes locks panic if they are already held.
0 commit comments