@@ -12,7 +12,7 @@ use core::sync::atomic;
1212use core:: sync:: atomic:: Ordering :: { Acquire , Relaxed , Release , SeqCst } ;
1313use core:: borrow;
1414use core:: fmt;
15- use core:: cmp:: { self , Ordering } ;
15+ use core:: cmp:: Ordering ;
1616use core:: iter;
1717use core:: intrinsics:: abort;
1818use core:: mem:: { self , align_of, align_of_val, size_of_val} ;
@@ -1508,9 +1508,8 @@ impl<T: ?Sized> Weak<T> {
15081508 /// Gets an approximation of the number of `Weak` pointers pointing to this
15091509 /// allocation.
15101510 ///
1511- /// If `self` was created using [`Weak::new`], this will return 0. If not,
1512- /// the returned value is at least 1, since `self` still points to the
1513- /// allocation.
1511+ /// If `self` was created using [`Weak::new`], or if there are no remaining
1512+ /// strong pointers, this will return 0.
15141513 ///
15151514 /// # Accuracy
15161515 ///
@@ -1520,30 +1519,21 @@ impl<T: ?Sized> Weak<T> {
15201519 ///
15211520 /// [`Weak::new`]: #method.new
15221521 #[ stable( feature = "weak_counts" , since = "1.40.0" ) ]
1523- pub fn weak_count ( & self ) -> Option < usize > {
1524- // Due to the implicit weak pointer added when any strong pointers are
1525- // around, we cannot implement `weak_count` correctly since it
1526- // necessarily requires accessing the strong count and weak count in an
1527- // unsynchronized fashion. So this version is a bit racy.
1522+ pub fn weak_count ( & self ) -> usize {
15281523 self . inner ( ) . map ( |inner| {
1529- let strong = inner. strong . load ( SeqCst ) ;
15301524 let weak = inner. weak . load ( SeqCst ) ;
1525+ let strong = inner. strong . load ( SeqCst ) ;
15311526 if strong == 0 {
1532- // If the last `Arc` has *just* been dropped, it might not yet
1533- // have removed the implicit weak count, so the value we get
1534- // here might be 1 too high.
1535- weak
1527+ 0
15361528 } else {
1537- // As long as there's still at least 1 `Arc` around, subtract
1538- // the implicit weak pointer.
1539- // Note that the last `Arc` might get dropped between the 2
1540- // loads we do above, removing the implicit weak pointer. This
1541- // means that the value might be 1 too low here. In order to not
1542- // return 0 here (which would happen if we're the only weak
1543- // pointer), we guard against that specifically.
1544- cmp:: max ( 1 , weak - 1 )
1529+ // Since we observed that there was at least one strong pointer
1530+ // after reading the weak count, we know that the implicit weak
1531+ // reference (present whenever any strong references are alive)
1532+ // was still around when we observed the weak count, and can
1533+ // therefore safely subtract it.
1534+ weak - 1
15451535 }
1546- } )
1536+ } ) . unwrap_or ( 0 )
15471537 }
15481538
15491539 /// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`,
0 commit comments