Skip to content

Commit 7c4d8a2

Browse files
committed
Replace ReseedWithDefault with ReseedWithNew
1 parent 603bb37 commit 7c4d8a2

File tree

2 files changed

+39
-57
lines changed

2 files changed

+39
-57
lines changed

src/lib.rs

+21-39
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ use prng::Isaac64Rng as IsaacWordRng;
276276

277277
use distributions::{Range, IndependentSample};
278278
use distributions::range::SampleRange;
279+
use reseeding::{ReseedingRng, ReseedWithNew};
279280

280281
// public modules
281282
pub mod distributions;
@@ -933,58 +934,39 @@ pub fn weak_rng() -> XorShiftRng {
933934
XorShiftRng::new().unwrap()
934935
}
935936

936-
/// Controls how the thread-local RNG is reseeded.
937-
#[cfg(feature="std")]
938-
#[derive(Debug)]
939-
struct ThreadRngReseeder;
940-
941-
#[cfg(feature="std")]
942-
impl reseeding::Reseeder<StdRng> for ThreadRngReseeder {
943-
fn reseed(&mut self, rng: &mut StdRng) {
944-
match StdRng::new() {
945-
Ok(r) => *rng = r,
946-
Err(e) => panic!("No entropy available: {}", e),
947-
}
948-
}
949-
}
950-
#[cfg(feature="std")]
951-
const THREAD_RNG_RESEED_THRESHOLD: u64 = 32_768;
952-
#[cfg(feature="std")]
953-
type ThreadRngInner = reseeding::ReseedingRng<StdRng, ThreadRngReseeder>;
954937

955938
/// The thread-local RNG.
956939
#[cfg(feature="std")]
957940
#[derive(Clone, Debug)]
958941
pub struct ThreadRng {
959-
rng: Rc<RefCell<ThreadRngInner>>,
942+
rng: Rc<RefCell<ReseedingRng<StdRng, ReseedWithNew>>>,
960943
}
961944

