@@ -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
@@ -906,9 +907,9 @@ struct ThreadRngReseeder;
906
907
907
908
impl reseeding:: Reseeder < StdRng > for ThreadRngReseeder {
908
909
fn reseed ( & mut self , rng : & mut StdRng ) {
909
- * rng = match StdRng :: new ( ) {
910
- Ok ( r) => r,
911
- Err ( e ) => panic ! ( "could not reseed thread_rng: {}" , e )
910
+ match StdRng :: new ( ) {
911
+ Ok ( r) => * rng = r,
912
+ Err ( _ ) => rng . reseed ( & weak_seed ( ) )
912
913
}
913
914
}
914
915
}
@@ -925,8 +926,9 @@ pub struct ThreadRng {
925
926
/// generator, seeded by the system. Intended to be used in method
926
927
/// chaining style, e.g. `thread_rng().gen::<i32>()`.
927
928
///
928
- /// The RNG provided will reseed itself from the operating system
929
- /// after generating a certain amount of randomness.
929
+ /// After generating a certain amount of randomness, the RNG will reseed itself
930
+ /// from the operating system or, if the operating system RNG returns an error,
931
+ /// a seed based on the current system time.
930
932
///
931
933
/// The internal RNG used is platform and architecture dependent, even
932
934
/// if the operating system random number generator is rigged to give
@@ -937,7 +939,7 @@ pub fn thread_rng() -> ThreadRng {
937
939
thread_local ! ( static THREAD_RNG_KEY : Rc <RefCell <ThreadRngInner >> = {
938
940
let r = match StdRng :: new( ) {
939
941
Ok ( r) => r,
940
- Err ( e ) => panic! ( "could not initialize thread_rng: {}" , e )
942
+ Err ( _ ) => StdRng :: from_seed ( & weak_seed ( ) )
941
943
} ;
942
944
let rng = reseeding:: ReseedingRng :: new( r,
943
945
THREAD_RNG_RESEED_THRESHOLD ,
@@ -948,6 +950,14 @@ pub fn thread_rng() -> ThreadRng {
948
950
ThreadRng { rng : THREAD_RNG_KEY . with ( |t| t. clone ( ) ) }
949
951
}
950
952
953
+ fn weak_seed ( ) -> [ usize ; 2 ] {
954
+ let now = time:: SystemTime :: now ( ) ;
955
+ let unix_time = now. duration_since ( time:: UNIX_EPOCH ) . unwrap ( ) ;
956
+ let seconds = unix_time. as_secs ( ) as usize ;
957
+ let nanoseconds = unix_time. subsec_nanos ( ) as usize ;
958
+ [ seconds, nanoseconds]
959
+ }
960
+
951
961
impl Rng for ThreadRng {
952
962
fn next_u32 ( & mut self ) -> u32 {
953
963
self . rng . borrow_mut ( ) . next_u32 ( )
0 commit comments