@@ -319,6 +319,79 @@ impl<T> Arc<T> {
319
319
Self :: from_inner ( Box :: leak ( x) . into ( ) )
320
320
}
321
321
322
+ /// Constructs a new `Arc<T>` using a weak reference to itself. Attempting
323
+ /// to upgrade the weak reference before this function returns will result
324
+ /// in a `None` value. However, the weak reference may be cloned freely and
325
+ /// stored for use at a later time.
326
+ ///
327
+ /// # Examples
328
+ /// ```
329
+ /// #![feature(arc_new_cyclic)]
330
+ /// #![allow(dead_code)]
331
+ ///
332
+ /// use std::sync::{Arc, Weak};
333
+ ///
334
+ /// struct Foo {
335
+ /// me: Weak<Foo>,
336
+ /// }
337
+ ///
338
+ /// let foo = Arc::new_cyclic(|me| Foo {
339
+ /// me: me.clone(),
340
+ /// });
341
+ /// ```
342
+ #[ inline]
343
+ #[ unstable( feature = "arc_new_cyclic" , issue = "75861" ) ]
344
+ pub fn new_cyclic ( data_fn : impl FnOnce ( & Weak < T > ) -> T ) -> Arc < T > {
345
+ // Construct the inner in the "uninitialized" state with a single
346
+ // weak reference.
347
+ let uninit_ptr: NonNull < _ > = Box :: leak ( box ArcInner {
348
+ strong : atomic:: AtomicUsize :: new ( 0 ) ,
349
+ weak : atomic:: AtomicUsize :: new ( 1 ) ,
350
+ data : mem:: MaybeUninit :: < T > :: uninit ( ) ,
351
+ } )
352
+ . into ( ) ;
353
+ let init_ptr: NonNull < ArcInner < T > > = uninit_ptr. cast ( ) ;
354
+
355
+ let weak = Weak { ptr : init_ptr } ;
356
+
357
+ // It's important we don't give up ownership of the weak pointer, or
358
+ // else the memory might be freed by the time `data_fn` returns. If
359
+ // we really wanted to pass ownership, we could create an additional
360
+ // weak pointer for ourselves, but this would result in additional
361
+ // updates to the weak reference count which might not be necessary
362
+ // otherwise.
363
+ let data = data_fn ( & weak) ;
364
+
365
+ // Now we can properly initialize the inner value and turn our weak
366
+ // reference into a strong reference.
367
+ unsafe {
368
+ let inner = init_ptr. as_ptr ( ) ;
369
+ ptr:: write ( & raw mut ( * inner) . data , data) ;
370
+
371
+ // The above write to the data field must be visible to any threads which
372
+ // observe a non-zero strong count. Therefore we need at least "Release" ordering
373
+ // in order to synchronize with the `compare_exchange_weak` in `Weak::upgrade`.
374
+ //
375
+ // "Acquire" ordering is not required. When considering the possible behaviours
376
+ // of `data_fn` we only need to look at what it could do with a reference to a
377
+ // non-upgradeable `Weak`:
378
+ // - It can *clone* the `Weak`, increasing the weak reference count.
379
+ // - It can drop those clones, decreasing the weak reference count (but never to zero).
380
+ //
381
+ // These side effects do not impact us in any way, and no other side effects are
382
+ // possible with safe code alone.
383
+ let prev_value = ( * inner) . strong . fetch_add ( 1 , Release ) ;
384
+ debug_assert_eq ! ( prev_value, 0 , "No prior strong references should exist" ) ;
385
+ }
386
+
387
+ let strong = Arc :: from_inner ( init_ptr) ;
388
+
389
+ // Strong references should collectively own a shared weak reference,
390
+ // so don't run the destructor for our old weak reference.
391
+ mem:: forget ( weak) ;
392
+ strong
393
+ }
394
+
322
395
/// Constructs a new `Arc` with uninitialized contents.
323
396
///
324
397
/// # Examples
@@ -1604,7 +1677,8 @@ impl<T: ?Sized> Weak<T> {
1604
1677
#[ stable( feature = "arc_weak" , since = "1.4.0" ) ]
1605
1678
pub fn upgrade ( & self ) -> Option < Arc < T > > {
1606
1679
// We use a CAS loop to increment the strong count instead of a
1607
- // fetch_add because once the count hits 0 it must never be above 0.
1680
+ // fetch_add as this function should never take the reference count
1681
+ // from zero to one.
1608
1682
let inner = self . inner ( ) ?;
1609
1683
1610
1684
// Relaxed load because any write of 0 that we can observe
@@ -1623,8 +1697,11 @@ impl<T: ?Sized> Weak<T> {
1623
1697
abort ( ) ;
1624
1698
}
1625
1699
1626
- // Relaxed is valid for the same reason it is on Arc's Clone impl
1627
- match inner. strong . compare_exchange_weak ( n, n + 1 , Relaxed , Relaxed ) {
1700
+ // Relaxed is fine for the failure case because we don't have any expectations about the new state.
1701
+ // Acquire is necessary for the success case to synchronise with `Arc::new_cyclic`, when the inner
1702
+ // value can be initialized after `Weak` references have already been created. In that case, we
1703
+ // expect to observe the fully initialized value.
1704
+ match inner. strong . compare_exchange_weak ( n, n + 1 , Acquire , Relaxed ) {
1628
1705
Ok ( _) => return Some ( Arc :: from_inner ( self . ptr ) ) , // null checked above
1629
1706
Err ( old) => n = old,
1630
1707
}
0 commit comments