Skip to content

Commit 6450279

Browse files
committed
Add shuttle-parking_lot
1 parent e0195a0 commit 6450279

File tree

12 files changed

+244
-37
lines changed

12 files changed

+244
-37
lines changed

Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
[workspace]
22
members = [
33
"shuttle",
4-
"wrappers/shuttle_rand_0.8",
5-
"wrappers/shuttle_sync",
4+
"wrappers/rand_0.8",
5+
"wrappers/sync",
6+
"wrappers/parking_lot",
67
]
78

8-
resolver = "2"
9+
resolver = "2"

wrappers/parking_lot/Cargo.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[package]
2+
name = "shuttle-parking_lot"
3+
version = "0.0.1"
4+
edition = "2024"
5+
6+
[features]
7+
shuttle = [ "dep:shuttle-parking_lot-impl" ]
8+
9+
arc_lock = [ "parking_lot/arc_lock", "shuttle-parking_lot-impl?/arc_lock" ]
10+
deadlock_detection = [ "parking_lot/deadlock_detection", "shuttle-parking_lot-impl?/deadlock_detection" ]
11+
hardware-lock-elision = [ "parking_lot/hardware-lock-elision", "shuttle-parking_lot-impl?/hardware-lock-elision" ]
12+
nightly = [ "parking_lot/nightly", "shuttle-parking_lot-impl?/nightly" ]
13+
owning_ref = [ "parking_lot/owning_ref", "shuttle-parking_lot-impl?/owning_ref" ]
14+
send_guard = [ "parking_lot/send_guard", "shuttle-parking_lot-impl?/send_guard" ]
15+
serde = [ "parking_lot/serde", "shuttle-parking_lot-impl?/serde" ]
16+
17+
[dependencies]
18+
cfg-if = "1.0"
19+
parking_lot = "0.12"
20+
shuttle-parking_lot-impl = { path = "./parking_lot_impl", version = "0.0.1", optional = true }
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "shuttle-parking_lot-impl"
3+
version = "0.0.1"
4+
edition = "2024"
5+
6+
[lib]
7+
name = "shuttle_parking_lot_impl"
8+
path = "src/lib.rs"
9+
doctest = false
10+
11+
[features]
12+
arc_lock = []
13+
deadlock_detection = []
14+
hardware-lock-elision = []
15+
nightly = []
16+
owning_ref = []
17+
send_guard = []
18+
serde = []
19+
20+
[dependencies]
21+
shuttle = { path = "../../../shuttle", version = "*"}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
//! This is the "impl" crate implementing [parking_lot] support for [`Shuttle`].
2+
//! This crate should not be depended on directly, the intended way to use this crate is via
3+
//! the `shuttle-parking_lot` crate and feature flag `shuttle`.
4+
//!
5+
//! [`Shuttle`]: <https://crates.io/crates/shuttle>
6+
//!
7+
//! [`parking_lot`]: <https://crates.io/crates/parking_lot>
8+
9+
use shuttle::sync;
10+
11+
#[derive(Default, Debug)]
12+
pub struct Mutex<T: ?Sized> {
13+
inner: sync::Mutex<T>,
14+
}
15+
16+
pub use sync::{MutexGuard, RwLockReadGuard, RwLockWriteGuard};
17+
18+
impl<T> Mutex<T> {
19+
/// Creates a new mutex in an unlocked state ready for use.
20+
pub fn new(value: T) -> Self {
21+
Self {
22+
inner: sync::Mutex::new(value),
23+
}
24+
}
25+
26+
/// Consumes this mutex, returning the underlying data.
27+
#[inline]
28+
pub fn into_inner(self) -> T {
29+
self.inner
30+
.into_inner()
31+
.expect("This shouldn't happen as there is no way to poision a Shuttle Mutex.")
32+
}
33+
}
34+
35+
impl<T: ?Sized> Mutex<T> {
36+
/// Acquires a mutex, blocking the current thread until it is able to do so.
37+
///
38+
/// This function will block the local thread until it is available to acquire
39+
/// the mutex. Upon returning, the thread is the only thread with the mutex
40+
/// held. An RAII guard is returned to allow scoped unlock of the lock. When
41+
/// the guard goes out of scope, the mutex will be unlocked.
42+
///
43+
/// Attempts to lock a mutex in the thread which already holds the lock will
44+
/// result in a deadlock.
45+
#[inline]
46+
pub fn lock(&self) -> sync::MutexGuard<'_, T> {
47+
self.inner
48+
.lock()
49+
.expect("This shouldn't happen as there is no way to poision a Shuttle Mutex.")
50+
}
51+
52+
/// Attempts to acquire this lock.
53+
///
54+
/// If the lock could not be acquired at this time, then `None` is returned.
55+
/// Otherwise, an RAII guard is returned. The lock will be unlocked when the
56+
/// guard is dropped.
57+
#[inline]
58+
pub fn try_lock(&self) -> Option<sync::MutexGuard<'_, T>> {
59+
self.inner.try_lock().ok()
60+
}
61+
}
62+
63+
/// A reader-writer lock
64+
#[derive(Debug, Default)]
65+
pub struct RwLock<T: ?Sized> {
66+
inner: sync::RwLock<T>,
67+
}
68+
69+
impl<T> RwLock<T> {
70+
/// Creates a new instance of an `RwLock<T>` which is unlocked.
71+
pub fn new(value: T) -> Self {
72+
Self {
73+
inner: sync::RwLock::new(value),
74+
}
75+
}
76+
77+
/// Consumes this `RwLock`, returning the underlying data.
78+
#[inline]
79+
pub fn into_inner(self) -> T {
80+
self.inner
81+
.into_inner()
82+
.expect("This shouldn't happen as there is no way to poision a Shuttle RwLock.")
83+
}
84+
}
85+
86+
impl<T: ?Sized> RwLock<T> {
87+
/// Locks this `RwLock` with shared read access, blocking the current thread
88+
/// until it can be acquired.
89+
///
90+
/// The calling thread will be blocked until there are no more writers which
91+
/// hold the lock. There may be other readers currently inside the lock when
92+
/// this method returns.
93+
///
94+
/// Note that attempts to recursively acquire a read lock on a `RwLock` when
95+
/// the current thread already holds one may result in a deadlock.
96+
///
97+
/// Returns an RAII guard which will release this thread's shared access
98+
/// once it is dropped.
99+
#[inline]
100+
pub fn read(&self) -> RwLockReadGuard<'_, T> {
101+
self.inner
102+
.read()
103+
.expect("This shouldn't happen as there is no way to poision a Shuttle RwLock.")
104+
}
105+
106+
/// Attempts to acquire this `RwLock` with shared read access.
107+
///
108+
/// If the access could not be granted at this time, then `None` is returned.
109+
/// Otherwise, an RAII guard is returned which will release the shared access
110+
/// when it is dropped.
111+
///
112+
/// This function does not block.
113+
#[inline]
114+
pub fn try_read(&self) -> Option<RwLockReadGuard<'_, T>> {
115+
self.inner.try_read().ok()
116+
}
117+
118+
/// Locks this `RwLock` with exclusive write access, blocking the current
119+
/// thread until it can be acquired.
120+
///
121+
/// This function will not return while other writers or other readers
122+
/// currently have access to the lock.
123+
///
124+
/// Returns an RAII guard which will drop the write access of this `RwLock`
125+
/// when dropped.
126+
#[inline]
127+
pub fn write(&self) -> RwLockWriteGuard<'_, T> {
128+
self.inner
129+
.write()
130+
.expect("This shouldn't happen as there is no way to poision a Shuttle RwLock.")
131+
}
132+
133+
/// Attempts to lock this `RwLock` with exclusive write access.
134+
///
135+
/// If the lock could not be acquired at this time, then `None` is returned.
136+
/// Otherwise, an RAII guard is returned which will release the lock when
137+
/// it is dropped.
138+
///
139+
/// This function does not block.
140+
#[inline]
141+
pub fn try_write(&self) -> Option<RwLockWriteGuard<'_, T>> {
142+
self.inner.try_write().ok()
143+
}
144+
}

