@@ -254,6 +254,7 @@ use std::mem;
254
254
use std:: io;
255
255
use std:: rc:: Rc ;
256
256
use std:: num:: Wrapping as w;
257
+ use std:: time;
257
258
258
259
pub use os:: OsRng ;
259
260
@@ -902,9 +903,9 @@ struct ThreadRngReseeder;
902
903
903
904
impl reseeding:: Reseeder < StdRng > for ThreadRngReseeder {
904
905
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 ( ) )
908
909
}
909
910
}
910
911
}
@@ -921,8 +922,9 @@ pub struct ThreadRng {
921
922
/// generator, seeded by the system. Intended to be used in method
922
923
/// chaining style, e.g. `thread_rng().gen::<i32>()`.
923
924
///
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.
926
928
///
927
929
/// The internal RNG used is platform and architecture dependent, even
928
930
/// if the operating system random number generator is rigged to give
@@ -933,7 +935,7 @@ pub fn thread_rng() -> ThreadRng {
933
935
thread_local ! ( static THREAD_RNG_KEY : Rc <RefCell <ThreadRngInner >> = {
934
936
let r = match StdRng :: new( ) {
935
937
Ok ( r) => r,
936
- Err ( e ) => panic! ( "could not initialize thread_rng: {}" , e )
938
+ Err ( _ ) => StdRng :: from_seed ( & weak_seed ( ) )
937
939
} ;
938
940
let rng = reseeding:: ReseedingRng :: new( r,
939
941
THREAD_RNG_RESEED_THRESHOLD ,
@@ -944,6 +946,14 @@ pub fn thread_rng() -> ThreadRng {
944
946
ThreadRng { rng : THREAD_RNG_KEY . with ( |t| t. clone ( ) ) }
945
947
}
946
948
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
+
947
957
impl Rng for ThreadRng {
948
958
fn next_u32 ( & mut self ) -> u32 {
949
959
self . rng . borrow_mut ( ) . next_u32 ( )
0 commit comments