@@ -211,6 +211,14 @@ impl<'tcx> TlsData<'tcx> {
211
211
false
212
212
}
213
213
}
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
+ }
214
222
}
215
223
216
224
impl < ' mir , ' tcx : ' mir > EvalContextPrivExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
@@ -271,8 +279,9 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
271
279
Ok ( ( ) )
272
280
}
273
281
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 > {
276
285
let this = self . eval_context_mut ( ) ;
277
286
let active_thread = this. get_active_thread ( ) ?;
278
287
@@ -300,11 +309,11 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
300
309
) ?;
301
310
302
311
this. enable_thread ( active_thread) ?;
303
- return Ok ( ( ) ) ;
312
+ return Ok ( true ) ;
304
313
}
305
314
this. machine . tls . dtors_running . get_mut ( & active_thread) . unwrap ( ) . last_dtor_key = None ;
306
315
307
- Ok ( ( ) )
316
+ Ok ( false )
308
317
}
309
318
}
310
319
@@ -322,16 +331,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
322
331
let this = self . eval_context_mut ( ) ;
323
332
let active_thread = this. get_active_thread ( ) ?;
324
333
325
- if this. tcx . sess . target . target . target_os == "windows" {
334
+ let finished = if this. tcx . sess . target . target . target_os == "windows" {
326
335
if !this. machine . tls . set_dtors_running_for_thread ( active_thread) {
327
336
this. schedule_windows_tls_dtors ( ) ?;
328
337
}
338
+ true
329
339
} else {
330
340
this. machine . tls . set_dtors_running_for_thread ( active_thread) ;
331
341
// The macOS thread wide destructor runs "before any TLS slots get
332
342
// freed", so do that first.
333
343
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) ;
335
349
}
336
350
337
351
Ok ( ( ) )
0 commit comments