This commit is contained in:
peamaeq
2022-05-03 21:28:32 +08:00
parent d80b76a568
commit 615eaf71b0
4 changed files with 34 additions and 44 deletions
+8 -10
View File
@@ -55,25 +55,24 @@ impl KeyedEvent {
#[allow(non_snake_case)]
pub fn create() -> Option<KeyedEvent> {
unsafe {
let ntdll = GetModuleHandleA(b"ntdll.dll\0".as_ptr());
let ntdll = unsafe { GetModuleHandleA(b"ntdll.dll\0".as_ptr()) };
if ntdll == 0 {
return None;
}
let NtCreateKeyedEvent =
GetProcAddress(ntdll, b"NtCreateKeyedEvent\0".as_ptr())?;
unsafe { GetProcAddress(ntdll, b"NtCreateKeyedEvent\0".as_ptr())? };
let NtReleaseKeyedEvent =
GetProcAddress(ntdll, b"NtReleaseKeyedEvent\0".as_ptr())?;
unsafe { GetProcAddress(ntdll, b"NtReleaseKeyedEvent\0".as_ptr())? };
let NtWaitForKeyedEvent =
GetProcAddress(ntdll, b"NtWaitForKeyedEvent\0".as_ptr())?;
unsafe { GetProcAddress(ntdll, b"NtWaitForKeyedEvent\0".as_ptr())?};
let NtCreateKeyedEvent: extern "system" fn(
KeyedEventHandle: *mut HANDLE,
DesiredAccess: u32,
ObjectAttributes: *mut ffi::c_void,
Flags: u32,
) -> NTSTATUS = mem::transmute(NtCreateKeyedEvent);
) -> NTSTATUS = unsafe { mem::transmute(NtCreateKeyedEvent) };
let mut handle = MaybeUninit::uninit();
let status = NtCreateKeyedEvent(
handle.as_mut_ptr(),
@@ -86,11 +85,10 @@ impl KeyedEvent {
}
Some(KeyedEvent {
handle: handle.assume_init(),
NtReleaseKeyedEvent: mem::transmute(NtReleaseKeyedEvent),
NtWaitForKeyedEvent: mem::transmute(NtWaitForKeyedEvent),
handle: unsafe { handle.assume_init() },
NtReleaseKeyedEvent: unsafe { mem::transmute(NtReleaseKeyedEvent) },
NtWaitForKeyedEvent: unsafe { mem::transmute(NtWaitForKeyedEvent) },
})
}
}
#[inline]
@@ -32,24 +32,22 @@ pub struct WaitAddress {
impl WaitAddress {
#[allow(non_snake_case)]
pub fn create() -> Option<WaitAddress> {
unsafe {
// MSDN claims that that WaitOnAddress and WakeByAddressSingle are
// located in kernel32.dll, but they are lying...
let synch_dll =
GetModuleHandleA(b"api-ms-win-core-synch-l1-2-0.dll\0".as_ptr());
unsafe { GetModuleHandleA(b"api-ms-win-core-synch-l1-2-0.dll\0".as_ptr()) };
if synch_dll == 0 {
return None;
}
let WaitOnAddress = GetProcAddress(synch_dll, b"WaitOnAddress\0".as_ptr())?;
let WaitOnAddress = unsafe { GetProcAddress(synch_dll, b"WaitOnAddress\0".as_ptr())? };
let WakeByAddressSingle =
GetProcAddress(synch_dll, b"WakeByAddressSingle\0".as_ptr())?;
unsafe { GetProcAddress(synch_dll, b"WakeByAddressSingle\0".as_ptr())? };
Some(WaitAddress {
WaitOnAddress: mem::transmute(WaitOnAddress),
WakeByAddressSingle: mem::transmute(WakeByAddressSingle),
WaitOnAddress: unsafe { mem::transmute(WaitOnAddress) },
WakeByAddressSingle: unsafe { mem::transmute(WakeByAddressSingle) },
})
}
}
#[inline]
+15 -21
View File
@@ -136,11 +136,10 @@ impl Condvar {
#[cold]
fn notify_one_slow(&self, mutex: *mut RawMutex) -> bool {
unsafe {
// Unpark one thread and requeue the rest onto the mutex
let from = self as *const _ as usize;
let to = mutex as usize;
let validate = || {
// Unpark one thread and requeue the rest onto the mutex
let from = self as *const _ as usize;
let to = mutex as usize;
let validate = unsafe { || {
// Make sure that our atomic state still points to the same
// mutex. If not then it means that all threads on the current
// mutex were woken up and a new waiting thread switched to a
@@ -161,7 +160,7 @@ impl Condvar {
} else {
RequeueOp::UnparkOne
}
};
} };
let callback = |_op, result: UnparkResult| {
// Clear our state if there are no more waiting threads
if !result.have_more_threads {
@@ -169,10 +168,9 @@ impl Condvar {
}
TOKEN_NORMAL
};
let res = parking_lot_core::unpark_requeue(from, to, validate, callback);
let res = unsafe { parking_lot_core::unpark_requeue(from, to, validate, callback) };
res.unparked_threads + res.requeued_threads != 0
}
}
/// Wakes up all blocked threads on this condvar.
@@ -197,11 +195,10 @@ impl Condvar {
#[cold]
fn notify_all_slow(&self, mutex: *mut RawMutex) -> usize {
unsafe {
// Unpark one thread and requeue the rest onto the mutex
let from = self as *const _ as usize;
let to = mutex as usize;
let validate = || {
let validate = unsafe { || {
// Make sure that our atomic state still points to the same
// mutex. If not then it means that all threads on the current
// mutex were woken up and a new waiting thread switched to a
@@ -226,19 +223,18 @@ impl Condvar {
} else {
RequeueOp::UnparkOneRequeueRest
}
};
} };
let callback = |op, result: UnparkResult| {
// If we requeued threads to the mutex, mark it as having
// parked threads. The RequeueAll case is already handled above.
if op == RequeueOp::UnparkOneRequeueRest && result.requeued_threads != 0 {
(*mutex).mark_parked();
unsafe { (*mutex).mark_parked() };
}
TOKEN_NORMAL
};
let res = parking_lot_core::unpark_requeue(from, to, validate, callback);
let res = unsafe { parking_lot_core::unpark_requeue(from, to, validate, callback) };
res.unparked_threads + res.requeued_threads
}
}
/// Blocks the current thread until this condition variable receives a
@@ -297,7 +293,6 @@ impl Condvar {
// This is a non-generic function to reduce the monomorphization cost of
// using `wait_until`.
fn wait_until_internal(&self, mutex: &RawMutex, timeout: Option<Instant>) -> WaitTimeoutResult {
unsafe {
let result;
let mut bad_mutex = false;
let mut requeued = false;
@@ -317,10 +312,10 @@ impl Condvar {
}
true
};
let before_sleep = || {
let before_sleep = unsafe { || {
// Unlock the mutex before sleeping...
mutex.unlock();
};
} };
let timed_out = |k, was_last_thread| {
// If we were requeued to a mutex, then we did not time out.
// We'll just park ourselves on the mutex again when we try
@@ -334,14 +329,14 @@ impl Condvar {
self.state.store(ptr::null_mut(), Ordering::Relaxed);
}
};
result = parking_lot_core::park(
result = unsafe { parking_lot_core::park(
addr,
validate,
before_sleep,
timed_out,
DEFAULT_PARK_TOKEN,
timeout,
);
) };
}
// Panic if we tried to use multiple mutexes with a Condvar. Note
@@ -353,13 +348,12 @@ impl Condvar {
// ... and re-lock it once we are done sleeping
if result == ParkResult::Unparked(TOKEN_HANDOFF) {
deadlock::acquire_resource(mutex as *const _ as usize);
unsafe { deadlock::acquire_resource(mutex as *const _ as usize) };
} else {
mutex.lock();
}
WaitTimeoutResult(!(result.is_unparked() || requeued))
}
}
/// Waits on this condition variable for a notification, timing out after a
+6 -6
View File
@@ -258,11 +258,11 @@ impl Once {
// Park our thread until we are woken up by the thread that owns the
// lock.
let addr = self as *const _ as usize;
let validate = || self.0.load(Ordering::Relaxed) == LOCKED_BIT | PARKED_BIT;
let before_sleep = || {};
let timed_out = |_, _| unreachable!();
unsafe {
let addr = self as *const _ as usize;
let validate = || self.0.load(Ordering::Relaxed) == LOCKED_BIT | PARKED_BIT;
let before_sleep = || {};
let timed_out = |_, _| unreachable!();
parking_lot_core::park(
addr,
validate,
@@ -285,8 +285,8 @@ impl Once {
let once = self.0;
let state = once.0.swap(POISON_BIT, Ordering::Release);
if state & PARKED_BIT != 0 {
let addr = once as *const _ as usize;
unsafe {
let addr = once as *const _ as usize;
parking_lot_core::unpark_all(addr, DEFAULT_UNPARK_TOKEN);
}
}
@@ -307,8 +307,8 @@ impl Once {
// Now unlock the state, set the done bit and unpark all threads
let state = self.0.swap(DONE_BIT, Ordering::Release);
if state & PARKED_BIT != 0 {
let addr = self as *const _ as usize;
unsafe {
let addr = self as *const _ as usize;
parking_lot_core::unpark_all(addr, DEFAULT_UNPARK_TOKEN);
}
}