Skip to content

Commit 1355574

Browse files
author
Vytautas Astrauskas
committed
Delete remaining tls entries after all destructors completed.
1 parent df2ca53 commit 1355574

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

src/shims/tls.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

216224
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
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

Comments
 (0)