@@ -41,6 +41,7 @@ use std::task::Waker;
41
41
use crate :: select:: Token ;
42
42
#[ cfg( feature = "async" ) ]
43
43
use crate :: r#async:: RecvFuture ;
44
+ use std:: cell:: Cell ;
44
45
45
46
/// An error that may be emitted when attempting to send a value into a channel on a sender.
46
47
#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
@@ -260,6 +261,7 @@ impl<T> Shared<T> {
260
261
}
261
262
262
263
#[ inline]
264
+ #[ cfg( feature = "async" ) ]
263
265
fn poll_inner ( & self ) -> Option < MutexGuard < ' _ , Inner < T > > > {
264
266
#[ cfg( windows) ] { self . inner . try_lock ( ) . ok ( ) }
265
267
#[ cfg( not( windows) ) ] { self . inner . try_lock ( ) }
@@ -363,6 +365,7 @@ impl<T> Shared<T> {
363
365
& ' a self ,
364
366
take_inner : impl FnOnce ( ) -> MutexGuard < ' a , Inner < T > > ,
365
367
buf : & mut VecDeque < T > ,
368
+ finished : & Cell < bool > ,
366
369
) -> Result < T , ( MutexGuard < Inner < T > > , TryRecvError ) > {
367
370
// Eagerly check the buffer
368
371
if let Some ( msg) = buf. pop_front ( ) {
@@ -380,8 +383,10 @@ impl<T> Shared<T> {
380
383
msg
381
384
} ,
382
385
// If there's nothing more in the queue, this might be because there are no senders
383
- None if inner. sender_count == 0 =>
384
- return Err ( ( inner, TryRecvError :: Disconnected ) ) ,
386
+ None if inner. sender_count == 0 => {
387
+ finished. set ( true ) ;
388
+ return Err ( ( inner, TryRecvError :: Disconnected ) ) ;
389
+ } ,
385
390
None => return Err ( ( inner, TryRecvError :: Empty ) ) ,
386
391
} ;
387
392
@@ -412,12 +417,13 @@ impl<T> Shared<T> {
412
417
fn recv (
413
418
& self ,
414
419
buf : & mut VecDeque < T > ,
420
+ finished : & Cell < bool > ,
415
421
) -> Result < T , RecvError > {
416
422
loop {
417
423
// Attempt to receive a message
418
424
let mut i = 0 ;
419
425
let inner = loop {
420
- match self . try_recv ( || self . wait_inner ( ) , buf) {
426
+ match self . try_recv ( || self . wait_inner ( ) , buf, finished ) {
421
427
Ok ( msg) => return Ok ( msg) ,
422
428
Err ( ( _, TryRecvError :: Disconnected ) ) => return Err ( RecvError :: Disconnected ) ,
423
429
Err ( ( inner, TryRecvError :: Empty ) ) if i == 3 => break inner,
@@ -438,9 +444,10 @@ impl<T> Shared<T> {
438
444
& self ,
439
445
deadline : Instant ,
440
446
buf : & mut VecDeque < T > ,
447
+ finished : & Cell < bool > ,
441
448
) -> Result < T , RecvTimeoutError > {
442
449
// Attempt a speculative recv. If we are lucky there might be a message in the queue!
443
- let mut inner = match self . try_recv ( || self . wait_inner ( ) , buf) {
450
+ let mut inner = match self . try_recv ( || self . wait_inner ( ) , buf, finished ) {
444
451
Ok ( msg) => return Ok ( msg) ,
445
452
Err ( ( _, TryRecvError :: Disconnected ) ) => return Err ( RecvTimeoutError :: Disconnected ) ,
446
453
Err ( ( inner, TryRecvError :: Empty ) ) => inner,
@@ -466,7 +473,7 @@ impl<T> Shared<T> {
466
473
}
467
474
468
475
// Attempt to receive a message from the queue
469
- inner = match self . try_recv ( || self . wait_inner ( ) , buf) {
476
+ inner = match self . try_recv ( || self . wait_inner ( ) , buf, finished ) {
470
477
Ok ( msg) => return Ok ( msg) ,
471
478
Err ( ( inner, TryRecvError :: Empty ) ) => inner,
472
479
Err ( ( _, TryRecvError :: Disconnected ) ) => return Err ( RecvTimeoutError :: Disconnected ) ,
@@ -555,28 +562,35 @@ pub struct Receiver<T> {
555
562
/// Used to prevent Sync being implemented for this type - we never actually use it!
556
563
/// TODO: impl<T> !Sync for Receiver<T> {} when negative traits are stable
557
564
_phantom_cell : UnsafeCell < ( ) > ,
565
+ /// Whether all receivers have disconnected and there are no messages in any buffer
566
+ finished : Cell < bool > ,
558
567
}
559
568
560
569
impl < T > Receiver < T > {
561
570
/// Wait for an incoming value from the channel associated with this receiver, returning an
562
571
/// error if all channel senders have been dropped.
563
572
pub fn recv ( & self ) -> Result < T , RecvError > {
564
- self . shared . recv ( & mut self . buffer . borrow_mut ( ) )
573
+ self . shared . recv ( & mut self . buffer . borrow_mut ( ) , & self . finished )
565
574
}
566
575
567
576
/// Wait for an incoming value from the channel associated with this receiver, returning an
568
577
/// error if all channel senders have been dropped or the timeout has expired.
569
578
pub fn recv_timeout ( & self , timeout : Duration ) -> Result < T , RecvTimeoutError > {
570
579
self . shared . recv_deadline (
571
580
Instant :: now ( ) . checked_add ( timeout) . unwrap ( ) ,
572
- & mut self . buffer . borrow_mut ( )
581
+ & mut self . buffer . borrow_mut ( ) ,
582
+ & self . finished
573
583
)
574
584
}
575
585
576
586
/// Wait for an incoming value from the channel associated with this receiver, returning an
577
587
/// error if all channel senders have been dropped or the deadline has passed.
578
588
pub fn recv_deadline ( & self , deadline : Instant ) -> Result < T , RecvTimeoutError > {
579
- self . shared . recv_deadline ( deadline, & mut self . buffer . borrow_mut ( ) )
589
+ self . shared . recv_deadline (
590
+ deadline,
591
+ & mut self . buffer . borrow_mut ( ) ,
592
+ & self . finished
593
+ )
580
594
}
581
595
582
596
// Takes `&mut self` to avoid >1 task waiting on this channel
@@ -593,7 +607,11 @@ impl<T> Receiver<T> {
593
607
pub fn try_recv ( & self ) -> Result < T , TryRecvError > {
594
608
self
595
609
. shared
596
- . try_recv ( || self . shared . wait_inner ( ) , & mut self . buffer . borrow_mut ( ) )
610
+ . try_recv (
611
+ || self . shared . wait_inner ( ) ,
612
+ & mut self . buffer . borrow_mut ( ) ,
613
+ & self . finished
614
+ )
597
615
. map_err ( |( _, err) | err)
598
616
}
599
617
@@ -716,6 +734,7 @@ pub fn unbounded<T>() -> (Sender<T>, Receiver<T>) {
716
734
Receiver {
717
735
shared,
718
736
buffer : RefCell :: new ( VecDeque :: new ( ) ) ,
737
+ finished : Cell :: new ( false ) ,
719
738
_phantom_cell : UnsafeCell :: new ( ( ) )
720
739
} ,
721
740
)
@@ -750,6 +769,7 @@ pub fn bounded<T>(cap: usize) -> (Sender<T>, Receiver<T>) {
750
769
Receiver {
751
770
shared,
752
771
buffer : RefCell :: new ( VecDeque :: new ( ) ) ,
772
+ finished : Cell :: new ( false ) ,
753
773
_phantom_cell : UnsafeCell :: new ( ( ) )
754
774
} ,
755
775
)
0 commit comments