diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-09-23 18:13:53 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-23 18:13:53 +0200 |
| commit | 64e81e5cb7f8a09e22cd1f570f6a6deb6bda4373 (patch) | |
| tree | 060c0a717b9513fd83fea6d21fccd07f8da17497 | |
| parent | 8f11c4dadb9e240815ca25e613b17656ab665eda (diff) | |
| parent | 389a502ade65e82d8a0c4d323118121c1c09c4f8 (diff) | |
| download | rust-64e81e5cb7f8a09e22cd1f570f6a6deb6bda4373.tar.gz rust-64e81e5cb7f8a09e22cd1f570f6a6deb6bda4373.zip | |
Rollup merge of #146799 - cuviper:dangling-count-latch, r=lcnr
Fix a dangling reference in `rustc_thread_pool` This diverged from `rayon` in rust-lang/rust#142384, where a cleanup commit turned the matched `worker_index` into a reference, which is read _after_ the `set` that may kill it. I've moved that read beforehand, and I hope the new comments will emphasize the subtlety of this unsafe code. Hopefully fixes rust-lang/rust#146677.
| -rw-r--r-- | compiler/rustc_thread_pool/src/latch.rs | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/compiler/rustc_thread_pool/src/latch.rs b/compiler/rustc_thread_pool/src/latch.rs index 18d654d9f78..58dabaf35c0 100644 --- a/compiler/rustc_thread_pool/src/latch.rs +++ b/compiler/rustc_thread_pool/src/latch.rs @@ -388,13 +388,17 @@ impl Latch for CountLatch { #[inline] unsafe fn set(this: *const Self) { if unsafe { (*this).counter.fetch_sub(1, Ordering::SeqCst) == 1 } { - // NOTE: Once we call `set` on the internal `latch`, + // SAFETY: Once we call `set` on the internal `latch`, // the target may proceed and invalidate `this`! match unsafe { &(*this).kind } { CountLatchKind::Stealing { latch, registry, worker_index } => { let registry = Arc::clone(registry); + let worker_index = *worker_index; + // SAFETY: We don't use any references from `this` after this call. if unsafe { CoreLatch::set(latch) } { - registry.notify_worker_latch_is_set(*worker_index); + // We **must not** access any part of `this` anymore, which + // is why we read and shadowed these fields beforehand. + registry.notify_worker_latch_is_set(worker_index); } } CountLatchKind::Blocking { latch } => unsafe { LockLatch::set(latch) }, |
