fix(lock): make slow-path waiter accounting cancellation-safe (#2805)

This commit is contained in:
houseme
2026-05-05 19:19:23 +08:00
committed by GitHub
parent 743b87014b
commit 49b2782d51
2 changed files with 118 additions and 14 deletions
+12 -6
View File
@@ -165,13 +165,13 @@ impl AtomicLockState {
}
/// Increment waiting readers count
pub fn inc_readers_waiting(&self) {
pub fn inc_readers_waiting(&self) -> bool {
loop {
let current = self.state.load(Ordering::Acquire);
let waiting = self.readers_waiting(current);
if waiting == 0xFFFF {
break; // Max waiting readers
return false; // Max waiting readers
}
let new_state = current + (1 << READERS_WAITING_SHIFT);
@@ -181,7 +181,7 @@ impl AtomicLockState {
.compare_exchange_weak(current, new_state, Ordering::AcqRel, Ordering::Relaxed)
.is_ok()
{
break;
return true;
}
}
}
@@ -209,13 +209,13 @@ impl AtomicLockState {
}
/// Increment waiting writers count
pub fn inc_writers_waiting(&self) {
pub fn inc_writers_waiting(&self) -> bool {
loop {
let current = self.state.load(Ordering::Acquire);
let waiting = self.writers_waiting(current);
if waiting == 0xFFFF {
break; // Max waiting writers
return false; // Max waiting writers
}
let new_state = current + (1 << WRITERS_WAITING_SHIFT);
@@ -225,7 +225,7 @@ impl AtomicLockState {
.compare_exchange_weak(current, new_state, Ordering::AcqRel, Ordering::Relaxed)
.is_ok()
{
break;
return true;
}
}
}
@@ -288,6 +288,12 @@ impl AtomicLockState {
fn writers_waiting(&self, state: u64) -> u16 {
((state & WRITERS_WAITING_MASK) >> WRITERS_WAITING_SHIFT) as u16
}
#[cfg(test)]
pub fn writers_waiting_count(&self) -> u16 {
let state = self.state.load(Ordering::Acquire);
self.writers_waiting(state)
}
}
/// Object lock state with version support - optimized memory layout