mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-28 20:16:58 +03:00
kmc-solid: Synchronize the first update of ThreadInner::lifecycle with the second one on detach
The first update (swap RMW operation) must happen-before the second update so that the latter can release `ThreadInner` safely.
This commit is contained in:
@@ -119,7 +119,7 @@ pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||
|
||||
let old_lifecycle = inner
|
||||
.lifecycle
|
||||
.swap(LIFECYCLE_EXITED_OR_FINISHED_OR_JOIN_FINALIZE, Ordering::Release);
|
||||
.swap(LIFECYCLE_EXITED_OR_FINISHED_OR_JOIN_FINALIZE, Ordering::AcqRel);
|
||||
|
||||
match old_lifecycle {
|
||||
LIFECYCLE_DETACHED => {
|
||||
@@ -129,9 +129,9 @@ pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||
|
||||
// In this case, `*p_inner`'s ownership has been moved to
|
||||
// us, and we are responsible for dropping it. The acquire
|
||||
// ordering is not necessary because the parent thread made
|
||||
// no memory access needing synchronization since the call
|
||||
// to `acre_tsk`.
|
||||
// ordering ensures that the swap operation that wrote
|
||||
// `LIFECYCLE_DETACHED` happens-before `Box::from_raw(
|
||||
// p_inner)`.
|
||||
// Safety: See above.
|
||||
let _ = unsafe { Box::from_raw(p_inner) };
|
||||
|
||||
@@ -267,15 +267,15 @@ fn drop(&mut self) {
|
||||
let inner = unsafe { self.p_inner.as_ref() };
|
||||
|
||||
// Detach the thread.
|
||||
match inner.lifecycle.swap(LIFECYCLE_DETACHED_OR_JOINED, Ordering::Acquire) {
|
||||
match inner.lifecycle.swap(LIFECYCLE_DETACHED_OR_JOINED, Ordering::AcqRel) {
|
||||
LIFECYCLE_INIT => {
|
||||
// [INIT → DETACHED]
|
||||
// When the time comes, the child will figure out that no
|
||||
// one will ever join it.
|
||||
// The ownership of `*p_inner` is moved to the child thread.
|
||||
// However, the release ordering is not necessary because we
|
||||
// made no memory access needing synchronization since the call
|
||||
// to `acre_tsk`.
|
||||
// The release ordering ensures that the above swap operation on
|
||||
// `lifecycle` happens-before the child thread's
|
||||
// `Box::from_raw(p_inner)`.
|
||||
}
|
||||
LIFECYCLE_FINISHED => {
|
||||
// [FINISHED → JOINED]
|
||||
|
||||
Reference in New Issue
Block a user