Skip to content

Commit 5d805a1

Browse files
committed
Make {Mutex, Notify, OnceCell, RwLock, Semaphore}::const_new always available
Since MSRV is bumped to 1.63, `Mutex::new` is now usable in const context. Also use `assert!` in const function to ensure correctness instead of silently truncating the value and remove cfg `tokio_no_const_mutex_new`. Signed-off-by: Jiahao XU <[email protected]>
1 parent c445e46 commit 5d805a1

File tree

12 files changed

+213
-245
lines changed

12 files changed

+213
-245
lines changed

.github/workflows/ci.yml

-6
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,6 @@ jobs:
442442

443443
# Run a platform without AtomicU64 and no const Mutex::new
444444
- target: armv5te-unknown-linux-gnueabi
445-
rustflags: --cfg tokio_no_const_mutex_new
446445
steps:
447446
- uses: actions/checkout@v3
448447
- name: Install Rust stable
@@ -485,7 +484,6 @@ jobs:
485484

486485
# Run a platform without AtomicU64 and no const Mutex::new
487486
- target: armv5te-unknown-linux-gnueabi
488-
rustflags: --cfg tokio_no_const_mutex_new
489487
steps:
490488
- uses: actions/checkout@v3
491489
- name: Install Rust stable
@@ -568,10 +566,6 @@ jobs:
568566

569567
# https://github.com/tokio-rs/tokio/pull/5356
570568
# https://github.com/tokio-rs/tokio/issues/5373
571-
- name: Check without const_mutex_new
572-
run: cargo hack check -p tokio --feature-powerset --depth 2 --keep-going
573-
env:
574-
RUSTFLAGS: --cfg tokio_unstable --cfg tokio_taskdump -Dwarnings --cfg tokio_no_atomic_u64 --cfg tokio_no_const_mutex_new
575569
- name: Check with const_mutex_new
576570
run: cargo hack check -p tokio --feature-powerset --depth 2 --keep-going
577571
env:

tokio/src/loom/std/mutex.rs

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ impl<T> Mutex<T> {
1313
}
1414

1515
#[inline]
16-
#[cfg(not(tokio_no_const_mutex_new))]
1716
pub(crate) const fn const_new(t: T) -> Mutex<T> {
1817
Mutex(sync::Mutex::new(t))
1918
}

tokio/src/macros/cfg.rs

+2-14
Original file line numberDiff line numberDiff line change
@@ -555,13 +555,7 @@ macro_rules! cfg_not_has_atomic_u64 {
555555
macro_rules! cfg_has_const_mutex_new {
556556
($($item:item)*) => {
557557
$(
558-
#[cfg(all(
559-
not(all(loom, test)),
560-
any(
561-
feature = "parking_lot",
562-
not(tokio_no_const_mutex_new)
563-
)
564-
))]
558+
#[cfg(not(all(loom, test)))]
565559
$item
566560
)*
567561
}
@@ -570,13 +564,7 @@ macro_rules! cfg_has_const_mutex_new {
570564
macro_rules! cfg_not_has_const_mutex_new {
571565
($($item:item)*) => {
572566
$(
573-
#[cfg(not(all(
574-
not(all(loom, test)),
575-
any(
576-
feature = "parking_lot",
577-
not(tokio_no_const_mutex_new)
578-
)
579-
)))]
567+
#[cfg(all(loom, test))]
580568
$item
581569
)*
582570
}

tokio/src/sync/batch_semaphore.rs

