Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ log = ["dep:log"]
log_parallelism = ["log"]
nightly = []
nightly_tests = []
parking_lot = ["dep:parking_lot"]
rayon = ["dep:rayon-core"]

[dependencies]
crossbeam-utils = "0.8.21"
log = { optional = true, version = "0.4" }
parking_lot = { optional = true, version = "0.12.5" }
rayon-core = { optional = true, version = "1.13.0" }

# Platforms that support `libc::sched_setaffinity()`.
Expand Down
48 changes: 39 additions & 9 deletions src/threads/thread_pool/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[cfg(feature = "parking_lot")]
use parking_lot::{Condvar, Mutex, MutexGuard};
use std::ptr::NonNull;
use std::sync::{Condvar, Mutex, MutexGuard, PoisonError};
use std::sync::PoisonError;
#[cfg(not(feature = "parking_lot"))]
use std::sync::{Condvar, Mutex, MutexGuard};

/// An ergonomic wrapper around a [`Mutex`]-[`Condvar`] pair.
pub struct Status<T> {
Expand All @@ -29,25 +33,51 @@ impl<T> Status<T> {
///
/// Fails if the [`Mutex`] is poisoned.
pub fn try_notify_one(&self, t: T) -> Result<(), PoisonError<MutexGuard<'_, T>>> {
*self.mutex.lock()? = t;
self.condvar.notify_one();
Ok(())
#[cfg(not(feature = "parking_lot"))]
{
*self.mutex.lock()? = t;
self.condvar.notify_one();
Ok(())
}
#[cfg(feature = "parking_lot")]
{
*self.mutex.lock() = t;
self.condvar.notify_one();
Ok(())
}
}

/// Sets the status to the given value and notifies all waiting threads.
pub fn notify_all(&self, t: T) {
*self.mutex.lock().unwrap() = t;
self.condvar.notify_all();
#[cfg(not(feature = "parking_lot"))]
{
*self.mutex.lock().unwrap() = t;
self.condvar.notify_all();
}
#[cfg(feature = "parking_lot")]
{
*self.mutex.lock() = t;
self.condvar.notify_all();
}
}

/// Waits until the predicate is true on this status.
///
/// This returns a [`MutexGuard`], allowing to further inspect or modify the
/// status.
pub fn wait_while(&self, predicate: impl FnMut(&mut T) -> bool) -> MutexGuard<'_, T> {
self.condvar
.wait_while(self.mutex.lock().unwrap(), predicate)
.unwrap()
#[cfg(not(feature = "parking_lot"))]
{
self.condvar
.wait_while(self.mutex.lock().unwrap(), predicate)
.unwrap()
}
#[cfg(feature = "parking_lot")]
{
let mut guard = self.mutex.lock();
self.condvar.wait_while(&mut guard, predicate);
guard
}
}
}

Expand Down