about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/sys')
-rw-r--r--library/std/src/sys/windows/rand.rs53
1 files changed, 22 insertions, 31 deletions
diff --git a/library/std/src/sys/windows/rand.rs b/library/std/src/sys/windows/rand.rs
index ec6c40d2f49..836fc148986 100644
--- a/library/std/src/sys/windows/rand.rs
+++ b/library/std/src/sys/windows/rand.rs
@@ -1,9 +1,9 @@
 use crate::io;
+use crate::lazy;
 use crate::mem;
-use crate::sync;
 use crate::sys::c;
 
-// The kinds of HashMap RNG that may be available
+/// The kinds of HashMap RNG that may be available
 #[derive(Clone, Copy, Debug, PartialEq)]
 enum HashMapRng {
     Preferred,
@@ -16,44 +16,35 @@ pub fn hashmap_random_keys() -> (u64, u64) {
             preferred_rng().expect("couldn't generate random bytes with preferred RNG")
         }
         HashMapRng::Fallback => {
-            fallback_rng().unwrap().expect("couldn't generate random bytes with fallback RNG")
+            fallback_rng().expect("couldn't generate random bytes with fallback RNG")
         }
     }
 }
 
-// Returns the HashMap RNG that should be used
-//
-// Panics if they are both broken
+/// Returns the HashMap RNG that should be used
+///
+/// Panics if they are both broken
 fn get_hashmap_rng() -> HashMapRng {
     // Assume that if the preferred RNG is broken the first time we use it, it likely means
     // that: the DLL has failed to load, there is no point to calling it over-and-over again,
     // and we should cache the result
-    static INIT: sync::Once = sync::Once::new();
-    static mut HASHMAP_RNG: HashMapRng = HashMapRng::Preferred;
-
-    unsafe {
-        INIT.call_once(|| HASHMAP_RNG = choose_hashmap_rng());
-        HASHMAP_RNG
-    }
+    static VALUE: lazy::SyncOnceCell<HashMapRng> = lazy::SyncOnceCell::new();
+    *VALUE.get_or_init(choose_hashmap_rng)
 }
 
-// Test whether we should use the preferred or fallback RNG
-//
-// If the preferred RNG is successful, we choose it. Otherwise, if the fallback RNG is successful,
-// we choose that
-//
-// Panics if both the preferred and the fallback RNG are both non-functional
+/// Test whether we should use the preferred or fallback RNG
+///
+/// If the preferred RNG is successful, we choose it. Otherwise, if the fallback RNG is successful,
+/// we choose that
+///
+/// Panics if both the preferred and the fallback RNG are both non-functional
 fn choose_hashmap_rng() -> HashMapRng {
     let preferred_error = match preferred_rng() {
         Ok(_) => return HashMapRng::Preferred,
         Err(e) => e,
     };
 
-    // On UWP, there is no fallback
-    let fallback_result = fallback_rng()
-        .unwrap_or_else(|| panic!("preferred RNG broken: `{}`, no fallback", preferred_error));
-
-    match fallback_result {
+    match fallback_rng() {
         Ok(_) => return HashMapRng::Fallback,
         Err(fallback_error) => panic!(
             "preferred RNG broken: `{}`, fallback RNG broken: `{}`",
@@ -62,7 +53,7 @@ fn choose_hashmap_rng() -> HashMapRng {
     }
 }
 
-// Generate random numbers using the preferred RNG function (BCryptGenRandom)
+/// Generate random numbers using the preferred RNG function (BCryptGenRandom)
 fn preferred_rng() -> Result<(u64, u64), io::Error> {
     use crate::ptr;
 
@@ -79,18 +70,18 @@ fn preferred_rng() -> Result<(u64, u64), io::Error> {
     if ret == 0 { Ok(v) } else { Err(io::Error::last_os_error()) }
 }
 
-// Generate random numbers using the fallback RNG function (RtlGenRandom)
+/// Generate random numbers using the fallback RNG function (RtlGenRandom)
 #[cfg(not(target_vendor = "uwp"))]
-fn fallback_rng() -> Option<Result<(u64, u64), io::Error>> {
+fn fallback_rng() -> Result<(u64, u64), io::Error> {
     let mut v = (0, 0);
     let ret =
         unsafe { c::RtlGenRandom(&mut v as *mut _ as *mut u8, mem::size_of_val(&v) as c::ULONG) };
 
-    Some(if ret != 0 { Ok(v) } else { Err(io::Error::last_os_error()) })
+    if ret != 0 { Ok(v) } else { Err(io::Error::last_os_error()) }
 }
 
-// We can't use RtlGenRandom with UWP, so there is no fallback
+/// We can't use RtlGenRandom with UWP, so there is no fallback
 #[cfg(target_vendor = "uwp")]
-fn fallback_rng() -> Option<Result<(u64, u64), io::Error>> {
-    None
+fn fallback_rng() -> Result<(u64, u64), io::Error> {
+    Err(io::const_io_error!(io::ErrorKind::Unsupported, "unsupported on UWP"))
 }