Skip to content

Commit 3d20a53

Browse files
committed
Add reset (unsafe)
1 parent 0cb8ce1 commit 3d20a53

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "intrusivelock"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
edition = "2024"
55
description = "Intrusive locks for Rust — locks that live inside the memory region they protect"
66
license = "Apache-2.0"

src/spin_rwlock.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ impl SpinRwLock {
5656
Self::INIT
5757
}
5858

59+
/// Reset the lock to the unlocked state.
60+
///
61+
/// # Safety
62+
/// The caller must ensure no other thread is currently accessing this lock
63+
/// (holding guards or attempting to acquire).
64+
pub unsafe fn reset(&self) {
65+
self.state.store(0, Ordering::Release);
66+
}
67+
5968
pub fn read(&self) -> ReadGuard<'_> {
6069
self._read();
6170
ReadGuard { lock: self }
@@ -855,4 +864,34 @@ mod tests {
855864
assert!(data.try_read().is_none());
856865
drop(wg);
857866
}
867+
868+
// --- reset ---
869+
870+
#[test]
871+
fn reset_unlocks_after_write() {
872+
let lock = SpinRwLock::new();
873+
let _wg = lock.write();
874+
// Simulate a crash: forget the guard so unlock_write never runs.
875+
core::mem::forget(_wg);
876+
// Lock is now stuck in writer-held state.
877+
assert!(lock.try_write().is_none());
878+
assert!(lock.try_read().is_none());
879+
// SAFETY: no other threads are accessing this lock.
880+
unsafe { lock.reset() };
881+
// Lock is usable again.
882+
assert!(lock.try_read().is_some());
883+
assert!(lock.try_write().is_some());
884+
}
885+
886+
#[test]
887+
fn reset_unlocks_after_read() {
888+
let lock = SpinRwLock::new();
889+
let _rg = lock.read();
890+
core::mem::forget(_rg);
891+
// Lock is stuck with a reader.
892+
assert!(lock.try_write().is_none());
893+
// SAFETY: no other threads are accessing this lock.
894+
unsafe { lock.reset() };
895+
assert!(lock.try_write().is_some());
896+
}
858897
}

0 commit comments

Comments
 (0)