@@ -12,7 +12,7 @@ use core::sync::atomic;
12
12
use core:: sync:: atomic:: Ordering :: { Acquire , Relaxed , Release , SeqCst } ;
13
13
use core:: borrow;
14
14
use core:: fmt;
15
- use core:: cmp:: { self , Ordering } ;
15
+ use core:: cmp:: Ordering ;
16
16
use core:: iter;
17
17
use core:: intrinsics:: abort;
18
18
use core:: mem:: { self , align_of, align_of_val, size_of_val} ;
@@ -1508,9 +1508,8 @@ impl<T: ?Sized> Weak<T> {
1508
1508
/// Gets an approximation of the number of `Weak` pointers pointing to this
1509
1509
/// allocation.
1510
1510
///
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.
1514
1513
///
1515
1514
/// # Accuracy
1516
1515
///
@@ -1520,30 +1519,21 @@ impl<T: ?Sized> Weak<T> {
1520
1519
///
1521
1520
/// [`Weak::new`]: #method.new
1522
1521
#[ 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 {
1528
1523
self . inner ( ) . map ( |inner| {
1529
- let strong = inner. strong . load ( SeqCst ) ;
1530
1524
let weak = inner. weak . load ( SeqCst ) ;
1525
+ let strong = inner. strong . load ( SeqCst ) ;
1531
1526
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
1536
1528
} 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
1545
1535
}
1546
- } )
1536
+ } ) . unwrap_or ( 0 )
1547
1537
}
1548
1538
1549
1539
/// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`,
0 commit comments