Skip to content

Commit db2c45d

Browse files
committed
use_file: std::sync::Mutex, dropping all libpthread use.
pthreads mutexes are not safe to move. While it is very unlikely that the mutex we create will ever be moved, we don't actively do anything to actively prevent it from being moved. (libstd, when it used/uses pthreads mutexes, would box them to prevent them from being moved.) Also, now on Linux and Android (and many other targets for which we don't use use_std), libstd uses futexes instead of pthreads mutexes. Thus using libstd's Mutex will be more efficient and avoid adding an often-otherwise-unnecessary libpthreads dependency on these targets. * Linux, Android: Futex [1]. * Haiku, Redox, NTO, AIX: pthreads [2]. * others: not using `use_file`. This will not affect our plans for *-*-linux-none, since we don't plan to use `use_file` for it. This breaks 32-bit x86 QNX Neutrino, which doesn't have libstd because the target itself is abandoned [3]. the other QNX Neutrino targets didn't get libstd support until Rust 1.69, so this effectively raises the MSRV for them to 1.69. On x86_64 Linux, this change removes all libpthreads dependencies: - call qword ptr [rip + pthread_mutex_lock@GOTPCREL] - call qword ptr [rip + pthread_mutex_unlock@GOTPCREL] and adds these dependencies: + core::ptr::drop_in_place<std::sync::mutex::MutexGuard<()>> + std::panicking::panic_count::is_zero_slow_path + std::sys::sync::mutex::futex::Mutex::lock_contended + std::sys::sync::mutex::futex::Mutex::wake as measured using `cargo asm`. [1] https://github.com/rust-lang/rust/blob/c1dba09f263cbff6170f130aa418e28bdf22bd96/library/std/src/sys/sync/mutex/mod.rs#L4-L10 [2] https://github.com/rust-lang/rust/blob/c1dba09f263cbff6170f130aa418e28bdf22bd96/library/std/src/sys/sync/mutex/mod.rs#L17-L20 [3] rust-random#453 (comment)
1 parent 05cdf6f commit db2c45d

File tree

2 files changed

+8
-24
lines changed

2 files changed

+8
-24
lines changed

Diff for: src/error.rs

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ impl Error {
5858
pub const NODE_ES_MODULE: Error = internal_error(14);
5959
/// Calling Windows ProcessPrng failed.
6060
pub const WINDOWS_PROCESS_PRNG: Error = internal_error(15);
61+
/// The mutex used when opening the random file was poisoned.
62+
pub const UNEXPECTED_FILE_MUTEX_POISONED: Error = internal_error(15);
6163

6264
/// Codes below this point represent OS Errors (i.e. positive i32 values).
6365
/// Codes at or above this point, but below [`Error::CUSTOM_START`] are

Diff for: src/use_file.rs

+6-24
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ use crate::{
44
Error,
55
};
66
use core::{
7-
cell::UnsafeCell,
87
ffi::c_void,
98
mem::MaybeUninit,
109
sync::atomic::{AtomicUsize, Ordering::Relaxed},
1110
};
11+
extern crate std;
12+
use std::sync::{Mutex, PoisonError};
1213

1314
/// For all platforms, we use `/dev/urandom` rather than `/dev/random`.
1415
/// For more information see the linked man pages in lib.rs.
@@ -44,11 +45,10 @@ fn get_rng_fd() -> Result<libc::c_int, Error> {
4445

4546
#[cold]
4647
fn get_fd_locked() -> Result<libc::c_int, Error> {
47-
// SAFETY: We use the mutex only in this method, and we always unlock it
48-
// before returning, making sure we don't violate the pthread_mutex_t API.
49-
static MUTEX: Mutex = Mutex::new();
50-
unsafe { MUTEX.lock() };
51-
let _guard = DropGuard(|| unsafe { MUTEX.unlock() });
48+
static MUTEX: Mutex<()> = Mutex::new(());
49+
let _guard = MUTEX
50+
.lock()
51+
.map_err(|_: PoisonError<_>| Error::UNEXPECTED_FILE_MUTEX_POISONED)?;
5252

5353
if let Some(fd) = get_fd() {
5454
return Ok(fd);
@@ -129,24 +129,6 @@ fn wait_until_rng_ready() -> Result<(), Error> {
129129
}
130130
}
131131

132-
struct Mutex(UnsafeCell<libc::pthread_mutex_t>);
133-
134-
impl Mutex {
135-
const fn new() -> Self {
136-
Self(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER))
137-
}
138-
unsafe fn lock(&self) {
139-
let r = libc::pthread_mutex_lock(self.0.get());
140-
debug_assert_eq!(r, 0);
141-
}
142-
unsafe fn unlock(&self) {
143-
let r = libc::pthread_mutex_unlock(self.0.get());
144-
debug_assert_eq!(r, 0);
145-
}
146-
}
147-
148-
unsafe impl Sync for Mutex {}
149-
150132
struct DropGuard<F: FnMut()>(F);
151133

152134
impl<F: FnMut()> Drop for DropGuard<F> {

0 commit comments

Comments
 (0)