Skip to content

Commit 6d297d5

Browse files
committed
Seed thread_rng with the current time if OsRng fails. Fixes #180.
1 parent 807b142 commit 6d297d5

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

src/lib.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ use std::mem;
254254
use std::io;
255255
use std::rc::Rc;
256256
use std::num::Wrapping as w;
257+
use std::time;
257258

258259
pub use os::OsRng;
259260

@@ -902,9 +903,9 @@ struct ThreadRngReseeder;
902903

903904
impl reseeding::Reseeder<StdRng> for ThreadRngReseeder {
904905
fn reseed(&mut self, rng: &mut StdRng) {
905-
*rng = match StdRng::new() {
906-
Ok(r) => r,
907-
Err(e) => panic!("could not reseed thread_rng: {}", e)
906+
match StdRng::new() {
907+
Ok(r) => *rng = r,
908+
Err(_) => rng.reseed(&weak_seed())
908909
}
909910
}
910911
}
@@ -921,8 +922,9 @@ pub struct ThreadRng {
921922
/// generator, seeded by the system. Intended to be used in method
922923
/// chaining style, e.g. `thread_rng().gen::<i32>()`.
923924
///
924-
/// The RNG provided will reseed itself from the operating system
925-
/// after generating a certain amount of randomness.
925+
/// After generating a certain amount of randomness, the RNG will reseed itself
926+
/// from the operating system or, if the operating system RNG returns an error,
927+
/// a seed based on the current system time.
926928
///
927929
/// The internal RNG used is platform and architecture dependent, even
928930
/// if the operating system random number generator is rigged to give
@@ -933,7 +935,7 @@ pub fn thread_rng() -> ThreadRng {
933935
thread_local!(static THREAD_RNG_KEY: Rc<RefCell<ThreadRngInner>> = {
934936
let r = match StdRng::new() {
935937
Ok(r) => r,
936-
Err(e) => panic!("could not initialize thread_rng: {}", e)
938+
Err(_) => StdRng::from_seed(&weak_seed())
937939
};
938940
let rng = reseeding::ReseedingRng::new(r,
939941
THREAD_RNG_RESEED_THRESHOLD,
@@ -944,6 +946,14 @@ pub fn thread_rng() -> ThreadRng {
944946
ThreadRng { rng: THREAD_RNG_KEY.with(|t| t.clone()) }
945947
}
946948

949+
fn weak_seed() -> [usize; 2] {
950+
let now = time::SystemTime::now();
951+
let unix_time = now.duration_since(time::UNIX_EPOCH).unwrap();
952+
let seconds = unix_time.as_secs() as usize;
953+
let nanoseconds = unix_time.subsec_nanos() as usize;
954+
[seconds, nanoseconds]
955+
}
956+
947957
impl Rng for ThreadRng {
948958
fn next_u32(&mut self) -> u32 {
949959
self.rng.borrow_mut().next_u32()

0 commit comments

Comments
 (0)