Skip to content

Commit cc8a662

Browse files
authored
sync: simplify the broadcast channel (tokio-rs#2467)
Replace an ad hoc read/write lock with RwLock. Use The parking_lot RwLock when possible.
1 parent 264ae3b commit cc8a662

File tree

5 files changed

+99
-185
lines changed

5 files changed

+99
-185
lines changed

tokio/Cargo.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,8 @@ futures-test = "0.3.0"
127127
proptest = "0.9.4"
128128
tempfile = "3.1.0"
129129

130-
# loom is currently not compiling on windows.
131-
# See: https://github.com/Xudong-Huang/generator-rs/issues/19
132-
[target.'cfg(not(windows))'.dev-dependencies]
133-
loom = { version = "0.3.1", features = ["futures", "checkpoint"] }
130+
[target.'cfg(loom)'.dev-dependencies]
131+
loom = { version = "0.3.4", features = ["futures", "checkpoint"] }
134132

135133
[package.metadata.docs.rs]
136134
all-features = true

tokio/src/loom/std/mod.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ mod atomic_u32;
66
mod atomic_u64;
77
mod atomic_u8;
88
mod atomic_usize;
9+
#[cfg(feature = "parking_lot")]
10+
mod parking_lot;
911
mod unsafe_cell;
1012

1113
pub(crate) mod cell {
@@ -41,24 +43,21 @@ pub(crate) mod rand {
4143
pub(crate) mod sync {
4244
pub(crate) use std::sync::Arc;
4345

44-
#[cfg(feature = "parking_lot")]
45-
mod pl_wrappers;
46-
4746
// Below, make sure all the feature-influenced types are exported for
4847
// internal use. Note however that some are not _currently_ named by
4948
// consuming code.
5049

5150
#[cfg(feature = "parking_lot")]
5251
#[allow(unused_imports)]
53-
pub(crate) use pl_wrappers::{Condvar, Mutex};
54-
55-
#[cfg(feature = "parking_lot")]
56-
#[allow(unused_imports)]
57-
pub(crate) use parking_lot::{MutexGuard, WaitTimeoutResult};
52+
pub(crate) use crate::loom::std::parking_lot::{
53+
Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard, WaitTimeoutResult,
54+
};
5855

5956
#[cfg(not(feature = "parking_lot"))]
6057
#[allow(unused_imports)]
61-
pub(crate) use std::sync::{Condvar, Mutex, MutexGuard, WaitTimeoutResult};
58+
pub(crate) use std::sync::{
59+
Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard, WaitTimeoutResult,
60+
};
6261

6362
pub(crate) mod atomic {
6463
pub(crate) use crate::loom::std::atomic_ptr::AtomicPtr;

tokio/src/loom/std/sync/pl_wrappers.rs renamed to tokio/src/loom/std/parking_lot.rs

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,33 @@
66
use std::sync::{LockResult, TryLockError, TryLockResult};
77
use std::time::Duration;
88

9-
use parking_lot as pl;
9+
// Types that do not need wrapping
10+
pub(crate) use parking_lot::{MutexGuard, RwLockReadGuard, RwLockWriteGuard, WaitTimeoutResult};
1011

1112
/// Adapter for `parking_lot::Mutex` to the `std::sync::Mutex` interface.
1213
#[derive(Debug)]
13-
pub(crate) struct Mutex<T: ?Sized>(pl::Mutex<T>);
14+
pub(crate) struct Mutex<T: ?Sized>(parking_lot::Mutex<T>);
15+
16+
#[derive(Debug)]
17+
pub(crate) struct RwLock<T>(parking_lot::RwLock<T>);
18+
19+
/// Adapter for `parking_lot::Condvar` to the `std::sync::Condvar` interface.
20+
#[derive(Debug)]
21+
pub(crate) struct Condvar(parking_lot::Condvar);
1422

1523
impl<T> Mutex<T> {
1624
#[inline]
1725
pub(crate) fn new(t: T) -> Mutex<T> {
18-
Mutex(pl::Mutex::new(t))
26+
Mutex(parking_lot::Mutex::new(t))
1927
}
2028

2129
#[inline]
22-
pub(crate) fn lock(&self) -> LockResult<pl::MutexGuard<'_, T>> {
30+
pub(crate) fn lock(&self) -> LockResult<MutexGuard<'_, T>> {
2331
Ok(self.0.lock())
2432
}
2533

2634
#[inline]
27-
pub(crate) fn try_lock(&self) -> TryLockResult<pl::MutexGuard<'_, T>> {
35+
pub(crate) fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>> {
2836
match self.0.try_lock() {
2937
Some(guard) => Ok(guard),
3038
None => Err(TryLockError::WouldBlock),
@@ -35,14 +43,24 @@ impl<T> Mutex<T> {
3543
// provided here as needed.
3644
}
3745

38-
/// Adapter for `parking_lot::Condvar` to the `std::sync::Condvar` interface.
39-
#[derive(Debug)]
40-
pub(crate) struct Condvar(pl::Condvar);
46+
impl<T> RwLock<T> {
47+
pub(crate) fn new(t: T) -> RwLock<T> {
48+
RwLock(parking_lot::RwLock::new(t))
49+
}
50+
51+
pub(crate) fn read(&self) -> LockResult<RwLockReadGuard<'_, T>> {
52+
Ok(self.0.read())
53+
}
54+
55+
pub(crate) fn write(&self) -> LockResult<RwLockWriteGuard<'_, T>> {
56+
Ok(self.0.write())
57+
}
58+
}
4159

4260
impl Condvar {
4361
#[inline]
4462
pub(crate) fn new() -> Condvar {
45-
Condvar(pl::Condvar::new())
63+
Condvar(parking_lot::Condvar::new())
4664
}
4765

4866
#[inline]
@@ -58,18 +76,18 @@ impl Condvar {
5876
#[inline]
5977
pub(crate) fn wait<'a, T>(
6078
&self,
61-
mut guard: pl::MutexGuard<'a, T>,
62-
) -> LockResult<pl::MutexGuard<'a, T>> {
79+
mut guard: MutexGuard<'a, T>,
80+
) -> LockResult<MutexGuard<'a, T>> {
6381
self.0.wait(&mut guard);
6482
Ok(guard)
6583
}
6684

6785
#[inline]
6886
pub(crate) fn wait_timeout<'a, T>(
6987
&self,
70-
mut guard: pl::MutexGuard<'a, T>,
88+
mut guard: MutexGuard<'a, T>,
7189
timeout: Duration,
72-
) -> LockResult<(pl::MutexGuard<'a, T>, pl::WaitTimeoutResult)> {
90+
) -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> {
7391
let wtr = self.0.wait_for(&mut guard, timeout);
7492
Ok((guard, wtr))
7593
}

0 commit comments

Comments
 (0)