File tree Expand file tree Collapse file tree 5 files changed +43
-18
lines changed Expand file tree Collapse file tree 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 {}
2222impl Thread {
2323 // unsafe: see thread::Builder::spawn_unchecked for safety requirements
2424 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) ;
2626 let mut native: libc:: pthread_t = mem:: zeroed ( ) ;
2727 let mut attr: libc:: pthread_attr_t = mem:: zeroed ( ) ;
2828 assert_eq ! ( libc:: pthread_attr_init( & mut attr) , 0 ) ;
2929
3030 let stack_size = cmp:: max ( stack, min_stack_size ( & attr) ) ;
3131 assert_eq ! ( libc:: pthread_attr_setstacksize( & mut attr, stack_size) , 0 ) ;
3232
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+ ) ;
3439 assert_eq ! ( libc:: pthread_attr_destroy( & mut attr) , 0 ) ;
3540
3641 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) ;
3745 Err ( io:: Error :: from_raw_os_error ( ret) )
3846 } else {
39- mem:: forget ( p) ; // ownership passed to pthread_create
4047 Ok ( Thread { id : native } )
4148 } ;
4249
Original file line number Diff line number Diff line change @@ -49,21 +49,23 @@ impl Thread {
4949 p : Box < dyn FnOnce ( ) > ,
5050 core_id : isize ,
5151 ) -> io:: Result < Thread > {
52- let p = box p;
52+ let mut p = mem :: ManuallyDrop :: new ( box p) ;
5353 let mut tid: Tid = u32:: MAX ;
5454 let ret = abi:: spawn (
5555 & mut tid as * mut Tid ,
5656 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 ,
5858 Priority :: into ( NORMAL_PRIO ) ,
5959 core_id,
6060 ) ;
6161
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 ) ;
6666 Err ( io:: Error :: new ( io:: ErrorKind :: Other , "Unable to create thread!" ) )
67+ } else {
68+ Ok ( Thread { tid : tid } )
6769 } ;
6870
6971 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(
4343impl Thread {
4444 // unsafe: see thread::Builder::spawn_unchecked for safety requirements
4545 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) ;
4747 let mut native: libc:: pthread_t = mem:: zeroed ( ) ;
4848 let mut attr: libc:: pthread_attr_t = mem:: zeroed ( ) ;
4949 assert_eq ! ( libc:: pthread_attr_init( & mut attr) , 0 ) ;
@@ -65,13 +65,20 @@ impl Thread {
6565 }
6666 } ;
6767
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+ ) ;
6974 assert_eq ! ( libc:: pthread_attr_destroy( & mut attr) , 0 ) ;
7075
7176 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) ;
7280 Err ( io:: Error :: from_raw_os_error ( ret) )
7381 } else {
74- mem:: forget ( p) ; // ownership passed to pthread_create
7582 Ok ( Thread { id : native } )
7683 } ;
7784
Original file line number Diff line number Diff line change @@ -31,7 +31,7 @@ unsafe fn pthread_attr_setstacksize(
3131impl Thread {
3232 // unsafe: see thread::Builder::spawn_unchecked for safety requirements
3333 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) ;
3535 let mut native: libc:: pthread_t = mem:: zeroed ( ) ;
3636 let mut attr: libc:: pthread_attr_t = mem:: zeroed ( ) ;
3737 assert_eq ! ( libc:: pthread_attr_init( & mut attr) , 0 ) ;
@@ -53,13 +53,20 @@ impl Thread {
5353 }
5454 } ;
5555
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+ ) ;
5762 assert_eq ! ( libc:: pthread_attr_destroy( & mut attr) , 0 ) ;
5863
5964 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) ;
6068 Err ( io:: Error :: from_raw_os_error ( ret) )
6169 } else {
62- mem:: forget ( p) ; // ownership passed to pthread_create
6370 Ok ( Thread { id : native } )
6471 } ;
6572
Original file line number Diff line number Diff line change @@ -20,7 +20,7 @@ pub struct Thread {
2020impl Thread {
2121 // unsafe: see thread::Builder::spawn_unchecked for safety requirements
2222 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) ;
2424
2525 // FIXME On UNIX, we guard against stack sizes that are too small but
2626 // that's because pthreads enforces that stacks are at least
@@ -34,15 +34,17 @@ impl Thread {
3434 ptr:: null_mut ( ) ,
3535 stack_size,
3636 thread_start,
37- & * p as * const _ as * mut _ ,
37+ & mut * p as & mut Box < dyn FnOnce ( ) > as * mut _ as * mut _ ,
3838 c:: STACK_SIZE_PARAM_IS_A_RESERVATION ,
3939 ptr:: null_mut ( ) ,
4040 ) ;
4141
4242 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) ;
4346 Err ( io:: Error :: last_os_error ( ) )
4447 } else {
45- mem:: forget ( p) ; // ownership passed to CreateThread
4648 Ok ( Thread { handle : Handle :: new ( ret) } )
4749 } ;
4850
You can’t perform that action at this time.
0 commit comments