Skip to content

Commit a8712f3

Browse files
authored
use_file: use Acquire/Release ordering instead of Relaxed (#469)
1 parent 480d6b0 commit a8712f3

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

src/use_file.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use core::{
77
cell::UnsafeCell,
88
ffi::c_void,
99
mem::MaybeUninit,
10-
sync::atomic::{AtomicI32, Ordering::Relaxed},
10+
sync::atomic::{AtomicI32, Ordering},
1111
};
1212

1313
/// For all platforms, we use `/dev/urandom` rather than `/dev/random`.
@@ -41,17 +41,30 @@ fn get_rng_fd() -> Result<libc::c_int, Error> {
4141
// need to use a different atomic type or make other accomodations. The
4242
// compiler will let us know if/when that is the case, because the
4343
// `FD.store(fd)` would fail to compile.
44+
//
45+
// The opening of the file, by libc/libstd/etc. may write some unknown
46+
// state into in-process memory. (Such state may include some sanitizer
47+
// bookkeeping, or we might be operating in a unikernal-like environment
48+
// where all the "kernel" file descriptor bookkeeping is done in our
49+
// process.) `get_fd_locked` stores into FD using `Ordering::Release` to
50+
// ensure any such state is synchronized. `get_fd` loads from `FD` with
51+
// `Ordering::Acquire` to synchronize with it.
4452
static FD: AtomicI32 = AtomicI32::new(FD_UNINIT);
4553

4654
fn get_fd() -> Option<libc::c_int> {
47-
match FD.load(Relaxed) {
55+
match FD.load(Ordering::Acquire) {
4856
FD_UNINIT => None,
4957
val => Some(val),
5058
}
5159
}
5260

5361
#[cold]
5462
fn get_fd_locked() -> Result<libc::c_int, Error> {
63+
// This mutex is used to prevent multiple threads from opening file
64+
// descriptors concurrently, which could run into the limit on the
65+
// number of open file descriptors. Our goal is to have no more than one
66+
// file descriptor open, ever.
67+
//
5568
// SAFETY: We use the mutex only in this method, and we always unlock it
5669
// before returning, making sure we don't violate the pthread_mutex_t API.
5770
static MUTEX: Mutex = Mutex::new();
@@ -68,7 +81,7 @@ fn get_rng_fd() -> Result<libc::c_int, Error> {
6881

6982
let fd = open_readonly(FILE_PATH)?;
7083
debug_assert!(fd != FD_UNINIT);
71-
FD.store(fd, Relaxed);
84+
FD.store(fd, Ordering::Release);
7285

7386
Ok(fd)
7487
}

0 commit comments

Comments
 (0)