Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions library/std/src/io/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Mutex<Vec<u8>>>;
// This is explicitly using poisoning, as that affects what gets captured.
// FIXME: maybe change this to a non-poisoning mutex regardless?
type LocalStream = Arc<poison::Mutex<Vec<u8>>>;

thread_local! {
/// Used by the test crate to capture the output of the print macros and panics.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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 {}

Comment on lines +440 to +445
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The manual implementation is necessary to avoid a situation like #146087.

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Stdin {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down Expand Up @@ -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<usize> {
Expand Down
18 changes: 9 additions & 9 deletions library/std/src/io/stdio/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,36 +122,36 @@ 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 = {
let (log, tx) = (Arc::clone(&log), tx2);
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
Expand All @@ -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]
);
}
10 changes: 5 additions & 5 deletions library/std/src/sync/mpmc/waker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand All @@ -159,7 +159,7 @@ impl SyncWaker {
/// Unregisters an operation previously registered by the current thread.
#[inline]
pub(crate) fn unregister(&self, oper: Operation) -> Option<Entry> {
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);
Expand All @@ -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();
Expand All @@ -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);
Expand Down
20 changes: 10 additions & 10 deletions library/std/src/sync/mpmc/zero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -141,7 +141,7 @@ impl<T> Channel<T> {
/// Attempts to send a message into the channel.
pub(crate) fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> {
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() {
Expand All @@ -165,7 +165,7 @@ impl<T> Channel<T> {
deadline: Option<Instant>,
) -> Result<(), SendTimeoutError<T>> {
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() {
Expand Down Expand Up @@ -196,12 +196,12 @@ impl<T> Channel<T> {
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))
}
Expand All @@ -217,7 +217,7 @@ impl<T> Channel<T> {
/// Attempts to receive a message without blocking.
pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> {
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() {
Expand All @@ -234,7 +234,7 @@ impl<T> Channel<T> {
/// Receives a message from the channel.
pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> {
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() {
Expand Down Expand Up @@ -264,11 +264,11 @@ impl<T> Channel<T> {
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(_) => {
Expand All @@ -284,7 +284,7 @@ impl<T> Channel<T> {
///
/// 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;
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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<'_> {
Expand Down
12 changes: 6 additions & 6 deletions library/std/src/sys/env/hermit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Option<HashMap<OsString, OsString>>> = 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() {
Expand Down Expand Up @@ -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();
Expand All @@ -57,16 +57,16 @@ pub fn env() -> Env {
}

pub fn getenv(k: &OsStr) -> Option<OsString> {
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(())
}
2 changes: 1 addition & 1 deletion library/std/src/sys/pal/unix/stack_overflow/thread_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/process/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/thread/sgx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -48,7 +48,7 @@ mod task_queue {
static TASK_QUEUE: Mutex<Vec<Task>> = Mutex::new(Vec::new());

pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
TASK_QUEUE.lock().unwrap()
TASK_QUEUE.lock()
}
}

Expand Down
4 changes: 2 additions & 2 deletions library/std/src/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1257,11 +1257,11 @@ impl ThreadId {
}
}
_ => {
use crate::sync::{Mutex, PoisonError};
use crate::sync::nonpoison::Mutex;

static COUNTER: Mutex<u64> = 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.
Expand Down
Loading