mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Prevent double reference in generic futex
This commit is contained in:
parent
a28b35eb35
commit
0585c4a23e
@ -15,6 +15,7 @@ pub type SmallAtomic = AtomicU8;
|
||||
/// Must be the underlying type of SmallAtomic
|
||||
pub type SmallPrimitive = u8;
|
||||
|
||||
pub unsafe trait Futex {}
|
||||
pub unsafe trait Waitable {
|
||||
type Atomic;
|
||||
}
|
||||
@ -24,6 +25,7 @@ macro_rules! unsafe_waitable_int {
|
||||
unsafe impl Waitable for $int {
|
||||
type Atomic = $atomic;
|
||||
}
|
||||
unsafe impl Futex for $atomic {}
|
||||
)*
|
||||
};
|
||||
}
|
||||
@ -46,6 +48,7 @@ unsafe impl<T> Waitable for *const T {
|
||||
unsafe impl<T> Waitable for *mut T {
|
||||
type Atomic = AtomicPtr<T>;
|
||||
}
|
||||
unsafe impl<T> Futex for AtomicPtr<T> {}
|
||||
|
||||
pub fn wait_on_address<W: Waitable>(
|
||||
address: &W::Atomic,
|
||||
@ -61,14 +64,14 @@ pub fn wait_on_address<W: Waitable>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wake_by_address_single<T>(address: &T) {
|
||||
pub fn wake_by_address_single<T: Futex>(address: &T) {
|
||||
unsafe {
|
||||
let addr = ptr::from_ref(address).cast::<c_void>();
|
||||
c::WakeByAddressSingle(addr);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wake_by_address_all<T>(address: &T) {
|
||||
pub fn wake_by_address_all<T: Futex>(address: &T) {
|
||||
unsafe {
|
||||
let addr = ptr::from_ref(address).cast::<c_void>();
|
||||
c::WakeByAddressAll(addr);
|
||||
@ -80,11 +83,11 @@ pub fn futex_wait<W: Waitable>(futex: &W::Atomic, expected: W, timeout: Option<D
|
||||
wait_on_address(futex, expected, timeout) || api::get_last_error() != WinError::TIMEOUT
|
||||
}
|
||||
|
||||
pub fn futex_wake<T>(futex: &T) -> bool {
|
||||
pub fn futex_wake<T: Futex>(futex: &T) -> bool {
|
||||
wake_by_address_single(futex);
|
||||
false
|
||||
}
|
||||
|
||||
pub fn futex_wake_all<T>(futex: &T) {
|
||||
pub fn futex_wake_all<T: Futex>(futex: &T) {
|
||||
wake_by_address_all(futex)
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ impl<'a> Drop for CompletionGuard<'a> {
|
||||
// up on the Once. `futex_wake_all` does its own synchronization, hence
|
||||
// we do not need `AcqRel`.
|
||||
if self.state.swap(self.set_state_on_drop_to, Release) == QUEUED {
|
||||
futex_wake_all(&self.state);
|
||||
futex_wake_all(self.state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user