diff options
| author | klutzy <klutzytheklutzy@gmail.com> | 2015-04-17 21:17:33 +0900 |
|---|---|---|
| committer | klutzy <klutzytheklutzy@gmail.com> | 2015-04-19 16:56:35 +0900 |
| commit | 4d80a823818f9953d9ff281f698404004356c328 (patch) | |
| tree | b7685d12bbc980b0acb9fd150fe5212aa338a5e7 | |
| parent | 049de3fe7f61d6ae5e6079981ed8e0e7701ea28e (diff) | |
| download | rust-4d80a823818f9953d9ff281f698404004356c328.tar.gz rust-4d80a823818f9953d9ff281f698404004356c328.zip | |
std::rand::os: Fix race condition of atomics
Fixes #21538.
| -rw-r--r-- | src/libstd/rand/os.rs | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index 6c107590237..30d5ae5c600 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -97,25 +97,24 @@ mod imp { target_arch = "powerpc")))] fn is_getrandom_available() -> bool { use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; + use sync::{Once, ONCE_INIT}; - static GETRANDOM_CHECKED: AtomicBool = ATOMIC_BOOL_INIT; - static GETRANDOM_AVAILABLE: AtomicBool = ATOMIC_BOOL_INIT; + static CHECKER: Once = ONCE_INIT; + static AVAILABLE: AtomicBool = ATOMIC_BOOL_INIT; - if !GETRANDOM_CHECKED.load(Ordering::Relaxed) { + CHECKER.call_once(|| { let mut buf: [u8; 0] = []; let result = getrandom(&mut buf); let available = if result == -1 { - let err = errno() as libc::c_int; - err != libc::ENOSYS + let err = io::Error::last_os_error().raw_os_error(); + err != Some(libc::ENOSYS) } else { true }; - GETRANDOM_AVAILABLE.store(available, Ordering::Relaxed); - GETRANDOM_CHECKED.store(true, Ordering::Relaxed); - available - } else { - GETRANDOM_AVAILABLE.load(Ordering::Relaxed) - } + AVAILABLE.store(available, Ordering::Relaxed); + }); + + AVAILABLE.load(Ordering::Relaxed) } #[cfg(not(all(target_os = "linux", |
