@@ -16,36 +16,48 @@ impl ThreadLocalEntropy {
16
16
/// allow mutable access without a cell, so using `UnsafeCell` to bypass overheads associated with
17
17
/// `RefCell`. There's no direct access to the pointer or mutable reference, so we control how long it
18
18
/// lives and can ensure no multiple mutable references exist.
19
+ ///
20
+ /// # Safety
21
+ ///
22
+ /// Caller must ensure only one `mut` reference exists at a time.
19
23
#[ inline]
20
- fn get_rng ( & ' _ mut self ) -> & ' _ mut ChaCha12Rng {
24
+ unsafe fn get_rng ( & ' _ mut self ) -> & ' _ mut ChaCha12Rng {
21
25
// Obtain pointer to thread local instance of PRNG which with Rc, should be !Send & !Sync as well
22
26
// as 'static.
23
27
let rng = SOURCE . with ( |source| source. get ( ) ) ;
24
28
25
- // SAFETY: We must make sure to stop using `rng` before anyone else creates another
26
- // mutable reference
27
- unsafe { & mut * rng }
29
+ & mut * rng
28
30
}
29
31
}
30
32
31
33
impl RngCore for ThreadLocalEntropy {
32
34
#[ inline]
33
35
fn next_u32 ( & mut self ) -> u32 {
34
- self . get_rng ( ) . next_u32 ( )
36
+ // SAFETY: We must ensure to drop the `&mut rng` ref before creating another
37
+ // mutable reference
38
+ unsafe { self . get_rng ( ) . next_u32 ( ) }
35
39
}
36
40
37
41
#[ inline]
38
42
fn next_u64 ( & mut self ) -> u64 {
39
- self . get_rng ( ) . next_u64 ( )
43
+ // SAFETY: We must ensure to drop the `&mut rng` ref before creating another
44
+ // mutable reference
45
+ unsafe { self . get_rng ( ) . next_u64 ( ) }
40
46
}
41
47
42
48
#[ inline]
43
49
fn fill_bytes ( & mut self , dest : & mut [ u8 ] ) {
44
- self . get_rng ( ) . fill_bytes ( dest) ;
50
+ // SAFETY: We must ensure to drop the `&mut rng` ref before creating another
51
+ // mutable reference
52
+ unsafe {
53
+ self . get_rng ( ) . fill_bytes ( dest) ;
54
+ }
45
55
}
46
56
47
57
#[ inline]
48
58
fn try_fill_bytes ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , rand_core:: Error > {
49
- self . get_rng ( ) . try_fill_bytes ( dest)
59
+ // SAFETY: We must ensure to drop the `&mut rng` ref before creating another
60
+ // mutable reference
61
+ unsafe { self . get_rng ( ) . try_fill_bytes ( dest) }
50
62
}
51
63
}
0 commit comments