@@ -117,17 +117,17 @@ impl<T> Arc<T> {
117
117
// these contents.
118
118
unsafe { & * self . _ptr }
119
119
}
120
+ }
120
121
121
- /// Get the number of weak references to this value.
122
- #[ inline]
123
- #[ experimental]
124
- pub fn weak_count ( & self ) -> uint { self . inner ( ) . weak . load ( atomic:: SeqCst ) - 1 }
122
+ /// Get the number of weak references to this value.
123
+ #[ inline]
124
+ #[ experimental]
125
+ pub fn weak_count < T > ( this : & Arc < T > ) -> uint { this . inner ( ) . weak . load ( atomic:: SeqCst ) - 1 }
125
126
126
- /// Get the number of strong references to this value.
127
- #[ inline]
128
- #[ experimental]
129
- pub fn strong_count ( & self ) -> uint { self . inner ( ) . strong . load ( atomic:: SeqCst ) }
130
- }
127
+ /// Get the number of strong references to this value.
128
+ #[ inline]
129
+ #[ experimental]
130
+ pub fn strong_count < T > ( this : & Arc < T > ) -> uint { this. inner ( ) . strong . load ( atomic:: SeqCst ) }
131
131
132
132
#[ unstable = "waiting on stability of Clone" ]
133
133
impl < T > Clone for Arc < T > {
@@ -257,29 +257,6 @@ impl<T: Sync + Send> Weak<T> {
257
257
// See comments above for why this is "safe"
258
258
unsafe { & * self . _ptr }
259
259
}
260
-
261
- // Why is there no `weak_count()`?
262
- //
263
- // It is not possible to determine the number of weak references with only a weak reference
264
- // accurately in a wait-free manner. This is because we have a data-race with the last strong
265
- // reference's `drop` method. If that operation pauses between decrementing the strong
266
- // reference count to 0 and removing the implicit weak reference that the strong references
267
- // share then we will incorrectly think there is one more weak reference then there really is.
268
- //
269
- // We cannot get around this without making parts of this object no longer wait-free, since we
270
- // would either need to use locks to get mutual exclusion with `drop` or make it so that the
271
- // weak and strong reference counts can be modified atomically together. The first option
272
- // destroys wait-freedom by adding a lock and the second (in addition to being annoying to
273
- // implement) would make many operations (at least `downgrade` and both `clone`s) go from being
274
- // wait-free to merely lock-free, as we would need to do a manual CAS loop to get around other
275
- // threads modifying the other value in each of these cases.
276
-
277
- /// Get the number of strong references to this value.
278
- ///
279
- /// If this function returns 0 then the value has been freed.
280
- #[ inline]
281
- #[ experimental]
282
- pub fn strong_count ( & self ) -> uint { self . inner ( ) . strong . load ( atomic:: SeqCst ) }
283
260
}
284
261
285
262
#[ experimental = "Weak pointers may not belong in this module." ]
@@ -354,7 +331,7 @@ mod tests {
354
331
use std:: sync:: atomic;
355
332
use std:: task;
356
333
use std:: vec:: Vec ;
357
- use super :: { Arc , Weak } ;
334
+ use super :: { Arc , Weak , weak_count , strong_count } ;
358
335
use std:: sync:: Mutex ;
359
336
360
337
struct Canary ( * mut atomic:: AtomicUint ) ;
@@ -501,38 +478,40 @@ mod tests {
501
478
#[ test]
502
479
fn test_strong_count ( ) {
503
480
let a = Arc :: new ( 0u32 ) ;
504
- assert ! ( a . strong_count( ) == 1 ) ;
481
+ assert ! ( strong_count( & a ) == 1 ) ;
505
482
let w = a. downgrade ( ) ;
506
- assert ! ( a . strong_count( ) == 1 ) ;
483
+ assert ! ( strong_count( & a ) == 1 ) ;
507
484
let b = w. upgrade ( ) . expect ( "" ) ;
508
- assert ! ( b . strong_count( ) == 2 ) ;
509
- assert ! ( a . strong_count( ) == 2 ) ;
485
+ assert ! ( strong_count( & b ) == 2 ) ;
486
+ assert ! ( strong_count( & a ) == 2 ) ;
510
487
drop ( w) ;
511
488
drop ( a) ;
512
- assert ! ( b . strong_count( ) == 1 ) ;
489
+ assert ! ( strong_count( & b ) == 1 ) ;
513
490
let c = b. clone ( ) ;
514
- assert ! ( b . strong_count( ) == 2 ) ;
515
- assert ! ( c . strong_count( ) == 2 ) ;
491
+ assert ! ( strong_count( & b ) == 2 ) ;
492
+ assert ! ( strong_count( & c ) == 2 ) ;
516
493
}
517
494
518
495
#[ test]
519
496
fn test_weak_count ( ) {
520
497
let a = Arc :: new ( 0u32 ) ;
521
- assert ! ( a . strong_count( ) == 1 ) ;
522
- assert ! ( a . weak_count( ) == 0 ) ;
498
+ assert ! ( strong_count( & a ) == 1 ) ;
499
+ assert ! ( weak_count( & a ) == 0 ) ;
523
500
let w = a. downgrade ( ) ;
524
- assert ! ( a. strong_count( ) == 1 ) ;
525
- assert ! ( w. strong_count( ) == 1 ) ;
526
- assert ! ( a. weak_count( ) == 1 ) ;
501
+ assert ! ( strong_count( & a) == 1 ) ;
502
+ assert ! ( weak_count( & a) == 1 ) ;
503
+ let x = w. clone ( ) ;
504
+ assert ! ( weak_count( & a) == 2 ) ;
527
505
drop ( w) ;
528
- assert ! ( a. strong_count( ) == 1 ) ;
529
- assert ! ( a. weak_count( ) == 0 ) ;
506
+ drop ( x) ;
507
+ assert ! ( strong_count( & a) == 1 ) ;
508
+ assert ! ( weak_count( & a) == 0 ) ;
530
509
let c = a. clone ( ) ;
531
- assert ! ( a . strong_count( ) == 2 ) ;
532
- assert ! ( a . weak_count( ) == 0 ) ;
510
+ assert ! ( strong_count( & a ) == 2 ) ;
511
+ assert ! ( weak_count( & a ) == 0 ) ;
533
512
let d = c. downgrade ( ) ;
534
- assert ! ( c . weak_count( ) == 1 ) ;
535
- assert ! ( c . strong_count( ) == 2 ) ;
513
+ assert ! ( weak_count( & c ) == 1 ) ;
514
+ assert ! ( strong_count( & c ) == 2 ) ;
536
515
537
516
drop ( a) ;
538
517
drop ( c) ;
0 commit comments