2121pub use self :: Failure :: * ;
2222
2323use core:: cmp;
24+ use core:: intrinsics:: abort;
2425use core:: isize;
2526
2627use sync:: atomic:: { AtomicUsize , AtomicIsize , AtomicBool , Ordering } ;
@@ -34,6 +35,7 @@ use time::Instant;
3435
3536const DISCONNECTED : isize = isize:: MIN ;
3637const FUDGE : isize = 1024 ;
38+ const MAX_REFCOUNT : usize = ( isize:: MAX ) as usize ;
3739#[ cfg( test) ]
3840const MAX_STEALS : isize = 5 ;
3941#[ cfg( not( test) ) ]
@@ -46,7 +48,7 @@ pub struct Packet<T> {
4648 to_wake : AtomicUsize , // SignalToken for wake up
4749
4850 // The number of channels which are currently using this packet.
49- channels : AtomicIsize ,
51+ channels : AtomicUsize ,
5052
5153 // See the discussion in Port::drop and the channel send methods for what
5254 // these are used for
@@ -72,7 +74,7 @@ impl<T> Packet<T> {
7274 cnt : AtomicIsize :: new ( 0 ) ,
7375 steals : 0 ,
7476 to_wake : AtomicUsize :: new ( 0 ) ,
75- channels : AtomicIsize :: new ( 2 ) ,
77+ channels : AtomicUsize :: new ( 2 ) ,
7678 port_dropped : AtomicBool :: new ( false ) ,
7779 sender_drain : AtomicIsize :: new ( 0 ) ,
7880 select_lock : Mutex :: new ( ( ) ) ,
@@ -340,7 +342,14 @@ impl<T> Packet<T> {
340342 // Prepares this shared packet for a channel clone, essentially just bumping
341343 // a refcount.
342344 pub fn clone_chan ( & mut self ) {
343- self . channels . fetch_add ( 1 , Ordering :: SeqCst ) ;
345+ let old_count = self . channels . fetch_add ( 1 , Ordering :: SeqCst ) ;
346+
347+ // See comments on Arc::clone() on why we do this (for `mem::forget`).
348+ if old_count > MAX_REFCOUNT {
349+ unsafe {
350+ abort ( ) ;
351+ }
352+ }
344353 }
345354
346355 // Decrement the reference count on a channel. This is called whenever a
0 commit comments