@@ -270,6 +270,68 @@ impl<T> Arc<T> {
270
270
Ok ( elem)
271
271
}
272
272
}
273
+
274
+ /// Consumes the `Arc`, returning the wrapped pointer.
275
+ ///
276
+ /// To avoid a memory leak the pointer must be converted back to an `Arc` using
277
+ /// [`Arc::from_raw`][from_raw].
278
+ ///
279
+ /// [from_raw]: struct.Arc.html#method.from_raw
280
+ ///
281
+ /// # Examples
282
+ ///
283
+ /// ```
284
+ /// #![feature(rc_raw)]
285
+ ///
286
+ /// use std::sync::Arc;
287
+ ///
288
+ /// let x = Arc::new(10);
289
+ /// let x_ptr = Arc::into_raw(x);
290
+ /// assert_eq!(unsafe { *x_ptr }, 10);
291
+ /// ```
292
+ #[ unstable( feature = "rc_raw" , issue = "37197" ) ]
293
+ pub fn into_raw ( this : Self ) -> * mut T {
294
+ let ptr = unsafe { & mut ( * * this. ptr ) . data as * mut _ } ;
295
+ mem:: forget ( this) ;
296
+ ptr
297
+ }
298
+
299
+ /// Constructs an `Arc` from a raw pointer.
300
+ ///
301
+ /// The raw pointer must have been previously returned by a call to a
302
+ /// [`Arc::into_raw`][into_raw].
303
+ ///
304
+ /// This function is unsafe because improper use may lead to memory problems. For example, a
305
+ /// double-free may occur if the function is called twice on the same raw pointer.
306
+ ///
307
+ /// [into_raw]: struct.Arc.html#method.into_raw
308
+ ///
309
+ /// # Examples
310
+ ///
311
+ /// ```
312
+ /// #![feature(rc_raw)]
313
+ ///
314
+ /// use std::sync::Arc;
315
+ ///
316
+ /// let x = Arc::new(10);
317
+ /// let x_ptr = Arc::into_raw(x);
318
+ ///
319
+ /// unsafe {
320
+ /// // Convert back to an `Arc` to prevent leak.
321
+ /// let x = Arc::from_raw(x_ptr);
322
+ /// assert_eq!(*x, 10);
323
+ ///
324
+ /// // Further calls to `Arc::from_raw(x_ptr)` would be memory unsafe.
325
+ /// }
326
+ ///
327
+ /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
328
+ /// ```
329
+ #[ unstable( feature = "rc_raw" , issue = "37197" ) ]
330
+ pub unsafe fn from_raw ( ptr : * mut T ) -> Self {
331
+ // To find the corresponding pointer to the `ArcInner` we need to subtract the offset of the
332
+ // `data` field from the pointer.
333
+ Arc { ptr : Shared :: new ( ( ptr as * mut u8 ) . offset ( -offset_of ! ( ArcInner <T >, data) ) as * mut _ ) }
334
+ }
273
335
}
274
336
275
337
impl < T : ?Sized > Arc < T > {
@@ -1179,6 +1241,23 @@ mod tests {
1179
1241
assert_eq ! ( Arc :: try_unwrap( x) , Ok ( 5 ) ) ;
1180
1242
}
1181
1243
1244
+ #[ test]
1245
+ fn into_from_raw ( ) {
1246
+ let x = Arc :: new ( box "hello" ) ;
1247
+ let y = x. clone ( ) ;
1248
+
1249
+ let x_ptr = Arc :: into_raw ( x) ;
1250
+ drop ( y) ;
1251
+ unsafe {
1252
+ assert_eq ! ( * * x_ptr, "hello" ) ;
1253
+
1254
+ let x = Arc :: from_raw ( x_ptr) ;
1255
+ assert_eq ! ( * * x, "hello" ) ;
1256
+
1257
+ assert_eq ! ( Arc :: try_unwrap( x) . map( |x| * x) , Ok ( "hello" ) ) ;
1258
+ }
1259
+ }
1260
+
1182
1261
#[ test]
1183
1262
fn test_cowarc_clone_make_mut ( ) {
1184
1263
let mut cow0 = Arc :: new ( 75 ) ;
0 commit comments