@@ -485,11 +485,13 @@ pub(crate) mod _thread {
485485 } ;
486486
487487 match handle_to_join {
488- Some ( ( inner , done_event) ) => {
488+ Some ( ( _inner , done_event) ) => {
489489 // Wait for this thread to finish (infinite timeout)
490+ // Only check done flag to avoid lock ordering issues
491+ // (done_event lock vs inner lock)
490492 let ( lock, cvar) = & * done_event;
491493 let mut done = lock. lock ( ) ;
492- while !* done && inner . lock ( ) . state != ThreadHandleState :: Done {
494+ while !* done {
493495 cvar. wait ( & mut done) ;
494496 }
495497 }
@@ -534,11 +536,14 @@ pub(crate) mod _thread {
534536
535537 // Store the main thread ident (initialized at VM startup)
536538 static MAIN_THREAD_IDENT : AtomicCell < u64 > = AtomicCell :: new ( 0 ) ;
539+ static MAIN_THREAD_INIT : std:: sync:: Once = std:: sync:: Once :: new ( ) ;
537540
538541 /// Initialize the main thread ident. Should be called once at interpreter startup.
539542 pub fn init_main_thread_ident ( ) {
540- let ident = get_ident ( ) ;
541- MAIN_THREAD_IDENT . store ( ident) ;
543+ MAIN_THREAD_INIT . call_once ( || {
544+ let ident = get_ident ( ) ;
545+ MAIN_THREAD_IDENT . store ( ident) ;
546+ } ) ;
542547 }
543548
544549 /// ExceptHookArgs - simple class to hold exception hook arguments
@@ -687,9 +692,11 @@ pub(crate) mod _thread {
687692
688693 impl Drop for LocalGuard {
689694 fn drop ( & mut self ) {
690- // eprintln!("[DEBUG] LocalGuard::drop called for thread {:?}", self.thread_id);
691695 if let Some ( local_data) = self . local . upgrade ( ) {
692- local_data. data . lock ( ) . remove ( & self . thread_id ) ;
696+ // Remove from map while holding the lock, but drop the value
697+ // outside the lock to prevent deadlock if __del__ accesses _local
698+ let removed = local_data. data . lock ( ) . remove ( & self . thread_id ) ;
699+ drop ( removed) ;
693700 }
694701 }
695702 }
@@ -961,14 +968,15 @@ pub(crate) mod _thread {
961968 }
962969
963970 // Wait for thread completion using Condvar (supports timeout)
971+ // Loop to handle spurious wakeups
964972 let ( lock, cvar) = & * self . done_event ;
965973 let mut done = lock. lock ( ) ;
966974
967- if !* done {
975+ while !* done {
968976 if let Some ( timeout) = timeout_duration {
969977 let result = cvar. wait_for ( & mut done, timeout) ;
970- if result. timed_out ( ) {
971- // Timeout occurred, return without joining
978+ if result. timed_out ( ) && ! * done {
979+ // Timeout occurred and done is still false
972980 return Ok ( ( ) ) ;
973981 }
974982 } else {
@@ -1100,6 +1108,10 @@ pub(crate) mod _thread {
11001108 unsafe { lock. mu. unlock( ) } ;
11011109 }
11021110 }
1111+
1112+ // Clean up thread-local data while VM context is still active
1113+ cleanup_thread_local_data( ) ;
1114+
11031115 vm_state. thread_count. fetch_sub( 1 ) ;
11041116 }
11051117
0 commit comments