diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 2d80fe49e80a7..3686b6673cc0f 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -12,11 +12,14 @@ use crate::io::{ }; use crate::panic::{RefUnwindSafe, UnwindSafe}; use crate::sync::atomic::{Atomic, AtomicBool, Ordering}; -use crate::sync::{Arc, Mutex, MutexGuard, OnceLock, ReentrantLock, ReentrantLockGuard}; +use crate::sync::nonpoison::{Mutex, MutexGuard}; +use crate::sync::{Arc, OnceLock, ReentrantLock, ReentrantLockGuard, poison}; use crate::sys::stdio; use crate::thread::AccessError; -type LocalStream = Arc>>; +// This is explicitly using poisoning, as that affects what gets captured. +// FIXME: maybe change this to a non-poisoning mutex regardless? +type LocalStream = Arc>>; thread_local! { /// Used by the test crate to capture the output of the print macros and panics. @@ -372,7 +375,7 @@ impl Stdin { pub fn lock(&self) -> StdinLock<'static> { // Locks this handle with 'static lifetime. This depends on the // implementation detail that the underlying `Mutex` is static. - StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } + StdinLock { inner: self.inner.lock() } } /// Locks this handle and reads a line of input, appending it to the specified buffer. @@ -434,6 +437,12 @@ impl Stdin { } } +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl UnwindSafe for Stdin {} + +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl RefUnwindSafe for Stdin {} + #[stable(feature = "std_debug", since = "1.16.0")] impl fmt::Debug for Stdin { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -507,6 +516,12 @@ impl StdinLock<'_> { } } +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl UnwindSafe for StdinLock<'_> {} + +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl RefUnwindSafe for StdinLock<'_> {} + #[stable(feature = "rust1", since = "1.0.0")] impl Read for StdinLock<'_> { fn read(&mut self, buf: &mut [u8]) -> io::Result { diff --git a/library/std/src/io/stdio/tests.rs b/library/std/src/io/stdio/tests.rs index e68d8c29fbce2..58f04720961eb 100644 --- a/library/std/src/io/stdio/tests.rs +++ b/library/std/src/io/stdio/tests.rs @@ -122,21 +122,21 @@ where let th1 = { let (log, tx) = (Arc::clone(&log), tx1); thread::spawn(move || { - log.lock().unwrap().push(Start1); + log.lock().push(Start1); let handle = get_handle(); { let locked = handle.lock(); - log.lock().unwrap().push(Acquire1); + log.lock().push(Acquire1); tx.send(Acquire1).unwrap(); // notify of acquisition tx.send(Release1).unwrap(); // wait for release command - log.lock().unwrap().push(Release1); + log.lock().push(Release1); } tx.send(Acquire1).unwrap(); // wait for th2 acquire { let locked = handle.lock(); - log.lock().unwrap().push(Acquire1); + log.lock().push(Acquire1); } - log.lock().unwrap().push(Release1); + log.lock().push(Release1); }) }; let th2 = { @@ -144,14 +144,14 @@ where thread::spawn(move || { tx.send(Start2).unwrap(); // wait for start command let locked = get_locked(); - log.lock().unwrap().push(Acquire2); + log.lock().push(Acquire2); tx.send(Acquire2).unwrap(); // notify of acquisition tx.send(Release2).unwrap(); // wait for release command - log.lock().unwrap().push(Release2); + log.lock().push(Release2); }) }; assert_eq!(rx1.recv().unwrap(), Acquire1); // wait for th1 acquire - log.lock().unwrap().push(Start2); + log.lock().push(Start2); assert_eq!(rx2.recv().unwrap(), Start2); // block th2 assert_eq!(rx1.recv().unwrap(), Release1); // release th1 assert_eq!(rx2.recv().unwrap(), Acquire2); // wait for th2 acquire @@ -160,7 +160,7 @@ where th2.join().unwrap(); th1.join().unwrap(); assert_eq!( - *log.lock().unwrap(), + *log.lock(), [Start1, Acquire1, Start2, Release1, Acquire2, Release2, Acquire1, Release1] ); } diff --git a/library/std/src/sync/mpmc/waker.rs b/library/std/src/sync/mpmc/waker.rs index 4216fb7ac5902..219263b84bb03 100644 --- a/library/std/src/sync/mpmc/waker.rs +++ b/library/std/src/sync/mpmc/waker.rs @@ -3,8 +3,8 @@ use super::context::Context; use super::select::{Operation, Selected}; use crate::ptr; -use crate::sync::Mutex; use crate::sync::atomic::{Atomic, AtomicBool, Ordering}; +use crate::sync::nonpoison::Mutex; /// Represents a thread blocked on a specific channel operation. pub(crate) struct Entry { @@ -150,7 +150,7 @@ impl SyncWaker { /// Registers the current thread with an operation. #[inline] pub(crate) fn register(&self, oper: Operation, cx: &Context) { - let mut inner = self.inner.lock().unwrap(); + let mut inner = self.inner.lock(); inner.register(oper, cx); self.is_empty .store(inner.selectors.is_empty() && inner.observers.is_empty(), Ordering::SeqCst); @@ -159,7 +159,7 @@ impl SyncWaker { /// Unregisters an operation previously registered by the current thread. #[inline] pub(crate) fn unregister(&self, oper: Operation) -> Option { - let mut inner = self.inner.lock().unwrap(); + let mut inner = self.inner.lock(); let entry = inner.unregister(oper); self.is_empty .store(inner.selectors.is_empty() && inner.observers.is_empty(), Ordering::SeqCst); @@ -170,7 +170,7 @@ impl SyncWaker { #[inline] pub(crate) fn notify(&self) { if !self.is_empty.load(Ordering::SeqCst) { - let mut inner = self.inner.lock().unwrap(); + let mut inner = self.inner.lock(); if !self.is_empty.load(Ordering::SeqCst) { inner.try_select(); inner.notify(); @@ -185,7 +185,7 @@ impl SyncWaker { /// Notifies all threads that the channel is disconnected. #[inline] pub(crate) fn disconnect(&self) { - let mut inner = self.inner.lock().unwrap(); + let mut inner = self.inner.lock(); inner.disconnect(); self.is_empty .store(inner.selectors.is_empty() && inner.observers.is_empty(), Ordering::SeqCst); diff --git a/library/std/src/sync/mpmc/zero.rs b/library/std/src/sync/mpmc/zero.rs index f1ecf80fcb9f6..383961801a725 100644 --- a/library/std/src/sync/mpmc/zero.rs +++ b/library/std/src/sync/mpmc/zero.rs @@ -9,8 +9,8 @@ use super::utils::Backoff; use super::waker::Waker; use crate::cell::UnsafeCell; use crate::marker::PhantomData; -use crate::sync::Mutex; use crate::sync::atomic::{Atomic, AtomicBool, Ordering}; +use crate::sync::nonpoison::Mutex; use crate::time::Instant; use crate::{fmt, ptr}; @@ -141,7 +141,7 @@ impl Channel { /// Attempts to send a message into the channel. pub(crate) fn try_send(&self, msg: T) -> Result<(), TrySendError> { let token = &mut Token::default(); - let mut inner = self.inner.lock().unwrap(); + let mut inner = self.inner.lock(); // If there's a waiting receiver, pair up with it. if let Some(operation) = inner.receivers.try_select() { @@ -165,7 +165,7 @@ impl Channel { deadline: Option, ) -> Result<(), SendTimeoutError> { let token = &mut Token::default(); - let mut inner = self.inner.lock().unwrap(); + let mut inner = self.inner.lock(); // If there's a waiting receiver, pair up with it. if let Some(operation) = inner.receivers.try_select() { @@ -196,12 +196,12 @@ impl Channel { match sel { Selected::Waiting => unreachable!(), Selected::Aborted => { - self.inner.lock().unwrap().senders.unregister(oper).unwrap(); + self.inner.lock().senders.unregister(oper).unwrap(); let msg = unsafe { packet.msg.get().replace(None).unwrap() }; Err(SendTimeoutError::Timeout(msg)) } Selected::Disconnected => { - self.inner.lock().unwrap().senders.unregister(oper).unwrap(); + self.inner.lock().senders.unregister(oper).unwrap(); let msg = unsafe { packet.msg.get().replace(None).unwrap() }; Err(SendTimeoutError::Disconnected(msg)) } @@ -217,7 +217,7 @@ impl Channel { /// Attempts to receive a message without blocking. pub(crate) fn try_recv(&self) -> Result { let token = &mut Token::default(); - let mut inner = self.inner.lock().unwrap(); + let mut inner = self.inner.lock(); // If there's a waiting sender, pair up with it. if let Some(operation) = inner.senders.try_select() { @@ -234,7 +234,7 @@ impl Channel { /// Receives a message from the channel. pub(crate) fn recv(&self, deadline: Option) -> Result { let token = &mut Token::default(); - let mut inner = self.inner.lock().unwrap(); + let mut inner = self.inner.lock(); // If there's a waiting sender, pair up with it. if let Some(operation) = inner.senders.try_select() { @@ -264,11 +264,11 @@ impl Channel { match sel { Selected::Waiting => unreachable!(), Selected::Aborted => { - self.inner.lock().unwrap().receivers.unregister(oper).unwrap(); + self.inner.lock().receivers.unregister(oper).unwrap(); Err(RecvTimeoutError::Timeout) } Selected::Disconnected => { - self.inner.lock().unwrap().receivers.unregister(oper).unwrap(); + self.inner.lock().receivers.unregister(oper).unwrap(); Err(RecvTimeoutError::Disconnected) } Selected::Operation(_) => { @@ -284,7 +284,7 @@ impl Channel { /// /// Returns `true` if this call disconnected the channel. pub(crate) fn disconnect(&self) -> bool { - let mut inner = self.inner.lock().unwrap(); + let mut inner = self.inner.lock(); if !inner.is_disconnected { inner.is_disconnected = true; diff --git a/library/std/src/sys/backtrace.rs b/library/std/src/sys/backtrace.rs index 57682207e078e..e5084c15b80ca 100644 --- a/library/std/src/sys/backtrace.rs +++ b/library/std/src/sys/backtrace.rs @@ -5,7 +5,7 @@ use crate::backtrace_rs::{self, BacktraceFmt, BytesOrWideString, PrintFmt}; use crate::borrow::Cow; use crate::io::prelude::*; use crate::path::{self, Path, PathBuf}; -use crate::sync::{Mutex, MutexGuard, PoisonError}; +use crate::sync::nonpoison::{Mutex, MutexGuard}; use crate::{env, fmt, io}; /// Max number of frames to print. @@ -15,7 +15,7 @@ pub(crate) struct BacktraceLock<'a>(#[allow(dead_code)] MutexGuard<'a, ()>); pub(crate) fn lock<'a>() -> BacktraceLock<'a> { static LOCK: Mutex<()> = Mutex::new(()); - BacktraceLock(LOCK.lock().unwrap_or_else(PoisonError::into_inner)) + BacktraceLock(LOCK.lock()) } impl BacktraceLock<'_> { diff --git a/library/std/src/sys/env/hermit.rs b/library/std/src/sys/env/hermit.rs index 445ecdeb6a39f..488f194a0aec4 100644 --- a/library/std/src/sys/env/hermit.rs +++ b/library/std/src/sys/env/hermit.rs @@ -5,12 +5,12 @@ use crate::collections::HashMap; use crate::ffi::{CStr, OsStr, OsString, c_char}; use crate::io; use crate::os::hermit::ffi::OsStringExt; -use crate::sync::Mutex; +use crate::sync::nonpoison::Mutex; static ENV: Mutex>> = Mutex::new(None); pub fn init(env: *const *const c_char) { - let mut guard = ENV.lock().unwrap(); + let mut guard = ENV.lock(); let map = guard.insert(HashMap::new()); if env.is_null() { @@ -48,7 +48,7 @@ pub fn init(env: *const *const c_char) { /// Returns a vector of (variable, value) byte-vector pairs for all the /// environment variables of the current process. pub fn env() -> Env { - let guard = ENV.lock().unwrap(); + let guard = ENV.lock(); let env = guard.as_ref().unwrap(); let result = env.iter().map(|(key, value)| (key.clone(), value.clone())).collect(); @@ -57,16 +57,16 @@ pub fn env() -> Env { } pub fn getenv(k: &OsStr) -> Option { - ENV.lock().unwrap().as_ref().unwrap().get(k).cloned() + ENV.lock().as_ref().unwrap().get(k).cloned() } pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { let (k, v) = (k.to_owned(), v.to_owned()); - ENV.lock().unwrap().as_mut().unwrap().insert(k, v); + ENV.lock().as_mut().unwrap().insert(k, v); Ok(()) } pub unsafe fn unsetenv(k: &OsStr) -> io::Result<()> { - ENV.lock().unwrap().as_mut().unwrap().remove(k); + ENV.lock().as_mut().unwrap().remove(k); Ok(()) } diff --git a/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs b/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs index e81429b98a6c7..2a8878c569184 100644 --- a/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs +++ b/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs @@ -27,8 +27,8 @@ use crate::collections::BTreeMap; use crate::hint::spin_loop; use crate::ops::Range; -use crate::sync::Mutex; use crate::sync::atomic::{AtomicUsize, Ordering}; +use crate::sync::nonpoison::Mutex; use crate::sys::os::errno_location; pub struct ThreadInfo { diff --git a/library/std/src/sys/process/windows.rs b/library/std/src/sys/process/windows.rs index 7d58093c54bbf..3c79283c12ceb 100644 --- a/library/std/src/sys/process/windows.rs +++ b/library/std/src/sys/process/windows.rs @@ -16,7 +16,7 @@ use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, FromRawHandl use crate::os::windows::process::ProcThreadAttributeList; use crate::path::{Path, PathBuf}; use crate::process::StdioPipes; -use crate::sync::Mutex; +use crate::sync::nonpoison::Mutex; use crate::sys::args::{self, Arg}; use crate::sys::c::{self, EXIT_FAILURE, EXIT_SUCCESS}; use crate::sys::fs::{File, OpenOptions}; diff --git a/library/std/src/sys/thread/sgx.rs b/library/std/src/sys/thread/sgx.rs index f20ef7d86b9c7..c0fb33e0edef8 100644 --- a/library/std/src/sys/thread/sgx.rs +++ b/library/std/src/sys/thread/sgx.rs @@ -12,7 +12,7 @@ pub use self::task_queue::JoinNotifier; mod task_queue { use super::wait_notify; - use crate::sync::{Mutex, MutexGuard}; + use crate::sync::nonpoison::{Mutex, MutexGuard}; pub type JoinHandle = wait_notify::Waiter; @@ -48,7 +48,7 @@ mod task_queue { static TASK_QUEUE: Mutex> = Mutex::new(Vec::new()); pub(super) fn lock() -> MutexGuard<'static, Vec> { - TASK_QUEUE.lock().unwrap() + TASK_QUEUE.lock() } } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 16313da8e178c..89a828181e960 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1257,11 +1257,11 @@ impl ThreadId { } } _ => { - use crate::sync::{Mutex, PoisonError}; + use crate::sync::nonpoison::Mutex; static COUNTER: Mutex = Mutex::new(0); - let mut counter = COUNTER.lock().unwrap_or_else(PoisonError::into_inner); + let mut counter = COUNTER.lock(); let Some(id) = counter.checked_add(1) else { // in case the panic handler ends up calling `ThreadId::new()`, // avoid reentrant lock acquire.