summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parking_lot.rs4
-rw-r--r--src/thread_parker/unix.rs8
-rw-r--r--src/thread_parker/windows/bindings.rs31
-rw-r--r--src/thread_parker/windows/keyed_event.rs10
-rw-r--r--src/thread_parker/windows/mod.rs43
-rw-r--r--src/thread_parker/windows/waitaddress.rs36
6 files changed, 68 insertions, 64 deletions
diff --git a/src/parking_lot.rs b/src/parking_lot.rs
index b388619..d74b439 100644
--- a/src/parking_lot.rs
+++ b/src/parking_lot.rs
@@ -248,7 +248,7 @@ fn create_hashtable() -> &'static HashTable {
// Free the table we created
// SAFETY: `new_table` is created from `Box::into_raw` above and only freed here.
unsafe {
- Box::from_raw(new_table);
+ let _ = Box::from_raw(new_table);
}
old_table
}
@@ -1476,7 +1476,7 @@ mod tests {
test! {
unpark_all_one_fast(
- repeats: 10000, latches: 1, delay: 0, threads: 1, single_unparks: 0
+ repeats: 1000, latches: 1, delay: 0, threads: 1, single_unparks: 0
);
unpark_all_hundred_fast(
repeats: 100, latches: 1, delay: 0, threads: 100, single_unparks: 0
diff --git a/src/thread_parker/unix.rs b/src/thread_parker/unix.rs
index 7f28603..fdc1ed9 100644
--- a/src/thread_parker/unix.rs
+++ b/src/thread_parker/unix.rs
@@ -5,7 +5,7 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
+#[cfg(any(target_os = "macos", target_os = "tvos", target_os = "ios", target_os = "watchos"))]
use core::ptr;
use core::{
cell::{Cell, UnsafeCell},
@@ -130,6 +130,7 @@ impl ThreadParker {
#[cfg(any(
target_os = "macos",
target_os = "ios",
+ target_os = "tvos",
target_os = "watchos",
target_os = "android",
target_os = "espidf"
@@ -141,6 +142,7 @@ impl ThreadParker {
#[cfg(not(any(
target_os = "macos",
target_os = "ios",
+ target_os = "tvos",
target_os = "watchos",
target_os = "android",
target_os = "espidf"
@@ -195,7 +197,7 @@ impl super::UnparkHandleT for UnparkHandle {
}
// Returns the current time on the clock used by pthread_cond_t as a timespec.
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
+#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
#[inline]
fn timespec_now() -> libc::timespec {
let mut now = MaybeUninit::<libc::timeval>::uninit();
@@ -208,7 +210,7 @@ fn timespec_now() -> libc::timespec {
tv_nsec: now.tv_usec as tv_nsec_t * 1000,
}
}
-#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "watchos")))]
+#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos")))]
#[inline]
fn timespec_now() -> libc::timespec {
let mut now = MaybeUninit::<libc::timespec>::uninit();
diff --git a/src/thread_parker/windows/bindings.rs b/src/thread_parker/windows/bindings.rs
new file mode 100644
index 0000000..3c37dfa
--- /dev/null
+++ b/src/thread_parker/windows/bindings.rs
@@ -0,0 +1,31 @@
+//! Manual bindings to the win32 API to avoid dependencies on windows-sys or winapi
+//! as these bindings will **never** change and parking_lot_core is a foundational
+//! dependency for the Rust ecosystem, so the dependencies used by it have an
+//! outsize affect
+
+pub const INFINITE: u32 = 4294967295;
+pub const ERROR_TIMEOUT: u32 = 1460;
+pub const GENERIC_READ: u32 = 2147483648;
+pub const GENERIC_WRITE: u32 = 1073741824;
+pub const STATUS_SUCCESS: i32 = 0;
+pub const STATUS_TIMEOUT: i32 = 258;
+
+pub type HANDLE = isize;
+pub type HINSTANCE = isize;
+pub type BOOL = i32;
+pub type BOOLEAN = u8;
+pub type NTSTATUS = i32;
+pub type FARPROC = Option<unsafe extern "system" fn() -> isize>;
+pub type WaitOnAddress = unsafe extern "system" fn(
+ Address: *const std::ffi::c_void,
+ CompareAddress: *const std::ffi::c_void,
+ AddressSize: usize,
+ dwMilliseconds: u32,
+) -> BOOL;
+pub type WakeByAddressSingle = unsafe extern "system" fn(Address: *const std::ffi::c_void);
+
+windows_targets::link!("kernel32.dll" "system" fn GetLastError() -> u32);
+windows_targets::link!("kernel32.dll" "system" fn CloseHandle(hObject: HANDLE) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn GetModuleHandleA(lpModuleName: *const u8) -> HINSTANCE);
+windows_targets::link!("kernel32.dll" "system" fn GetProcAddress(hModule: HINSTANCE, lpProcName: *const u8) -> FARPROC);
+windows_targets::link!("kernel32.dll" "system" fn Sleep(dwMilliseconds: u32) -> ());
diff --git a/src/thread_parker/windows/keyed_event.rs b/src/thread_parker/windows/keyed_event.rs
index 302bab5..84a71d0 100644
--- a/src/thread_parker/windows/keyed_event.rs
+++ b/src/thread_parker/windows/keyed_event.rs
@@ -13,18 +13,12 @@ use core::{
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Instant;
-use windows_sys::Win32::{
- Foundation::{CloseHandle, BOOLEAN, HANDLE, NTSTATUS, STATUS_SUCCESS, STATUS_TIMEOUT},
- System::{
- LibraryLoader::{GetModuleHandleA, GetProcAddress},
- SystemServices::{GENERIC_READ, GENERIC_WRITE},
- },
-};
-
const STATE_UNPARKED: usize = 0;
const STATE_PARKED: usize = 1;
const STATE_TIMED_OUT: usize = 2;
+use super::bindings::*;
+
#[allow(non_snake_case)]
pub struct KeyedEvent {
handle: HANDLE,
diff --git a/src/thread_parker/windows/mod.rs b/src/thread_parker/windows/mod.rs
index 1f5ed23..27028a1 100644
--- a/src/thread_parker/windows/mod.rs
+++ b/src/thread_parker/windows/mod.rs
@@ -11,6 +11,7 @@ use core::{
};
use std::time::Instant;
+mod bindings;
mod keyed_event;
mod waitaddress;
@@ -60,7 +61,7 @@ impl Backend {
Err(global_backend_ptr) => {
unsafe {
// We lost the race, free our object and return the global one
- Box::from_raw(backend_ptr);
+ let _ = Box::from_raw(backend_ptr);
&*global_backend_ptr
}
}
@@ -74,11 +75,13 @@ pub struct ThreadParker {
backend: &'static Backend,
}
-impl ThreadParker {
- pub const IS_CHEAP_TO_CONSTRUCT: bool = true;
+impl super::ThreadParkerT for ThreadParker {
+ type UnparkHandle = UnparkHandle;
+
+ const IS_CHEAP_TO_CONSTRUCT: bool = true;
#[inline]
- pub fn new() -> ThreadParker {
+ fn new() -> ThreadParker {
// Initialize the backend here to ensure we don't get any panics
// later on, which could leave synchronization primitives in a broken
// state.
@@ -90,7 +93,7 @@ impl ThreadParker {
// Prepares the parker. This should be called before adding it to the queue.
#[inline]
- pub fn prepare_park(&self) {
+ unsafe fn prepare_park(&self) {
match *self.backend {
Backend::KeyedEvent(ref x) => x.prepare_park(&self.key),
Backend::WaitAddress(ref x) => x.prepare_park(&self.key),
@@ -100,7 +103,7 @@ impl ThreadParker {
// Checks if the park timed out. This should be called while holding the
// queue lock after park_until has returned false.
#[inline]
- pub fn timed_out(&self) -> bool {
+ unsafe fn timed_out(&self) -> bool {
match *self.backend {
Backend::KeyedEvent(ref x) => x.timed_out(&self.key),
Backend::WaitAddress(ref x) => x.timed_out(&self.key),
@@ -110,7 +113,7 @@ impl ThreadParker {
// Parks the thread until it is unparked. This should be called after it has
// been added to the queue, after unlocking the queue.
#[inline]
- pub unsafe fn park(&self) {
+ unsafe fn park(&self) {
match *self.backend {
Backend::KeyedEvent(ref x) => x.park(&self.key),
Backend::WaitAddress(ref x) => x.park(&self.key),
@@ -121,7 +124,7 @@ impl ThreadParker {
// should be called after it has been added to the queue, after unlocking
// the queue. Returns true if we were unparked and false if we timed out.
#[inline]
- pub unsafe fn park_until(&self, timeout: Instant) -> bool {
+ unsafe fn park_until(&self, timeout: Instant) -> bool {
match *self.backend {
Backend::KeyedEvent(ref x) => x.park_until(&self.key, timeout),
Backend::WaitAddress(ref x) => x.park_until(&self.key, timeout),
@@ -132,7 +135,7 @@ impl ThreadParker {
// necessary to ensure that thread-local ThreadData objects remain valid.
// This should be called while holding the queue lock.
#[inline]
- pub unsafe fn unpark_lock(&self) -> UnparkHandle {
+ unsafe fn unpark_lock(&self) -> UnparkHandle {
match *self.backend {
Backend::KeyedEvent(ref x) => UnparkHandle::KeyedEvent(x.unpark_lock(&self.key)),
Backend::WaitAddress(ref x) => UnparkHandle::WaitAddress(x.unpark_lock(&self.key)),
@@ -148,11 +151,11 @@ pub enum UnparkHandle {
WaitAddress(waitaddress::UnparkHandle),
}
-impl UnparkHandle {
+impl super::UnparkHandleT for UnparkHandle {
// Wakes up the parked thread. This should be called after the queue lock is
// released to avoid blocking the queue for too long.
#[inline]
- pub unsafe fn unpark(self) {
+ unsafe fn unpark(self) {
match self {
UnparkHandle::KeyedEvent(x) => x.unpark(),
UnparkHandle::WaitAddress(x) => x.unpark(),
@@ -163,26 +166,10 @@ impl UnparkHandle {
// Yields the rest of the current timeslice to the OS
#[inline]
pub fn thread_yield() {
- // Note that this is manually defined here rather than using the definition
- // through `winapi`. The `winapi` definition comes from the `synchapi`
- // header which enables the "synchronization.lib" library. It turns out,
- // however that `Sleep` comes from `kernel32.dll` so this activation isn't
- // necessary.
- //
- // This was originally identified in rust-lang/rust where on MinGW the
- // libsynchronization.a library pulls in a dependency on a newer DLL not
- // present in older versions of Windows. (see rust-lang/rust#49438)
- //
- // This is a bit of a hack for now and ideally we'd fix MinGW's own import
- // libraries, but that'll probably take a lot longer than patching this here
- // and avoiding the `synchapi` feature entirely.
- extern "system" {
- fn Sleep(a: u32);
- }
unsafe {
// We don't use SwitchToThread here because it doesn't consider all
// threads in the system and the thread we are waiting for may not get
// selected.
- Sleep(0);
+ bindings::Sleep(0);
}
}
diff --git a/src/thread_parker/windows/waitaddress.rs b/src/thread_parker/windows/waitaddress.rs
index ef6cb44..41df45f 100644
--- a/src/thread_parker/windows/waitaddress.rs
+++ b/src/thread_parker/windows/waitaddress.rs
@@ -10,30 +10,18 @@ use core::{
sync::atomic::{AtomicUsize, Ordering},
};
use std::{ffi, time::Instant};
-use windows_sys::Win32::{
- Foundation::{GetLastError, BOOL, ERROR_TIMEOUT},
- System::{
- LibraryLoader::{GetModuleHandleA, GetProcAddress},
- WindowsProgramming::INFINITE,
- },
-};
+
+use super::bindings::*;
#[allow(non_snake_case)]
pub struct WaitAddress {
- WaitOnAddress: extern "system" fn(
- Address: *mut ffi::c_void,
- CompareAddress: *mut ffi::c_void,
- AddressSize: usize,
- dwMilliseconds: u32,
- ) -> BOOL,
- WakeByAddressSingle: extern "system" fn(Address: *mut ffi::c_void),
+ WaitOnAddress: WaitOnAddress,
+ WakeByAddressSingle: WakeByAddressSingle,
}
impl WaitAddress {
#[allow(non_snake_case)]
pub fn create() -> Option<WaitAddress> {
- // MSDN claims that that WaitOnAddress and WakeByAddressSingle are
- // located in kernel32.dll, but they are lying...
let synch_dll = unsafe { GetModuleHandleA(b"api-ms-win-core-synch-l1-2-0.dll\0".as_ptr()) };
if synch_dll == 0 {
return None;
@@ -108,12 +96,14 @@ impl WaitAddress {
#[inline]
fn wait_on_address(&'static self, key: &AtomicUsize, timeout: u32) -> BOOL {
let cmp = 1usize;
- (self.WaitOnAddress)(
- key as *const _ as *mut ffi::c_void,
- &cmp as *const _ as *mut ffi::c_void,
- mem::size_of::<usize>(),
- timeout,
- )
+ unsafe {
+ (self.WaitOnAddress)(
+ key as *const _ as *mut ffi::c_void,
+ &cmp as *const _ as *mut ffi::c_void,
+ mem::size_of::<usize>(),
+ timeout,
+ )
+ }
}
}
@@ -130,6 +120,6 @@ impl UnparkHandle {
// released to avoid blocking the queue for too long.
#[inline]
pub fn unpark(self) {
- (self.waitaddress.WakeByAddressSingle)(self.key as *mut ffi::c_void);
+ unsafe { (self.waitaddress.WakeByAddressSingle)(self.key as *mut ffi::c_void) };
}
}