@@ -27,7 +27,7 @@ use vec;
27
27
///
28
28
/// Enforces no shared-memory safety.
29
29
pub struct UnsafeArc < T > {
30
- data : * mut libc :: c_void ,
30
+ data : * mut ArcData < T > ,
31
31
}
32
32
33
33
struct ArcData < T > {
@@ -41,7 +41,7 @@ struct ArcData<T> {
41
41
data : Option < T > ,
42
42
}
43
43
44
- unsafe fn new_inner < T : Send > ( data : T , refcount : uint ) -> * mut libc :: c_void {
44
+ unsafe fn new_inner < T : Send > ( data : T , refcount : uint ) -> * mut ArcData < T > {
45
45
let data = ~ArcData { count : AtomicUint :: new ( refcount) ,
46
46
unwrapper : AtomicOption :: empty ( ) ,
47
47
data : Some ( data) } ;
@@ -79,12 +79,11 @@ impl<T: Send> UnsafeArc<T> {
79
79
~[ ] // The "num_handles - 1" trick (below) fails in the 0 case.
80
80
} else {
81
81
unsafe {
82
- let mut data: ~ArcData < T > = cast:: transmute ( self . data ) ;
83
82
// Minus one because we are recycling the given handle's refcount.
84
- let old_count = data. count . fetch_add ( num_handles - 1 , Acquire ) ;
85
- // let old_count = data.count.fetch_add(num_handles, Acquire);
83
+ let old_count = ( * self . data ) . count . fetch_add ( num_handles - 1 , Acquire ) ;
84
+ // let old_count = (*self. data) .count.fetch_add(num_handles, Acquire);
86
85
assert ! ( old_count >= 1 ) ;
87
- let ptr = cast :: transmute ( data) ;
86
+ let ptr = self . data ;
88
87
cast:: forget ( self ) ; // Don't run the destructor on this handle.
89
88
vec:: from_fn ( num_handles, |_| UnsafeArc { data : ptr } )
90
89
}
@@ -94,21 +93,17 @@ impl<T: Send> UnsafeArc<T> {
94
93
#[ inline]
95
94
pub fn get ( & self ) -> * mut T {
96
95
unsafe {
97
- let mut data: ~ArcData < T > = cast:: transmute ( self . data ) ;
98
- assert ! ( data. count. load( Relaxed ) > 0 ) ;
99
- let r: * mut T = data. data . get_mut_ref ( ) ;
100
- cast:: forget ( data) ;
96
+ assert ! ( ( * self . data) . count. load( Relaxed ) > 0 ) ;
97
+ let r: * mut T = ( * self . data ) . data . get_mut_ref ( ) ;
101
98
return r;
102
99
}
103
100
}
104
101
105
102
#[ inline]
106
103
pub fn get_immut ( & self ) -> * T {
107
104
unsafe {
108
- let data: ~ArcData < T > = cast:: transmute ( self . data ) ;
109
- assert ! ( data. count. load( Relaxed ) > 0 ) ;
110
- let r: * T = data. data . get_ref ( ) ;
111
- cast:: forget ( data) ;
105
+ assert ! ( ( * self . data) . count. load( Relaxed ) > 0 ) ;
106
+ let r: * T = ( * self . data ) . data . get_ref ( ) ;
112
107
return r;
113
108
}
114
109
}
@@ -122,6 +117,7 @@ impl<T: Send> UnsafeArc<T> {
122
117
do task:: unkillable {
123
118
unsafe {
124
119
let mut this = this. take ( ) ;
120
+ // The ~ dtor needs to run if this code succeeds.
125
121
let mut data: ~ArcData < T > = cast:: transmute ( this. data ) ;
126
122
// Set up the unwrap protocol.
127
123
let ( p1, c1) = comm:: oneshot ( ) ; // ()
@@ -186,6 +182,7 @@ impl<T: Send> UnsafeArc<T> {
186
182
pub fn try_unwrap ( self ) -> Either < UnsafeArc < T > , T > {
187
183
unsafe {
188
184
let mut this = self ; // FIXME(#4330) mutable self
185
+ // The ~ dtor needs to run if this code succeeds.
189
186
let mut data: ~ArcData < T > = cast:: transmute ( this. data ) ;
190
187
// This can of course race with anybody else who has a handle, but in
191
188
// such a case, the returned count will always be at least 2. If we
@@ -212,11 +209,9 @@ impl<T: Send> UnsafeArc<T> {
212
209
impl < T : Send > Clone for UnsafeArc < T > {
213
210
fn clone ( & self ) -> UnsafeArc < T > {
214
211
unsafe {
215
- let mut data: ~ArcData < T > = cast:: transmute ( self . data ) ;
216
212
// This barrier might be unnecessary, but I'm not sure...
217
- let old_count = data. count . fetch_add ( 1 , Acquire ) ;
213
+ let old_count = ( * self . data ) . count . fetch_add ( 1 , Acquire ) ;
218
214
assert ! ( old_count >= 1 ) ;
219
- cast:: forget ( data) ;
220
215
return UnsafeArc { data : self . data } ;
221
216
}
222
217
}
0 commit comments