Skip to content

Commit a0f2e4b

Browse files
committed
Add log feature
1 parent 927ab7b commit a0f2e4b

File tree

6 files changed

+40
-17
lines changed

6 files changed

+40
-17
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ matrix:
2828
script:
2929
- cargo test
3030
- cargo test --tests --no-default-features
31-
- cargo test --features serde-1
31+
- cargo test --features serde-1,log
3232
- cargo test --tests --no-default-features --features=serde-1
3333
- cargo test --manifest-path rand-derive/Cargo.toml
3434

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ libc = { version = "0.2", optional = true }
3232
winapi = { version = "0.3", features = ["minwindef", "ntsecapi", "profileapi", "winnt"], optional = true }
3333

3434
[dependencies]
35+
log = { version = "0.4", optional = true }
36+
3537
serde = {version="1",optional=true}
3638
serde_derive = {version="1", optional=true}
3739

README.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ changes since the `0.3` series, but nevertheless contains some significant
3333
new code, including a new "external" entropy source (`JitterRng`) and `no_std`
3434
support.
3535

36-
Version `0.5` is in development and contains significant performance
37-
improvements for the ISAAC random number generators.
36+
Version `0.5` is in development and will contain significant breaking changes.
3837

3938
## Examples
4039

@@ -68,21 +67,22 @@ println!("i32: {}, u32: {}", rng.gen::<i32>(), rng.gen::<u32>())
6867
By default, `rand` is built with all stable features available. The following
6968
optional features are available:
7069

70+
- `alloc` can be used instead of `std` to provide `Vec` and `Box`
7171
- `i128_support` enables support for generating `u128` and `i128` values
72+
- `log` enables some logging via the `log` crate
7273
- `nightly` enables all unstable features (`i128_support`)
74+
- `serde-1` enables serialisation for some types, via Serde version 1
7375
- `std` enabled by default; by setting "default-features = false" `no_std`
7476
mode is activated; this removes features depending on `std` functionality:
75-
76-
- `OsRng` is entirely unavailable
77-
- `JitterRng` code is still present, but a nanosecond timer must be
78-
provided via `JitterRng::new_with_timer`
79-
- Since no external entropy is available, it is not possible to create
80-
generators with fresh seeds (user must provide entropy)
81-
- `thread_rng`, `weak_rng` and `random` are all disabled
82-
- exponential, normal and gamma type distributions are unavailable
83-
since `exp` and `log` functions are not provided in `core`
84-
- any code requiring `Vec` or `Box`
85-
- `alloc` can be used instead of `std` to provide `Vec` and `Box`
77+
- `OsRng` is entirely unavailable
78+
- `JitterRng` code is still present, but a nanosecond timer must be
79+
provided via `JitterRng::new_with_timer`
80+
- Since no external entropy is available, it is not possible to create
81+
generators with fresh seeds (user must provide entropy)
82+
- `thread_rng`, `weak_rng` and `random` are all disabled
83+
- exponential, normal and gamma type distributions are unavailable
84+
since `exp` and `log` functions are not provided in `core`
85+
- any code requiring `Vec` or `Box`
8686

8787
## Testing
8888

src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,16 @@
249249

250250
#[cfg(feature="std")] extern crate std as core;
251251
#[cfg(all(feature = "alloc", not(feature="std")))] extern crate alloc;
252+
252253
#[cfg(test)] #[cfg(feature="serde-1")] extern crate bincode;
253254
#[cfg(feature="serde-1")] extern crate serde;
254255
#[cfg(feature="serde-1")] #[macro_use] extern crate serde_derive;
255256

257+
#[cfg(feature = "log")] #[macro_use] extern crate log;
258+
#[cfg(not(feature = "log"))] macro_rules! trace { ($($x:tt)*) => () }
259+
#[cfg(all(feature="std", not(feature = "log")))] macro_rules! warn { ($($x:tt)*) => () }
260+
261+
256262
use core::{marker, mem};
257263
#[cfg(feature="std")] use std::cell::RefCell;
258264
#[cfg(feature="std")] use std::rc::Rc;
@@ -846,9 +852,11 @@ impl<R: SeedableRng> NewRng for R {
846852
T::from_rng(&mut r)
847853
}
848854

855+
trace!("Seeding new RNG");
849856
new_os().or_else(|e1| {
857+
warn!("OsRng failed [falling back to JitterRng]: {:?}", e1);
850858
new_jitter().map_err(|_e2| {
851-
// TODO: log
859+
warn!("JitterRng failed: {:?}", _e2);
852860
// TODO: can we somehow return both error sources?
853861
Error::with_cause(
854862
ErrorKind::Unavailable,

src/os.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,35 @@ impl Rng for OsRng {
6969
const MAX_WAIT: u32 = (10 * 1000) / WAIT_DUR_MS; // max 10s
7070
const TRANSIENT_STEP: u32 = MAX_WAIT / 8;
7171
let mut err_count = 0;
72+
let mut log_err = 0; // log when err_count >= log_err
7273

7374
loop {
7475
if let Err(e) = self.try_fill_bytes(dest) {
75-
// TODO: add logging to explain why we wait and the full cause
76+
if log_err == 0 {
77+
warn!("OsRng failed: {:?}", e);
78+
}
79+
7680
if e.kind().should_retry() {
7781
if err_count > MAX_WAIT {
7882
panic!("Too many RNG errors or timeout; last error: {}", e.msg());
7983
}
8084

8185
if e.kind().should_wait() {
86+
err_count += 1;
87+
if err_count >= log_err {
88+
log_err += TRANSIENT_STEP;
89+
warn!("OsRng: waiting and retrying ...");
90+
}
8291
#[cfg(feature="std")]{
8392
let dur = ::std::time::Duration::from_millis(WAIT_DUR_MS as u64);
8493
::std::thread::sleep(dur);
8594
}
86-
err_count += 1;
8795
} else {
8896
err_count += TRANSIENT_STEP;
97+
if err_count >= log_err {
98+
log_err += TRANSIENT_STEP;
99+
warn!("OsRng: retrying ...");
100+
}
89101
}
90102

91103
continue;

src/reseeding.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ impl<R: Rng, Rsdr: Reseeder<R>> ReseedingRng<R, Rsdr> {
4747
/// generated exceed the threshold.
4848
pub fn reseed_if_necessary(&mut self) {
4949
if self.bytes_generated >= self.generation_threshold {
50+
trace!("Reseeding RNG");
5051
self.reseeder.reseed(&mut self.rng).unwrap();
5152
self.bytes_generated = 0;
5253
}

0 commit comments

Comments
 (0)