wrappers/parking_lot/src/lib.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//! This crate provides a Shuttle-compatible implementation and wrapper for [`parking_lot`] in order to make it
2+
//! more ergonomic to run a codebase under Shuttle.
3+
//!
4+
//! [`parking_lot`]: <https://crates.io/crates/parking_lot>
5+
//!
6+
//! To use this crate, add something akin to the following to your Cargo.toml:
7+
//!
8+
//! ```ignore
9+
//! [features]
10+
//! shuttle = [
11+
//! "parking_lot/shuttle",
12+
//! ]
13+
//!
14+
//! [dependencies]
15+
//! parking_lot = { package = "shuttle-parking_lot", version = "VERSION_NUMBER" }
16+
//! ```
17+
//!
18+
//! The rest of the codebase then remains unchanged, and running with Shuttle-compatible `parking_lot` can be done via the "shuttle" feature flag.
19+
20+
cfg_if::cfg_if! {
21+
if #[cfg(feature = "shuttle")] {
22+
pub use shuttle_parking_lot_impl::*;
23+
} else {
24+
pub use parking_lot::*;
25+
}
26+
}

wrappers/rand_0.8/Cargo.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[package]
2+
name = "shuttle-rand"
3+
version = "0.0.1"
4+
edition = "2024"
5+
6+
[features]
7+
shuttle = [ "dep:shuttle-rand-impl" ]
8+
9+
alloc = ["rand/alloc", "shuttle-rand-impl/alloc"]
10+
getrandom = [ "rand/getrandom", "shuttle-rand-impl/getrandom" ]
11+
min_const_gen = [ "rand/min_const_gen", "shuttle-rand-impl/min_const_gen" ]
12+
nightly = [ "rand/nightly", "shuttle-rand-impl/nightly" ]
13+
serde1 = [ "rand/serde1", "shuttle-rand-impl/serde1" ]
14+
simd_support = [ "rand/simd_support", "shuttle-rand-impl/simd_support" ]
15+
small_rng = [ "rand/small_rng", "shuttle-rand-impl/small_rng" ]
16+
std = [ "rand/std", "shuttle-rand-impl/std" ]
17+
std_rng = [ "rand/std_rng", "shuttle-rand-impl/std_rng" ]
18+
19+
[dependencies]
20+
cfg-if = "1.0"
21+
rand = "0.8"
22+
shuttle-rand-impl = { path = "./shuttle_rand_impl", version = "0.0.1", optional = true }
Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
[package]
2-
name = "shuttle-rand-inner"
3-
version = "0.1.0"
2+
name = "shuttle-rand-impl"
3+
version = "0.0.1"
44
edition = "2024"
55

66
[features]
77
alloc = []
8-
default = []
98
getrandom = []
109
min_const_gen = []
1110
nightly = []
@@ -18,5 +17,3 @@ std_rng = []
1817
[dependencies]
1918
shuttle = { path = "../../../shuttle", version = "*"}
2019
rand-orig = { package = "rand", version = "0.8" }
21-
22-

wrappers/shuttle_rand_0.8/shuttle_rand_inner/src/lib.rs renamed to wrappers/rand_0.8/shuttle_rand_impl/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! This is the "inner" crate implementing [`rand` version 0.8] support for [`Shuttle`].
1+
//! This is the "impl" crate implementing [`rand` version 0.8] support for [`Shuttle`].
22
//! This crate should not be depended on directly, the intended way to use this crate is via
33
//! the `shuttle-rand` crate and feature flag `shuttle`.
44
//!
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
2020
cfg_if::cfg_if! {
2121
if #[cfg(feature = "shuttle")] {
22-
pub use shuttle_rand_inner::*;
22+
pub use shuttle_rand_impl::*;
2323
} else {
24-
pub use rand_orig::*;
24+
pub use rand::*;
2525
}
2626
}

wrappers/shuttle_rand_0.8/Cargo.toml

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)