From 4547b622d8d29df964fa2914213088b148c498fc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:32 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- library/std/src/sys_common/condvar.rs | 57 ----------------------- library/std/src/sys_common/condvar/check.rs | 58 ----------------------- library/std/src/sys_common/mod.rs | 4 +- library/std/src/sys_common/mutex.rs | 50 -------------------- library/std/src/sys_common/once/generic.rs | 1 + library/std/src/sys_common/remutex.rs | 10 ++-- library/std/src/sys_common/rwlock.rs | 71 ----------------------------- library/std/src/sys_common/wstr.rs | 59 ++++++++++++++++++++++++ 8 files changed, 66 insertions(+), 244 deletions(-) delete mode 100644 library/std/src/sys_common/condvar.rs delete mode 100644 library/std/src/sys_common/condvar/check.rs delete mode 100644 library/std/src/sys_common/mutex.rs delete mode 100644 library/std/src/sys_common/rwlock.rs create mode 100644 library/std/src/sys_common/wstr.rs (limited to 'library/std/src/sys_common') diff --git a/library/std/src/sys_common/condvar.rs b/library/std/src/sys_common/condvar.rs deleted file mode 100644 index 8bc5b2411..000000000 --- a/library/std/src/sys_common/condvar.rs +++ /dev/null @@ -1,57 +0,0 @@ -use crate::sys::locks as imp; -use crate::sys_common::mutex::MovableMutex; -use crate::time::Duration; - -mod check; - -type CondvarCheck = ::Check; - -/// An OS-based condition variable. -pub struct Condvar { - inner: imp::MovableCondvar, - check: CondvarCheck, -} - -impl Condvar { - /// Creates a new condition variable for use. - #[inline] - #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] - pub const fn new() -> Self { - Self { inner: imp::MovableCondvar::new(), check: CondvarCheck::new() } - } - - /// Signals one waiter on this condition variable to wake up. - #[inline] - pub fn notify_one(&self) { - unsafe { self.inner.notify_one() }; - } - - /// Awakens all current waiters on this condition variable. - #[inline] - pub fn notify_all(&self) { - unsafe { self.inner.notify_all() }; - } - - /// Waits for a signal on the specified mutex. - /// - /// Behavior is undefined if the mutex is not locked by the current thread. - /// - /// May panic if used with more than one mutex. - #[inline] - pub unsafe fn wait(&self, mutex: &MovableMutex) { - self.check.verify(mutex); - self.inner.wait(mutex.raw()) - } - - /// Waits for a signal on the specified mutex with a timeout duration - /// specified by `dur` (a relative time into the future). - /// - /// Behavior is undefined if the mutex is not locked by the current thread. - /// - /// May panic if used with more than one mutex. - #[inline] - pub unsafe fn wait_timeout(&self, mutex: &MovableMutex, dur: Duration) -> bool { - self.check.verify(mutex); - self.inner.wait_timeout(mutex.raw(), dur) - } -} diff --git a/library/std/src/sys_common/condvar/check.rs b/library/std/src/sys_common/condvar/check.rs deleted file mode 100644 index 4ac9e62bf..000000000 --- a/library/std/src/sys_common/condvar/check.rs +++ /dev/null @@ -1,58 +0,0 @@ -use crate::ptr; -use crate::sync::atomic::{AtomicPtr, Ordering}; -use crate::sys::locks as imp; -use crate::sys_common::lazy_box::{LazyBox, LazyInit}; -use crate::sys_common::mutex::MovableMutex; - -pub trait CondvarCheck { - type Check; -} - -/// For boxed mutexes, a `Condvar` will check it's only ever used with the same -/// mutex, based on its (stable) address. -impl CondvarCheck for LazyBox { - type Check = SameMutexCheck; -} - -pub struct SameMutexCheck { - addr: AtomicPtr<()>, -} - -#[allow(dead_code)] -impl SameMutexCheck { - pub const fn new() -> Self { - Self { addr: AtomicPtr::new(ptr::null_mut()) } - } - pub fn verify(&self, mutex: &MovableMutex) { - let addr = mutex.raw() as *const imp::Mutex as *const () as *mut _; - // Relaxed is okay here because we never read through `self.addr`, and only use it to - // compare addresses. - match self.addr.compare_exchange( - ptr::null_mut(), - addr, - Ordering::Relaxed, - Ordering::Relaxed, - ) { - Ok(_) => {} // Stored the address - Err(n) if n == addr => {} // Lost a race to store the same address - _ => panic!("attempted to use a condition variable with two mutexes"), - } - } -} - -/// Unboxed mutexes may move, so `Condvar` can not require its address to stay -/// constant. -impl CondvarCheck for imp::Mutex { - type Check = NoCheck; -} - -pub struct NoCheck; - -#[allow(dead_code)] -impl NoCheck { - #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] - pub const fn new() -> Self { - Self - } - pub fn verify(&self, _: &MovableMutex) {} -} diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 8c19f9332..b1987aa0f 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -21,20 +21,18 @@ mod tests; pub mod backtrace; -pub mod condvar; pub mod fs; pub mod io; pub mod lazy_box; pub mod memchr; -pub mod mutex; pub mod once; pub mod process; pub mod remutex; -pub mod rwlock; pub mod thread; pub mod thread_info; pub mod thread_local_dtor; pub mod thread_parker; +pub mod wstr; pub mod wtf8; cfg_if::cfg_if! { diff --git a/library/std/src/sys_common/mutex.rs b/library/std/src/sys_common/mutex.rs deleted file mode 100644 index 98046f20f..000000000 --- a/library/std/src/sys_common/mutex.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::sys::locks as imp; - -/// An OS-based mutual exclusion lock. -/// -/// This mutex cleans up its resources in its `Drop` implementation, may safely -/// be moved (when not borrowed), and does not cause UB when used reentrantly. -/// -/// This mutex does not implement poisoning. -/// -/// This is either a wrapper around `LazyBox` or `imp::Mutex`, -/// depending on the platform. It is boxed on platforms where `imp::Mutex` may -/// not be moved. -pub struct MovableMutex(imp::MovableMutex); - -unsafe impl Sync for MovableMutex {} - -impl MovableMutex { - /// Creates a new mutex. - #[inline] - #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] - pub const fn new() -> Self { - Self(imp::MovableMutex::new()) - } - - pub(super) fn raw(&self) -> &imp::Mutex { - &self.0 - } - - /// Locks the mutex blocking the current thread until it is available. - #[inline] - pub fn raw_lock(&self) { - unsafe { self.0.lock() } - } - - /// Attempts to lock the mutex without blocking, returning whether it was - /// successfully acquired or not. - #[inline] - pub fn try_lock(&self) -> bool { - unsafe { self.0.try_lock() } - } - - /// Unlocks the mutex. - /// - /// Behavior is undefined if the current thread does not actually hold the - /// mutex. - #[inline] - pub unsafe fn raw_unlock(&self) { - self.0.unlock() - } -} diff --git a/library/std/src/sys_common/once/generic.rs b/library/std/src/sys_common/once/generic.rs index acf5f2471..d953a6745 100644 --- a/library/std/src/sys_common/once/generic.rs +++ b/library/std/src/sys_common/once/generic.rs @@ -107,6 +107,7 @@ struct WaiterQueue<'a> { impl Once { #[inline] + #[rustc_const_stable(feature = "const_once_new", since = "1.32.0")] pub const fn new() -> Once { Once { state_and_queue: AtomicPtr::new(ptr::invalid_mut(INCOMPLETE)) } } diff --git a/library/std/src/sys_common/remutex.rs b/library/std/src/sys_common/remutex.rs index b448ae3a9..4c054da64 100644 --- a/library/std/src/sys_common/remutex.rs +++ b/library/std/src/sys_common/remutex.rs @@ -1,11 +1,11 @@ #[cfg(all(test, not(target_os = "emscripten")))] mod tests; -use super::mutex as sys; use crate::cell::UnsafeCell; use crate::ops::Deref; use crate::panic::{RefUnwindSafe, UnwindSafe}; use crate::sync::atomic::{AtomicUsize, Ordering::Relaxed}; +use crate::sys::locks as sys; /// A re-entrant mutual exclusion /// @@ -39,7 +39,7 @@ use crate::sync::atomic::{AtomicUsize, Ordering::Relaxed}; /// synchronization is left to the mutex, making relaxed memory ordering for /// the `owner` field fine in all cases. pub struct ReentrantMutex { - mutex: sys::MovableMutex, + mutex: sys::Mutex, owner: AtomicUsize, lock_count: UnsafeCell, data: T, @@ -74,7 +74,7 @@ impl ReentrantMutex { /// Creates a new reentrant mutex in an unlocked state. pub const fn new(t: T) -> ReentrantMutex { ReentrantMutex { - mutex: sys::MovableMutex::new(), + mutex: sys::Mutex::new(), owner: AtomicUsize::new(0), lock_count: UnsafeCell::new(0), data: t, @@ -100,7 +100,7 @@ impl ReentrantMutex { if self.owner.load(Relaxed) == this_thread { self.increment_lock_count(); } else { - self.mutex.raw_lock(); + self.mutex.lock(); self.owner.store(this_thread, Relaxed); debug_assert_eq!(*self.lock_count.get(), 0); *self.lock_count.get() = 1; @@ -162,7 +162,7 @@ impl Drop for ReentrantMutexGuard<'_, T> { *self.lock.lock_count.get() -= 1; if *self.lock.lock_count.get() == 0 { self.lock.owner.store(0, Relaxed); - self.lock.mutex.raw_unlock(); + self.lock.mutex.unlock(); } } } diff --git a/library/std/src/sys_common/rwlock.rs b/library/std/src/sys_common/rwlock.rs deleted file mode 100644 index 042981dac..000000000 --- a/library/std/src/sys_common/rwlock.rs +++ /dev/null @@ -1,71 +0,0 @@ -use crate::sys::locks as imp; - -/// An OS-based reader-writer lock. -/// -/// This rwlock cleans up its resources in its `Drop` implementation and may -/// safely be moved (when not borrowed). -/// -/// This rwlock does not implement poisoning. -/// -/// This is either a wrapper around `LazyBox` or `imp::RwLock`, -/// depending on the platform. It is boxed on platforms where `imp::RwLock` may -/// not be moved. -pub struct MovableRwLock(imp::MovableRwLock); - -impl MovableRwLock { - /// Creates a new reader-writer lock for use. - #[inline] - #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] - pub const fn new() -> Self { - Self(imp::MovableRwLock::new()) - } - - /// Acquires shared access to the underlying lock, blocking the current - /// thread to do so. - #[inline] - pub fn read(&self) { - unsafe { self.0.read() } - } - - /// Attempts to acquire shared access to this lock, returning whether it - /// succeeded or not. - /// - /// This function does not block the current thread. - #[inline] - pub fn try_read(&self) -> bool { - unsafe { self.0.try_read() } - } - - /// Acquires write access to the underlying lock, blocking the current thread - /// to do so. - #[inline] - pub fn write(&self) { - unsafe { self.0.write() } - } - - /// Attempts to acquire exclusive access to this lock, returning whether it - /// succeeded or not. - /// - /// This function does not block the current thread. - #[inline] - pub fn try_write(&self) -> bool { - unsafe { self.0.try_write() } - } - - /// Unlocks previously acquired shared access to this lock. - /// - /// Behavior is undefined if the current thread does not have shared access. - #[inline] - pub unsafe fn read_unlock(&self) { - self.0.read_unlock() - } - - /// Unlocks previously acquired exclusive access to this lock. - /// - /// Behavior is undefined if the current thread does not currently have - /// exclusive access. - #[inline] - pub unsafe fn write_unlock(&self) { - self.0.write_unlock() - } -} diff --git a/library/std/src/sys_common/wstr.rs b/library/std/src/sys_common/wstr.rs new file mode 100644 index 000000000..b230fd1a8 --- /dev/null +++ b/library/std/src/sys_common/wstr.rs @@ -0,0 +1,59 @@ +//! This module contains constructs to work with 16-bit characters (UCS-2 or UTF-16) +#![allow(dead_code)] + +use crate::marker::PhantomData; +use crate::num::NonZeroU16; +use crate::ptr::NonNull; + +/// A safe iterator over a LPWSTR +/// (aka a pointer to a series of UTF-16 code units terminated by a NULL). +pub struct WStrUnits<'a> { + // The pointer must never be null... + lpwstr: NonNull, + // ...and the memory it points to must be valid for this lifetime. + lifetime: PhantomData<&'a [u16]>, +} + +impl WStrUnits<'_> { + /// Create the iterator. Returns `None` if `lpwstr` is null. + /// + /// SAFETY: `lpwstr` must point to a null-terminated wide string that lives + /// at least as long as the lifetime of this struct. + pub unsafe fn new(lpwstr: *const u16) -> Option { + Some(Self { lpwstr: NonNull::new(lpwstr as _)?, lifetime: PhantomData }) + } + + pub fn peek(&self) -> Option { + // SAFETY: It's always safe to read the current item because we don't + // ever move out of the array's bounds. + unsafe { NonZeroU16::new(*self.lpwstr.as_ptr()) } + } + + /// Advance the iterator while `predicate` returns true. + /// Returns the number of items it advanced by. + pub fn advance_while bool>(&mut self, mut predicate: P) -> usize { + let mut counter = 0; + while let Some(w) = self.peek() { + if !predicate(w) { + break; + } + counter += 1; + self.next(); + } + counter + } +} + +impl Iterator for WStrUnits<'_> { + // This can never return zero as that marks the end of the string. + type Item = NonZeroU16; + fn next(&mut self) -> Option { + // SAFETY: If NULL is reached we immediately return. + // Therefore it's safe to advance the pointer after that. + unsafe { + let next = self.peek()?; + self.lpwstr = NonNull::new_unchecked(self.lpwstr.as_ptr().add(1)); + Some(next) + } + } +} -- cgit v1.2.3