@@ -24,8 +24,7 @@ use core::mem;
24
24
use core:: ops:: { Drop , Deref } ;
25
25
use core:: option:: Option ;
26
26
use core:: option:: Option :: { Some , None } ;
27
- use core:: ptr:: RawPtr ;
28
- use core:: ptr;
27
+ use core:: ptr:: { mod, NonZero , RawPtr } ;
29
28
use heap:: deallocate;
30
29
31
30
/// An atomically reference counted wrapper for shared state.
@@ -59,7 +58,7 @@ use heap::deallocate;
59
58
pub struct Arc < T > {
60
59
// FIXME #12808: strange name to try to avoid interfering with
61
60
// field accesses of the contained type via Deref
62
- _ptr : * mut ArcInner < T > ,
61
+ _ptr : NonZero < * mut ArcInner < T > > ,
63
62
}
64
63
65
64
/// A weak pointer to an `Arc`.
@@ -71,7 +70,7 @@ pub struct Arc<T> {
71
70
pub struct Weak < T > {
72
71
// FIXME #12808: strange name to try to avoid interfering with
73
72
// field accesses of the contained type via Deref
74
- _ptr : * mut ArcInner < T > ,
73
+ _ptr : NonZero < * mut ArcInner < T > > ,
75
74
}
76
75
77
76
struct ArcInner < T > {
@@ -92,7 +91,7 @@ impl<T: Sync + Send> Arc<T> {
92
91
weak : atomic:: AtomicUint :: new ( 1 ) ,
93
92
data : data,
94
93
} ;
95
- Arc { _ptr : unsafe { mem:: transmute ( x) } }
94
+ Arc { _ptr : NonZero ( unsafe { mem:: transmute ( x) } ) }
96
95
}
97
96
98
97
/// Downgrades a strong pointer to a weak pointer.
@@ -116,7 +115,8 @@ impl<T> Arc<T> {
116
115
// `ArcInner` structure itself is `Sync` because the inner data is
117
116
// `Sync` as well, so we're ok loaning out an immutable pointer to
118
117
// these contents.
119
- unsafe { & * self . _ptr }
118
+ let NonZero ( ptr) = self . _ptr ;
119
+ unsafe { & * ptr }
120
120
}
121
121
}
122
122
@@ -184,7 +184,8 @@ impl<T: Send + Sync + Clone> Arc<T> {
184
184
// reference count is guaranteed to be 1 at this point, and we required
185
185
// the Arc itself to be `mut`, so we're returning the only possible
186
186
// reference to the inner data.
187
- let inner = unsafe { & mut * self . _ptr } ;
187
+ let NonZero ( ptr) = self . _ptr ;
188
+ let inner = unsafe { & mut * ptr } ;
188
189
& mut inner. data
189
190
}
190
191
}
@@ -193,10 +194,11 @@ impl<T: Send + Sync + Clone> Arc<T> {
193
194
#[ experimental = "waiting on stability of Drop" ]
194
195
impl < T : Sync + Send > Drop for Arc < T > {
195
196
fn drop ( & mut self ) {
197
+ let NonZero ( ptr) = self . _ptr ;
196
198
// This structure has #[unsafe_no_drop_flag], so this drop glue may run
197
199
// more than once (but it is guaranteed to be zeroed after the first if
198
200
// it's run more than once)
199
- if self . _ptr . is_null ( ) { return }
201
+ if ptr . is_null ( ) { return }
200
202
201
203
// Because `fetch_sub` is already atomic, we do not need to synchronize
202
204
// with other threads unless we are going to delete the object. This
@@ -228,7 +230,7 @@ impl<T: Sync + Send> Drop for Arc<T> {
228
230
229
231
if self . inner ( ) . weak . fetch_sub ( 1 , atomic:: Release ) == 1 {
230
232
atomic:: fence ( atomic:: Acquire ) ;
231
- unsafe { deallocate ( self . _ptr as * mut u8 , size_of :: < ArcInner < T > > ( ) ,
233
+ unsafe { deallocate ( ptr as * mut u8 , size_of :: < ArcInner < T > > ( ) ,
232
234
min_align_of :: < ArcInner < T > > ( ) ) }
233
235
}
234
236
}
@@ -256,7 +258,8 @@ impl<T: Sync + Send> Weak<T> {
256
258
#[ inline]
257
259
fn inner ( & self ) -> & ArcInner < T > {
258
260
// See comments above for why this is "safe"
259
- unsafe { & * self . _ptr }
261
+ let NonZero ( ptr) = self . _ptr ;
262
+ unsafe { & * ptr }
260
263
}
261
264
}
262
265
@@ -274,15 +277,17 @@ impl<T: Sync + Send> Clone for Weak<T> {
274
277
#[ experimental = "Weak pointers may not belong in this module." ]
275
278
impl < T : Sync + Send > Drop for Weak < T > {
276
279
fn drop ( & mut self ) {
280
+ let NonZero ( ptr) = self . _ptr ;
281
+
277
282
// see comments above for why this check is here
278
- if self . _ptr . is_null ( ) { return }
283
+ if ptr . is_null ( ) { return }
279
284
280
285
// If we find out that we were the last weak pointer, then its time to
281
286
// deallocate the data entirely. See the discussion in Arc::drop() about
282
287
// the memory orderings
283
288
if self . inner ( ) . weak . fetch_sub ( 1 , atomic:: Release ) == 1 {
284
289
atomic:: fence ( atomic:: Acquire ) ;
285
- unsafe { deallocate ( self . _ptr as * mut u8 , size_of :: < ArcInner < T > > ( ) ,
290
+ unsafe { deallocate ( ptr as * mut u8 , size_of :: < ArcInner < T > > ( ) ,
286
291
min_align_of :: < ArcInner < T > > ( ) ) }
287
292
}
288
293
}
0 commit comments