@@ -4,21 +4,22 @@ use crate::mem;
44use crate :: ptr;
55use crate :: sys:: mutex:: Mutex ;
66use crate :: time:: Duration ;
7- use crate :: sync:: { Arc , atomic:: { AtomicUsize , Ordering :: SeqCst } } ;
7+ use crate :: sync:: { Arc , atomic:: { AtomicU8 , Ordering :: SeqCst } } ;
88
99use crate :: sys:: ffi:: * ;
1010use crate :: sys:: thread_local;
1111
12- const RUNNING : usize = 0 ;
13- const DETACHED : usize = 1 ;
14- const EXITED : usize = 2 ;
12+ const PENDING : u8 = 0 ;
13+ const RUNNING : u8 = 1 ;
14+ const DETACHED : u8 = 2 ;
15+ const EXITED : u8 = 3 ;
1516
1617pub const DEFAULT_MIN_STACK_SIZE : usize = 4096 ;
1718
1819pub struct Thread {
1920 id : TaskHandle_t ,
2021 join_mutex : Arc < Mutex > ,
21- state : Arc < AtomicUsize > ,
22+ state : Arc < AtomicU8 > ,
2223}
2324
2425unsafe impl Send for Thread { }
@@ -29,27 +30,29 @@ impl Thread {
2930 pub unsafe fn new ( name : Option < & CStr > , stack : usize , p : Box < dyn FnOnce ( ) > )
3031 -> io:: Result < Thread > {
3132 let join_mutex = Arc :: new ( Mutex :: new ( ) ) ;
32- let state = Arc :: new ( AtomicUsize :: new ( RUNNING ) ) ;
33+ let state = Arc :: new ( AtomicU8 :: new ( PENDING ) ) ;
3334
3435 let arg = box ( join_mutex. clone ( ) , state. clone ( ) , box p) ;
3536
3637 let name = name. unwrap_or_else ( || CStr :: from_bytes_with_nul_unchecked ( b"\0 " ) ) ;
3738
3839 let mut thread = Thread { id : ptr:: null_mut ( ) , join_mutex, state } ;
3940
40- thread . join_mutex . lock ( ) ;
41+ let arg = Box :: into_raw ( arg ) ;
4142
4243 let res = xTaskCreate (
4344 thread_start,
4445 name. as_ptr ( ) ,
4546 stack as u32 ,
46- Box :: into_raw ( arg) as * mut libc:: c_void ,
47+ arg as * mut libc:: c_void ,
4748 5 ,
4849 & mut thread. id ,
4950 ) ;
5051
5152 if res != pdTRUE {
52- thread. join_mutex . unlock ( ) ;
53+ if thread. state . load ( SeqCst ) == PENDING {
54+ drop ( Box :: from_raw ( arg) ) ;
55+ }
5356
5457 if res == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY {
5558 return Err ( io:: Error :: new ( io:: ErrorKind :: Other , "could not allocate required memory for thread" ) ) ;
@@ -62,9 +65,13 @@ impl Thread {
6265
6366 extern fn thread_start ( arg : * mut libc:: c_void ) -> * mut libc:: c_void {
6467 unsafe {
65- let arg = Box :: < ( Arc < Mutex > , Arc < AtomicUsize > , Box < Box < dyn FnOnce ( ) > > ) > :: from_raw ( arg as * mut _ ) ;
68+ let arg = Box :: < ( Arc < Mutex > , Arc < AtomicU8 > , Box < Box < dyn FnOnce ( ) > > ) > :: from_raw ( arg as * mut _ ) ;
6669 let ( join_mutex, state, main) = * arg;
6770
71+ join_mutex. lock ( ) ;
72+
73+ state. store ( RUNNING , SeqCst ) ;
74+
6875 main ( ) ;
6976 thread_local:: cleanup ( ) ;
7077
@@ -119,6 +126,8 @@ impl Thread {
119126 unsafe {
120127 assert ! ( self . id != xTaskGetCurrentTaskHandle( ) ) ;
121128
129+ while self . state . load ( SeqCst ) == PENDING { }
130+
122131 // Just wait for the thread to finish, the rest is handled by `Drop`.
123132 self . join_mutex . lock ( ) ;
124133 self . join_mutex . unlock ( ) ;
0 commit comments