Skip to content

Commit 764f31c

Browse files
committed
Inline fill_via_try_fill implicit error handling, and revise
1 parent fb3a2c7 commit 764f31c

File tree

2 files changed

+32
-37
lines changed

2 files changed

+32
-37
lines changed

src/impls.rs

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -167,40 +167,4 @@ pub fn next_u64_via_fill<R: Rng+?Sized>(rng: &mut R) -> u64 {
167167
impl_uint_from_fill!(rng, u64, 8)
168168
}
169169

170-
/// Implement `fill` via `try_fill` with implicit error handling.
171-
pub fn fill_via_try_fill<R: Rng+?Sized>(rng: &mut R, dest: &mut [u8]) {
172-
const WAIT_DUR_MS: u32 = 100;
173-
const MAX_WAIT: u32 = (1 * 60 * 1000) / WAIT_DUR_MS;
174-
const TRANSIENT_STEP: u32 = MAX_WAIT / 8;
175-
let mut err_count = 0;
176-
177-
loop {
178-
if let Err(e) = rng.try_fill(dest) {
179-
if e.kind().should_retry() {
180-
if err_count > MAX_WAIT {
181-
// TODO: log details & cause?
182-
panic!("Too many RNG errors or timeout; last error: {}", e.msg());
183-
}
184-
185-
if e.kind().should_wait() {
186-
#[cfg(feature="std")]{
187-
let dur = ::std::time::Duration::from_millis(WAIT_DUR_MS as u64);
188-
::std::thread::sleep(dur);
189-
}
190-
err_count += 1;
191-
} else {
192-
err_count += TRANSIENT_STEP;
193-
}
194-
195-
continue;
196-
}
197-
198-
// TODO: log details & cause?
199-
panic!("Fatal RNG error: {}", e.msg());
200-
}
201-
202-
break;
203-
}
204-
}
205-
206170
// TODO: implement tests for the above

src/os.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,38 @@ impl Rng for OsRng {
6161
}
6262

6363
fn fill(&mut self, dest: &mut [u8]) {
64-
impls::fill_via_try_fill(self, dest)
64+
// We cannot return Err(..), so we try to handle before panicking.
65+
const WAIT_DUR_MS: u32 = 100; // retry every 100ms
66+
const MAX_WAIT: u32 = (10 * 1000) / WAIT_DUR_MS; // max 10s
67+
const TRANSIENT_STEP: u32 = MAX_WAIT / 8;
68+
let mut err_count = 0;
69+
70+
loop {
71+
if let Err(e) = self.try_fill(dest) {
72+
// TODO: add logging to explain why we wait and the full cause
73+
if e.kind().should_retry() {
74+
if err_count > MAX_WAIT {
75+
panic!("Too many RNG errors or timeout; last error: {}", e.msg());
76+
}
77+
78+
if e.kind().should_wait() {
79+
#[cfg(feature="std")]{
80+
let dur = ::std::time::Duration::from_millis(WAIT_DUR_MS as u64);
81+
::std::thread::sleep(dur);
82+
}
83+
err_count += 1;
84+
} else {
85+
err_count += TRANSIENT_STEP;
86+
}
87+
88+
continue;
89+
}
90+
91+
panic!("Fatal RNG error: {}", e.msg());
92+
}
93+
94+
break;
95+
}
6596
}
6697

6798
fn try_fill(&mut self, v: &mut [u8]) -> Result<(), Error> {

0 commit comments

Comments
 (0)