9
9
//! Thread-local random number generator
10
10
11
11
use std:: cell:: UnsafeCell ;
12
+ use std:: ptr:: NonNull ;
12
13
13
14
use { RngCore , CryptoRng , SeedableRng , Error } ;
14
15
use rngs:: adapter:: ReseedingRng ;
@@ -28,9 +29,6 @@ use super::std::Core;
28
29
// completely under our control. We just have to ensure none of them use
29
30
// `ThreadRng` internally, which is nonsensical anyway. We should also never run
30
31
// `ThreadRng` in destructors of its implementation, which is also nonsensical.
31
- //
32
- // The additional `Rc` is not strictly neccesary, and could be removed. For now
33
- // it ensures `ThreadRng` stays `!Send` and `!Sync`, and implements `Clone`.
34
32
35
33
36
34
// Number of generated bytes after which to reseed `ThreadRng`.
@@ -52,13 +50,13 @@ const THREAD_RNG_RESEED_THRESHOLD: u64 = 1024 * 64;
52
50
/// Note that the reseeding is done as an extra precaution against side-channel
53
51
/// attacks and mis-use (e.g. if somehow weak entropy were supplied initially).
54
52
/// The PRNG algorithms used are assumed to be secure.
55
- ///
53
+ ///
56
54
/// [`ReseedingRng`]: crate::rngs::adapter::ReseedingRng
57
55
/// [`StdRng`]: crate::rngs::StdRng
58
56
#[ derive( Copy , Clone , Debug ) ]
59
57
pub struct ThreadRng {
60
- // use of raw pointer implies type is neither Send nor Sync
61
- rng : * mut ReseedingRng < Core , OsRng > ,
58
+ // inner raw pointer implies type is neither Send nor Sync
59
+ rng : NonNull < ReseedingRng < Core , OsRng > > ,
62
60
}
63
61
64
62
thread_local ! (
@@ -80,7 +78,9 @@ thread_local!(
80
78
///
81
79
/// For more information see [`ThreadRng`].
82
80
pub fn thread_rng ( ) -> ThreadRng {
83
- ThreadRng { rng : THREAD_RNG_KEY . with ( |t| t. get ( ) ) }
81
+ let raw = THREAD_RNG_KEY . with ( |t| t. get ( ) ) ;
82
+ let nn = NonNull :: new ( raw) . unwrap ( ) ;
83
+ ThreadRng { rng : nn }
84
84
}
85
85
86
86
impl Default for ThreadRng {
@@ -92,20 +92,20 @@ impl Default for ThreadRng {
92
92
impl RngCore for ThreadRng {
93
93
#[ inline( always) ]
94
94
fn next_u32 ( & mut self ) -> u32 {
95
- unsafe { ( * self . rng ) . next_u32 ( ) }
95
+ unsafe { self . rng . as_mut ( ) . next_u32 ( ) }
96
96
}
97
97
98
98
#[ inline( always) ]
99
99
fn next_u64 ( & mut self ) -> u64 {
100
- unsafe { ( * self . rng ) . next_u64 ( ) }
100
+ unsafe { self . rng . as_mut ( ) . next_u64 ( ) }
101
101
}
102
102
103
103
fn fill_bytes ( & mut self , dest : & mut [ u8 ] ) {
104
- unsafe { ( * self . rng ) . fill_bytes ( dest) }
104
+ unsafe { self . rng . as_mut ( ) . fill_bytes ( dest) }
105
105
}
106
106
107
107
fn try_fill_bytes ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , Error > {
108
- unsafe { ( * self . rng ) . try_fill_bytes ( dest) }
108
+ unsafe { self . rng . as_mut ( ) . try_fill_bytes ( dest) }
109
109
}
110
110
}
111
111
0 commit comments