@@ -986,7 +986,9 @@ impl Rng for ThreadRng {
986
986
/// `EntropyRng` uses the interface for random numbers provided by the operating
987
987
/// system ([`OsRng`]). If that returns an error, it will fall back to the
988
988
/// [`JitterRng`] entropy collector. Occasionally it will then check if `OsRng`
989
- /// is still not available, and switch back if possible.
989
+ /// is still not available, and switch back if possible. Once every 8 calls to
990
+ /// `try_fill_bytes` if `OsRng` failed with `ErrorKind:Unavailable`, otherwise
991
+ /// with every call.
990
992
///
991
993
/// [`OsRng`]: os/struct.OsRng.html
992
994
/// [`JitterRng`]: jitter/struct.JitterRng.html
@@ -1074,22 +1076,28 @@ impl Rng for EntropyRng {
1074
1076
}
1075
1077
}
1076
1078
EntropySource :: Jitter ( ref mut rng) => {
1077
- if self . counter >= 8 {
1078
- if let Ok ( os_rng) = try_os_new ( dest) {
1079
- switch_rng = Some ( EntropySource :: Os ( os_rng) ) ;
1080
- } else {
1081
- self . counter = ( self . counter + 1 ) % 8 ;
1082
- return rng. try_fill_bytes ( dest) ; // use JitterRng
1079
+ if self . counter == 0 {
1080
+ match try_os_new ( dest) {
1081
+ Ok ( os_rng) => {
1082
+ switch_rng = Some ( EntropySource :: Os ( os_rng) ) ;
1083
+ }
1084
+ Err ( e) => {
1085
+ if e. kind ( ) == ErrorKind :: Unavailable {
1086
+ self . counter = 8 ; // Wait 8 calls before retry
1087
+ } else {
1088
+ self . counter = 0 ; // Retry on next call
1089
+ }
1090
+ return rng. try_fill_bytes ( dest) ; // use JitterRng
1091
+ }
1083
1092
}
1084
1093
} else {
1085
- self . counter = ( self . counter + 1 ) % 8 ;
1094
+ self . counter -= 1 ;
1086
1095
return rng. try_fill_bytes ( dest) ; // use JitterRng
1087
1096
}
1088
1097
}
1089
1098
}
1090
1099
if let Some ( rng) = switch_rng {
1091
1100
self . rng = rng;
1092
- self . counter = 0 ;
1093
1101
}
1094
1102
Ok ( ( ) )
1095
1103
}
0 commit comments