962-
/// Retrieve the lazily-initialized thread-local random number
963-
/// generator, seeded by the system. Intended to be used in method
964-
/// chaining style, e.g. `thread_rng().gen::<i32>()`.
965-
///
966-
/// After generating a certain amount of randomness, the RNG will reseed itself
967-
/// from the operating system or, if the operating system RNG returns an error,
968-
/// a seed based on the current system time.
969-
///
970-
/// The internal RNG used is platform and architecture dependent, even
971-
/// if the operating system random number generator is rigged to give
972-
/// the same sequence always. If absolute consistency is required,
973-
/// explicitly select an RNG, e.g. `IsaacRng` or `Isaac64Rng`.
974945
#[cfg(feature="std")]
975-
pub fn thread_rng() -> ThreadRng {
976-
// used to make space in TLS for a random number generator
977-
thread_local!(static THREAD_RNG_KEY: Rc<RefCell<ThreadRngInner>> = {
946+
thread_local!(
947+
static THREAD_RNG_KEY: Rc<RefCell<ReseedingRng<StdRng, ReseedWithNew>>> = {
948+
const THREAD_RNG_RESEED_THRESHOLD: u64 = 32_768;
978949
let r = match StdRng::new() {
979950
Ok(r) => r,
980-
Err(e) => panic!("No entropy available: {}", e),
951+
Err(e) => panic!("could not initialize thread_rng: {:?}", e)
981952
};
982-
let rng = reseeding::ReseedingRng::new(r,
983-
THREAD_RNG_RESEED_THRESHOLD,
984-
ThreadRngReseeder);
953+
let rng = ReseedingRng::new(r,
954+
THREAD_RNG_RESEED_THRESHOLD,
955+
ReseedWithNew);
985956
Rc::new(RefCell::new(rng))
986-
});
957+
}
958+
);
987959

960+
/// Retrieve the lazily-initialized thread-local random number
961+
/// generator, seeded by the system. Intended to be used in method
962+
/// chaining style, e.g. `thread_rng().gen::<i32>()`.
963+
///
964+
/// The internal RNG used is the one defined by `StdRng`. After generating 32KiB
965+
/// of random bytes, the RNG will reseed itself from the operating system or, if
966+
/// the operating system RNG returns an error, the `JitterRng` entropy
967+
/// collector.
968+
#[cfg(feature="std")]
969+
pub fn thread_rng() -> ThreadRng {
988970
ThreadRng { rng: THREAD_RNG_KEY.with(|t| t.clone()) }
989971
}
990972

src/reseeding.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
//! A wrapper around another RNG that reseeds it after it
1212
//! generates a certain number of random bytes.
1313
14-
use core::default::Default;
15-
1614
use {Rng, Error};
15+
#[cfg(feature="std")]
16+
use NewSeeded;
1717

1818
/// A wrapper around any RNG which reseeds the underlying RNG after it
1919
/// has generated a certain number of random bytes.
@@ -47,7 +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-
self.reseeder.reseed(&mut self.rng);
50+
self.reseeder.reseed(&mut self.rng).unwrap();
5151
self.bytes_generated = 0;
5252
}
5353
}
@@ -85,30 +85,31 @@ impl<R: Rng, Rsdr: Reseeder<R>> Rng for ReseedingRng<R, Rsdr> {
8585
/// Note that implementations should support `Clone` only if reseeding is
8686
/// deterministic (no external entropy source). This is so that a `ReseedingRng`
8787
/// only supports `Clone` if fully deterministic.
88-
pub trait Reseeder<R> {
88+
pub trait Reseeder<R: ?Sized> {
8989
/// Reseed the given RNG.
90-
fn reseed(&mut self, rng: &mut R);
90+
///
91+
/// On error, this should just forward the source error; errors are handled
92+
/// by the caller.
93+
fn reseed(&mut self, rng: &mut R) -> Result<(), Error>;
9194
}
9295

93-
/// Reseed an RNG using a `Default` instance. This reseeds by
94-
/// replacing the RNG with the result of a `Default::default` call.
95-
#[derive(Clone, Copy, Debug)]
96-
pub struct ReseedWithDefault;
96+
/// Reseed an RNG using `NewSeeded` to replace the current instance.
97+
#[cfg(feature="std")]
98+
#[derive(Debug)]
99+
pub struct ReseedWithNew;
97100

98-
impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
99-
fn reseed(&mut self, rng: &mut R) {
100-
*rng = Default::default();
101+
#[cfg(feature="std")]
102+
impl<R: Rng + NewSeeded> Reseeder<R> for ReseedWithNew {
103+
fn reseed(&mut self, rng: &mut R) -> Result<(), Error> {
104+
R::new().map(|result| *rng = result)
101105
}
102106
}
103-
impl Default for ReseedWithDefault {
104-
fn default() -> ReseedWithDefault { ReseedWithDefault }
105-
}
106107

107108
#[cfg(test)]
108109
mod test {
109110
use {impls, le};
110111
use core::default::Default;
111-
use super::{ReseedingRng, ReseedWithDefault};
112+
use super::{ReseedingRng, ReseedWithNew};
112113
use {SeedableRng, Rng};
113114

114115
struct Counter {
@@ -142,11 +143,10 @@ mod test {
142143
Counter { i: seed_u32[0] }
143144
}
144145
}
145-
type MyRng = ReseedingRng<Counter, ReseedWithDefault>;
146146

147147
#[test]
148148
fn test_reseeding() {
149-
let mut rs = ReseedingRng::new(Counter {i:0}, 400, ReseedWithDefault);
149+
let mut rs = ReseedingRng::new(Counter {i:0}, 400, ReseedWithNew);
150150

151151
let mut i = 0;
152152
for _ in 0..1000 {

0 commit comments

Comments
 (0)