@@ -145,6 +145,7 @@ pub struct Receiver<T> {
145
145
#[ derive( Debug ) ]
146
146
pub struct UnboundedReceiver < T > {
147
147
inner : Arc < UnboundedInner < T > > ,
148
+ num_received : usize ,
148
149
}
149
150
150
151
// `Pin<&mut UnboundedReceiver<T>>` is never projected to `Pin<&mut T>`
@@ -300,7 +301,8 @@ struct State {
300
301
// `true` when the channel is open
301
302
is_open : bool ,
302
303
303
- // Number of messages in the channel
304
+ // Number of messages in the channel for bounded queue
305
+ // Number of sent messages modulo MAX_CAPACITY + 1 for unbounded queue
304
306
num_messages : usize ,
305
307
}
306
308
@@ -424,6 +426,7 @@ pub fn unbounded<T>() -> (UnboundedSender<T>, UnboundedReceiver<T>) {
424
426
425
427
let rx = UnboundedReceiver {
426
428
inner,
429
+ num_received : 0 ,
427
430
} ;
428
431
429
432
( tx, rx)
@@ -625,17 +628,14 @@ impl<T> UnboundedSender<T> {
625
628
626
629
// Do the send without parking current task.
627
630
fn do_send_nb ( & self , msg : T ) -> Result < ( ) , TrySendError < T > > {
628
- match self . inner . inc_num_messages ( ) {
629
- Some ( _num_messages) => { }
630
- None => {
631
- return Err ( TrySendError {
632
- err : SendError {
633
- kind : SendErrorKind :: Disconnected ,
634
- } ,
635
- val : msg,
636
- } ) ;
637
- } ,
638
- } ;
631
+ if !self . inner . inc_num_messages ( ) {
632
+ return Err ( TrySendError {
633
+ err : SendError {
634
+ kind : SendErrorKind :: Disconnected ,
635
+ } ,
636
+ val : msg,
637
+ } ) ;
638
+ }
639
639
640
640
self . inner . queue_push_and_signal ( msg) ;
641
641
@@ -844,13 +844,12 @@ impl<T> UnboundedReceiver<T> {
844
844
match unsafe { self . inner . message_queue . pop_spin ( ) } {
845
845
Some ( msg) => {
846
846
// Decrement number of messages
847
- self . inner . dec_num_messages ( ) ;
847
+ self . num_received = self . num_received . wrapping_add ( 1 ) ;
848
848
849
849
Poll :: Ready ( Some ( msg) )
850
850
}
851
851
None => {
852
- let state = decode_state ( self . inner . state . load ( SeqCst ) ) ;
853
- if state. is_open || state. num_messages != 0 {
852
+ if !self . is_end_of_queue_from_state ( ) {
854
853
// If queue is open, we need to return Pending
855
854
// to be woken up when new messages arrive.
856
855
// If queue is closed but num_messages is non-zero,
@@ -868,6 +867,20 @@ impl<T> UnboundedReceiver<T> {
868
867
}
869
868
}
870
869
870
+ fn is_end_of_queue_from_state ( & self ) -> bool {
871
+ let state = decode_state ( self . inner . state . load ( SeqCst ) ) ;
872
+ if state. is_open {
873
+ false
874
+ } else {
875
+ // The condition is true when either:
876
+ // * queue is empty
877
+ // * N * (MAX_CAPACITY + 1) messages are in the queue
878
+ // or being added to the queue at this moment
879
+ // The latter is very improbable because receiver has checked the queue recently.
880
+ state. num_messages == ( self . num_received & !OPEN_MASK )
881
+ }
882
+ }
883
+
871
884
/// Tries to receive the next message without notifying a context if empty.
872
885
///
873
886
/// It is not recommended to call this function from inside of a future,
@@ -996,29 +1009,24 @@ impl<T> UnboundedInner<T> {
996
1009
}
997
1010
998
1011
// Increment the number of queued messages. Returns new `num_messages`.
999
- fn inc_num_messages ( & self ) -> Option < usize > {
1012
+ fn inc_num_messages ( & self ) -> bool {
1000
1013
let mut curr = self . state . load ( SeqCst ) ;
1001
1014
1002
1015
loop {
1003
1016
let mut state = decode_state ( curr) ;
1004
1017
1005
1018
// The receiver end closed the channel.
1006
1019
if !state. is_open {
1007
- return None ;
1020
+ return false ;
1008
1021
}
1009
1022
1010
- // This probably is never hit? Odds are the process will run out of
1011
- // memory first. It may be worth to return something else in this
1012
- // case?
1013
- assert ! ( state. num_messages < MAX_CAPACITY , "buffer space \
1014
- exhausted; sending this messages would overflow the state") ;
1015
-
1016
- state. num_messages += 1 ;
1023
+ // Won't overflow
1024
+ state. num_messages = ( state. num_messages + 1 ) & !OPEN_MASK ;
1017
1025
1018
1026
let next = encode_state ( & state) ;
1019
1027
match self . state . compare_exchange ( curr, next, SeqCst , SeqCst ) {
1020
1028
Ok ( _) => {
1021
- return Some ( state . num_messages )
1029
+ return true ;
1022
1030
}
1023
1031
Err ( actual) => curr = actual,
1024
1032
}
@@ -1034,13 +1042,6 @@ impl<T> UnboundedInner<T> {
1034
1042
1035
1043
self . state . fetch_and ( !OPEN_MASK , SeqCst ) ;
1036
1044
}
1037
-
1038
- fn dec_num_messages ( & self ) {
1039
- // OPEN_MASK is highest bit, so it's unaffected by subtraction
1040
- // unless there's underflow, and we know there's no underflow
1041
- // because number of messages at this point is always > 0.
1042
- self . state . fetch_sub ( 1 , SeqCst ) ;
1043
- }
1044
1045
}
1045
1046
1046
1047
unsafe impl < T : Send > Send for BoundedInner < T > { }
0 commit comments