File tree 5 files changed +43
-18
lines changed
5 files changed +43
-18
lines changed Original file line number Diff line number Diff line change @@ -22,21 +22,28 @@ unsafe impl Sync for Thread {}
22
22
impl Thread {
23
23
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
24
24
pub unsafe fn new ( stack : usize , p : Box < dyn FnOnce ( ) > ) -> io:: Result < Thread > {
25
- let p = box p;
25
+ let mut p = mem :: ManuallyDrop :: new ( box p) ;
26
26
let mut native: libc:: pthread_t = mem:: zeroed ( ) ;
27
27
let mut attr: libc:: pthread_attr_t = mem:: zeroed ( ) ;
28
28
assert_eq ! ( libc:: pthread_attr_init( & mut attr) , 0 ) ;
29
29
30
30
let stack_size = cmp:: max ( stack, min_stack_size ( & attr) ) ;
31
31
assert_eq ! ( libc:: pthread_attr_setstacksize( & mut attr, stack_size) , 0 ) ;
32
32
33
- let ret = libc:: pthread_create ( & mut native, & attr, thread_start, & * p as * const _ as * mut _ ) ;
33
+ let ret = libc:: pthread_create (
34
+ & mut native,
35
+ & attr,
36
+ thread_start,
37
+ & mut * p as & mut Box < dyn FnOnce ( ) > as * mut _ as * mut _ ,
38
+ ) ;
34
39
assert_eq ! ( libc:: pthread_attr_destroy( & mut attr) , 0 ) ;
35
40
36
41
return if ret != 0 {
42
+ // The thread failed to start and as a result p was not consumed. Therefore, it is
43
+ // safe to manually drop it.
44
+ mem:: ManuallyDrop :: drop ( & mut p) ;
37
45
Err ( io:: Error :: from_raw_os_error ( ret) )
38
46
} else {
39
- mem:: forget ( p) ; // ownership passed to pthread_create
40
47
Ok ( Thread { id : native } )
41
48
} ;
42
49
Original file line number Diff line number Diff line change @@ -49,21 +49,23 @@ impl Thread {
49
49
p : Box < dyn FnOnce ( ) > ,
50
50
core_id : isize ,
51
51
) -> io:: Result < Thread > {
52
- let p = box p;
52
+ let mut p = mem :: ManuallyDrop :: new ( box p) ;
53
53
let mut tid: Tid = u32:: MAX ;
54
54
let ret = abi:: spawn (
55
55
& mut tid as * mut Tid ,
56
56
thread_start,
57
- & * p as * const _ as * const u8 as usize ,
57
+ & mut * p as & mut Box < dyn FnOnce ( ) > as * mut _ as * mut u8 as usize ,
58
58
Priority :: into ( NORMAL_PRIO ) ,
59
59
core_id,
60
60
) ;
61
61
62
- return if ret = = 0 {
63
- mem :: forget ( p ) ; // ownership passed to pthread_create
64
- Ok ( Thread { tid : tid } )
65
- } else {
62
+ return if ret ! = 0 {
63
+ // The thread failed to start and as a result p was not consumed. Therefore, it is
64
+ // safe to manually drop it.
65
+ mem :: ManuallyDrop :: drop ( & mut p ) ;
66
66
Err ( io:: Error :: new ( io:: ErrorKind :: Other , "Unable to create thread!" ) )
67
+ } else {
68
+ Ok ( Thread { tid : tid } )
67
69
} ;
68
70
69
71
extern "C" fn thread_start ( main : usize ) {
Original file line number Diff line number Diff line change @@ -43,7 +43,7 @@ unsafe fn pthread_attr_setstacksize(
43
43
impl Thread {
44
44
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
45
45
pub unsafe fn new ( stack : usize , p : Box < dyn FnOnce ( ) > ) -> io:: Result < Thread > {
46
- let p = box p;
46
+ let mut p = mem :: ManuallyDrop :: new ( box p) ;
47
47
let mut native: libc:: pthread_t = mem:: zeroed ( ) ;
48
48
let mut attr: libc:: pthread_attr_t = mem:: zeroed ( ) ;
49
49
assert_eq ! ( libc:: pthread_attr_init( & mut attr) , 0 ) ;
@@ -65,13 +65,20 @@ impl Thread {
65
65
}
66
66
} ;
67
67
68
- let ret = libc:: pthread_create ( & mut native, & attr, thread_start, & * p as * const _ as * mut _ ) ;
68
+ let ret = libc:: pthread_create (
69
+ & mut native,
70
+ & attr,
71
+ thread_start,
72
+ & mut * p as & mut Box < dyn FnOnce ( ) > as * mut _ as * mut _ ,
73
+ ) ;
69
74
assert_eq ! ( libc:: pthread_attr_destroy( & mut attr) , 0 ) ;
70
75
71
76
return if ret != 0 {
77
+ // The thread failed to start and as a result p was not consumed. Therefore, it is
78
+ // safe to manually drop it.
79
+ mem:: ManuallyDrop :: drop ( & mut p) ;
72
80
Err ( io:: Error :: from_raw_os_error ( ret) )
73
81
} else {
74
- mem:: forget ( p) ; // ownership passed to pthread_create
75
82
Ok ( Thread { id : native } )
76
83
} ;
77
84
Original file line number Diff line number Diff line change @@ -31,7 +31,7 @@ unsafe fn pthread_attr_setstacksize(
31
31
impl Thread {
32
32
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
33
33
pub unsafe fn new ( stack : usize , p : Box < dyn FnOnce ( ) > ) -> io:: Result < Thread > {
34
- let p = box p;
34
+ let mut p = mem :: ManuallyDrop :: new ( box p) ;
35
35
let mut native: libc:: pthread_t = mem:: zeroed ( ) ;
36
36
let mut attr: libc:: pthread_attr_t = mem:: zeroed ( ) ;
37
37
assert_eq ! ( libc:: pthread_attr_init( & mut attr) , 0 ) ;
@@ -53,13 +53,20 @@ impl Thread {
53
53
}
54
54
} ;
55
55
56
- let ret = libc:: pthread_create ( & mut native, & attr, thread_start, & * p as * const _ as * mut _ ) ;
56
+ let ret = libc:: pthread_create (
57
+ & mut native,
58
+ & attr,
59
+ thread_start,
60
+ & mut * p as & mut Box < dyn FnOnce ( ) > as * mut _ as * mut _ ,
61
+ ) ;
57
62
assert_eq ! ( libc:: pthread_attr_destroy( & mut attr) , 0 ) ;
58
63
59
64
return if ret != 0 {
65
+ // The thread failed to start and as a result p was not consumed. Therefore, it is
66
+ // safe to manually drop it.
67
+ mem:: ManuallyDrop :: drop ( & mut p) ;
60
68
Err ( io:: Error :: from_raw_os_error ( ret) )
61
69
} else {
62
- mem:: forget ( p) ; // ownership passed to pthread_create
63
70
Ok ( Thread { id : native } )
64
71
} ;
65
72
Original file line number Diff line number Diff line change @@ -20,7 +20,7 @@ pub struct Thread {
20
20
impl Thread {
21
21
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
22
22
pub unsafe fn new ( stack : usize , p : Box < dyn FnOnce ( ) > ) -> io:: Result < Thread > {
23
- let p = box p;
23
+ let mut p = mem :: ManuallyDrop :: new ( box p) ;
24
24
25
25
// FIXME On UNIX, we guard against stack sizes that are too small but
26
26
// that's because pthreads enforces that stacks are at least
@@ -34,15 +34,17 @@ impl Thread {
34
34
ptr:: null_mut ( ) ,
35
35
stack_size,
36
36
thread_start,
37
- & * p as * const _ as * mut _ ,
37
+ & mut * p as & mut Box < dyn FnOnce ( ) > as * mut _ as * mut _ ,
38
38
c:: STACK_SIZE_PARAM_IS_A_RESERVATION ,
39
39
ptr:: null_mut ( ) ,
40
40
) ;
41
41
42
42
return if ret as usize == 0 {
43
+ // The thread failed to start and as a result p was not consumed. Therefore, it is
44
+ // safe to manually drop it.
45
+ mem:: ManuallyDrop :: drop ( & mut p) ;
43
46
Err ( io:: Error :: last_os_error ( ) )
44
47
} else {
45
- mem:: forget ( p) ; // ownership passed to CreateThread
46
48
Ok ( Thread { handle : Handle :: new ( ret) } )
47
49
} ;
48
50
You can’t perform that action at this time.
0 commit comments