@@ -88,23 +88,30 @@ Mutable statics are still very useful, however. They can be used with C
88
88
libraries and can also be bound from C libraries in an ` extern ` block.
89
89
90
90
``` rust
91
- # fn atomic_add (_ : & mut u32 , _ : u32 ) -> u32 { 2 }
91
+ # fn atomic_add (_ : * mut u32 , _ : u32 ) -> u32 { 2 }
92
92
93
93
static mut LEVELS : u32 = 0 ;
94
94
95
95
// This violates the idea of no shared state, and this doesn't internally
96
96
// protect against races, so this function is `unsafe`
97
- unsafe fn bump_levels_unsafe1 () -> u32 {
98
- let ret = LEVELS ;
99
- LEVELS += 1 ;
100
- return ret ;
97
+ unsafe fn bump_levels_unsafe () -> u32 {
98
+ unsafe {
99
+ let ret = LEVELS ;
100
+ LEVELS += 1 ;
101
+ return ret ;
102
+ }
101
103
}
102
104
103
- // Assuming that we have an atomic_add function which returns the old value,
104
- // this function is "safe" but the meaning of the return value may not be what
105
- // callers expect, so it's still marked as `unsafe`
106
- unsafe fn bump_levels_unsafe2 () -> u32 {
107
- return atomic_add (& mut LEVELS , 1 );
105
+ // As an alternative to `bump_levels_unsafe`, this function is safe, assuming
106
+ // that we have an atomic_add function which returns the old value. This
107
+ // function is safe only if no other code accesses the static in a non-atomic
108
+ // fashion. If such accesses are possible (such as in `bump_levels_unsafe`),
109
+ // then this would need to be `unsafe` to indicate to the caller that they
110
+ // must still guard against concurrent access.
111
+ fn bump_levels_safe () -> u32 {
112
+ unsafe {
113
+ return atomic_add (std :: ptr :: addr_of_mut! (LEVELS ), 1 );
114
+ }
108
115
}
109
116
```
110
117
0 commit comments