7
7
//! The thread pool is implemented entirely using
8
8
//! the threading utilities in [`crate::thread`].
9
9
10
- use std:: sync:: {
11
- atomic:: { AtomicUsize , Ordering } ,
12
- Arc ,
10
+ use std:: {
11
+ panic:: { self , UnwindSafe } ,
12
+ sync:: {
13
+ atomic:: { AtomicUsize , Ordering } ,
14
+ Arc ,
15
+ } ,
13
16
} ;
14
17
15
18
use crossbeam_channel:: { Receiver , Sender } ;
@@ -25,13 +28,13 @@ pub struct Pool {
25
28
// so that the channel is actually closed
26
29
// before we join the worker threads!
27
30
job_sender : Sender < Job > ,
28
- _handles : Vec < JoinHandle > ,
31
+ _handles : Box < [ JoinHandle ] > ,
29
32
extant_tasks : Arc < AtomicUsize > ,
30
33
}
31
34
32
35
struct Job {
33
36
requested_intent : ThreadIntent ,
34
- f : Box < dyn FnOnce ( ) + Send + ' static > ,
37
+ f : Box < dyn FnOnce ( ) + Send + UnwindSafe + ' static > ,
35
38
}
36
39
37
40
impl Pool {
@@ -47,6 +50,7 @@ impl Pool {
47
50
let handle = Builder :: new ( INITIAL_INTENT )
48
51
. stack_size ( STACK_SIZE )
49
52
. name ( "Worker" . into ( ) )
53
+ . allow_leak ( true )
50
54
. spawn ( {
51
55
let extant_tasks = Arc :: clone ( & extant_tasks) ;
52
56
let job_receiver: Receiver < Job > = job_receiver. clone ( ) ;
@@ -58,7 +62,8 @@ impl Pool {
58
62
current_intent = job. requested_intent ;
59
63
}
60
64
extant_tasks. fetch_add ( 1 , Ordering :: SeqCst ) ;
61
- ( job. f ) ( ) ;
65
+ // discard the panic, we should've logged the backtrace already
66
+ _ = panic:: catch_unwind ( job. f ) ;
62
67
extant_tasks. fetch_sub ( 1 , Ordering :: SeqCst ) ;
63
68
}
64
69
}
@@ -68,12 +73,12 @@ impl Pool {
68
73
handles. push ( handle) ;
69
74
}
70
75
71
- Pool { _handles : handles, extant_tasks, job_sender }
76
+ Pool { _handles : handles. into_boxed_slice ( ) , extant_tasks, job_sender }
72
77
}
73
78
74
79
pub fn spawn < F > ( & self , intent : ThreadIntent , f : F )
75
80
where
76
- F : FnOnce ( ) + Send + ' static ,
81
+ F : FnOnce ( ) + Send + UnwindSafe + ' static ,
77
82
{
78
83
let f = Box :: new ( move || {
79
84
if cfg ! ( debug_assertions) {
0 commit comments