@@ -211,6 +211,14 @@ impl<'tcx> TlsData<'tcx> {
211211 false
212212 }
213213 }
214+
215+ /// Delete all TLS entries for the given thread. This function should be
216+ /// called after all TLS destructors have already finished.
217+ fn delete_all_thread_tls ( & mut self , thread_id : ThreadId ) {
218+ for TlsEntry { data, .. } in self . keys . values_mut ( ) {
219+ data. remove ( & thread_id) ;
220+ }
221+ }
214222}
215223
216224impl < ' mir , ' tcx : ' mir > EvalContextPrivExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
@@ -271,8 +279,9 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
271279 Ok ( ( ) )
272280 }
273281
274- /// Schedule a pthread TLS destructor.
275- fn schedule_pthread_tls_dtors ( & mut self ) -> InterpResult < ' tcx > {
282+ /// Schedule a pthread TLS destructor. Returns `true` if found
283+ /// a destructor to schedule, and `false` otherwise.
284+ fn schedule_pthread_tls_dtors ( & mut self ) -> InterpResult < ' tcx , bool > {
276285 let this = self . eval_context_mut ( ) ;
277286 let active_thread = this. get_active_thread ( ) ?;
278287
@@ -300,11 +309,11 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
300309 ) ?;
301310
302311 this. enable_thread ( active_thread) ?;
303- return Ok ( ( ) ) ;
312+ return Ok ( true ) ;
304313 }
305314 this. machine . tls . dtors_running . get_mut ( & active_thread) . unwrap ( ) . last_dtor_key = None ;
306315
307- Ok ( ( ) )
316+ Ok ( false )
308317 }
309318}
310319
@@ -322,16 +331,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
322331 let this = self . eval_context_mut ( ) ;
323332 let active_thread = this. get_active_thread ( ) ?;
324333
325- if this. tcx . sess . target . target . target_os == "windows" {
334+ let finished = if this. tcx . sess . target . target . target_os == "windows" {
326335 if !this. machine . tls . set_dtors_running_for_thread ( active_thread) {
327336 this. schedule_windows_tls_dtors ( ) ?;
328337 }
338+ true
329339 } else {
330340 this. machine . tls . set_dtors_running_for_thread ( active_thread) ;
331341 // The macOS thread wide destructor runs "before any TLS slots get
332342 // freed", so do that first.
333343 this. schedule_macos_tls_dtor ( ) ?;
334- this. schedule_pthread_tls_dtors ( ) ?;
344+ this. schedule_pthread_tls_dtors ( ) ?
345+ } ;
346+
347+ if finished {
348+ this. machine . tls . delete_all_thread_tls ( active_thread) ;
335349 }
336350
337351 Ok ( ( ) )
0 commit comments