+16-8
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,9 @@ impl Semaphore {
178178
/// Creates a new semaphore with the initial number of permits.
179179
///
180180
/// Maximum number of permits on 32-bit platforms is `1<<29`.
181-
///
182-
/// If the specified number of permits exceeds the maximum permit amount
183-
/// Then the value will get clamped to the maximum number of permits.
184-
#[cfg(all(feature = "parking_lot", not(all(loom, test))))]
185-
pub(crate) const fn const_new(mut permits: usize) -> Self {
186-
// NOTE: assertions and by extension panics are still being worked on: https://github.com/rust-lang/rust/issues/74925
187-
// currently we just clamp the permit count when it exceeds the max
188-
permits &= Self::MAX_PERMITS;
181+
#[cfg(not(all(loom, test)))]
182+
pub(crate) const fn const_new(permits: usize) -> Self {
183+
assert!(permits <= Self::MAX_PERMITS);
189184

190185
Self {
191186
permits: AtomicUsize::new(permits << Self::PERMIT_SHIFT),
@@ -198,6 +193,19 @@ impl Semaphore {
198193
}
199194
}
200195

196+
/// Creates a new closed semaphore with 0 permits.
197+
pub(crate) fn new_closed() -> Self {
198+
Self {
199+
permits: AtomicUsize::new(Self::CLOSED),
200+
waiters: Mutex::new(Waitlist {
201+
queue: LinkedList::new(),
202+
closed: true,
203+
}),
204+
#[cfg(all(tokio_unstable, feature = "tracing"))]
205+
resource_span: tracing::Span::none(),
206+
}
207+
}
208+
201209
/// Returns the current number of available permits.
202210
pub(crate) fn available_permits(&self) -> usize {
203211
self.permits.load(Acquire) >> Self::PERMIT_SHIFT

tokio/src/sync/mutex.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,7 @@ impl<T: ?Sized> Mutex<T> {
378378
///
379379
/// static LOCK: Mutex<i32> = Mutex::const_new(5);
380380
/// ```
381-
#[cfg(all(feature = "parking_lot", not(all(loom, test)),))]
382-
#[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))]
381+
#[cfg(not(all(loom, test)))]
383382
pub const fn const_new(t: T) -> Self
384383
where
385384
T: Sized,

tokio/src/sync/notify.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,7 @@ impl Notify {
443443
///
444444
/// static NOTIFY: Notify = Notify::const_new();
445445
/// ```
446-
#[cfg(all(feature = "parking_lot", not(all(loom, test))))]
447-
#[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))]
446+
#[cfg(not(all(loom, test)))]
448447
pub const fn const_new() -> Notify {
449448
Notify {
450449
state: AtomicUsize::new(0),

tokio/src/sync/once_cell.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,10 @@ impl<T> Drop for OnceCell<T> {
114114

115115
impl<T> From<T> for OnceCell<T> {
116116
fn from(value: T) -> Self {
117-
let semaphore = Semaphore::new(0);
118-
semaphore.close();
119117
OnceCell {
120118
value_set: AtomicBool::new(true),
121119
value: UnsafeCell::new(MaybeUninit::new(value)),
122-
semaphore,
120+
semaphore: Semaphore::new_closed(),
123121
}
124122
}
125123
}
@@ -139,6 +137,10 @@ impl<T> OnceCell<T> {
139137
/// If the `Option` is `None`, this is equivalent to `OnceCell::new`.
140138
///
141139
/// [`OnceCell::new`]: crate::sync::OnceCell::new
140+
// Once https://github.com/rust-lang/rust/issues/73255 lands
141+
// and tokio MSRV is bumped to the rustc version with it stablised,
142+
// we can made this function available in const context,
143+
// by creating `Semaphore::const_new_closed`.
142144
pub fn new_with(value: Option<T>) -> Self {
143145
if let Some(v) = value {
144146
OnceCell::from(v)
@@ -171,8 +173,7 @@ impl<T> OnceCell<T> {
171173
/// assert_eq!(*result, 2);
172174
/// }
173175
/// ```
174-
#[cfg(all(feature = "parking_lot", not(all(loom, test))))]
175-
#[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))]
176+
#[cfg(not(all(loom, test)))]
176177
pub const fn const_new() -> Self {
177178
OnceCell {
178179
value_set: AtomicBool::new(false),

tokio/src/sync/rwlock.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,7 @@ impl<T: ?Sized> RwLock<T> {
334334
///
335335
/// static LOCK: RwLock<i32> = RwLock::const_new(5);
336336
/// ```
337-
#[cfg(all(feature = "parking_lot", not(all(loom, test))))]
338-
#[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))]
337+
#[cfg(not(all(loom, test)))]
339338
pub const fn const_new(value: T) -> RwLock<T>
340339
where
341340
T: Sized,
@@ -359,13 +358,13 @@ impl<T: ?Sized> RwLock<T> {
359358
///
360359
/// static LOCK: RwLock<i32> = RwLock::const_with_max_readers(5, 1024);
361360
/// ```
362-
#[cfg(all(feature = "parking_lot", not(all(loom, test))))]
363-
#[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))]
364-
pub const fn const_with_max_readers(value: T, mut max_reads: u32) -> RwLock<T>
361+
#[cfg(not(all(loom, test)))]
362+
pub const fn const_with_max_readers(value: T, max_reads: u32) -> RwLock<T>
365363
where
366364
T: Sized,
367365
{
368-
max_reads &= MAX_READS;
366+
assert!(max_reads <= MAX_READS);
367+
369368
RwLock {
370369
mr: max_reads,
371370
c: UnsafeCell::new(value),

tokio/src/sync/semaphore.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -172,20 +172,22 @@ impl Semaphore {
172172
///
173173
/// static SEM: Semaphore = Semaphore::const_new(10);
174174
/// ```
175-
///
176-
#[cfg(all(feature = "parking_lot", not(all(loom, test))))]
177-
#[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))]
175+
#[cfg(not(all(loom, test)))]
178176
pub const fn const_new(permits: usize) -> Self {
179-
#[cfg(all(tokio_unstable, feature = "tracing"))]
180-
return Self {
177+
Self {
181178
ll_sem: ll::Semaphore::const_new(permits),
179+
#[cfg(all(tokio_unstable, feature = "tracing"))]
182180
resource_span: tracing::Span::none(),
183-
};
181+
}
182+
}
184183

185-
#[cfg(any(not(tokio_unstable), not(feature = "tracing")))]
186-
return Self {
187-
ll_sem: ll::Semaphore::const_new(permits),
188-
};
184+
/// Creates a new closed semaphore with 0 permits.
185+
pub(crate) fn new_closed() -> Self {
186+
Self {
187+
ll_sem: ll::Semaphore::new_closed(),
188+
#[cfg(all(tokio_unstable, feature = "tracing"))]
189+
resource_span: tracing::Span::none(),
190+
}
189191
}
190192

191193
/// Returns the current number of available permits.

tokio/src/util/mod.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@ cfg_io_driver! {
55
#[cfg(feature = "rt")]
66
pub(crate) mod atomic_cell;
77

8-
#[cfg(any(
9-
feature = "rt",
10-
feature = "signal",
11-
feature = "process",
12-
tokio_no_const_mutex_new,
13-
))]
8+
#[cfg(any(feature = "rt", feature = "signal", feature = "process",))]
149
pub(crate) mod once_cell;
1510

1611
#[cfg(any(

0 commit comments

Comments
 (0)