@@ -252,6 +252,7 @@ impl<T> Shared<T> {
252
252
}
253
253
254
254
#[ inline]
255
+ #[ cfg( feature = "async" ) ]
255
256
fn poll_inner ( & self ) -> Option < MutexGuard < ' _ , Inner < T > > > {
256
257
#[ cfg( windows) ] { self . inner . try_lock ( ) . ok ( ) }
257
258
#[ cfg( not( windows) ) ] { self . inner . try_lock ( ) }
@@ -356,6 +357,7 @@ impl<T> Shared<T> {
356
357
& ' a self ,
357
358
take_inner : impl FnOnce ( ) -> MutexGuard < ' a , Inner < T > > ,
358
359
buf : & mut VecDeque < T > ,
360
+ finished : & Cell < bool > ,
359
361
mpmc_mode : bool ,
360
362
) -> Result < T , ( MutexGuard < Inner < T > > , TryRecvError ) > {
361
363
// Eagerly check the buffer
@@ -374,8 +376,10 @@ impl<T> Shared<T> {
374
376
msg
375
377
} ,
376
378
// If there's nothing more in the queue, this might be because there are no senders
377
- None if inner. sender_count == 0 =>
378
- return Err ( ( inner, TryRecvError :: Disconnected ) ) ,
379
+ None if inner. sender_count == 0 => {
380
+ finished. set ( true ) ;
381
+ return Err ( ( inner, TryRecvError :: Disconnected ) ) ;
382
+ } ,
379
383
None => return Err ( ( inner, TryRecvError :: Empty ) ) ,
380
384
} ;
381
385
@@ -412,13 +416,14 @@ impl<T> Shared<T> {
412
416
fn recv (
413
417
& self ,
414
418
buf : & mut VecDeque < T > ,
419
+ finished : & Cell < bool > ,
415
420
mpmc_mode : bool ,
416
421
) -> Result < T , RecvError > {
417
422
loop {
418
423
// Attempt to receive a message
419
424
let mut i = 0 ;
420
425
let inner = loop {
421
- match self . try_recv ( || self . wait_inner ( ) , buf, mpmc_mode) {
426
+ match self . try_recv ( || self . wait_inner ( ) , buf, finished , mpmc_mode) {
422
427
Ok ( msg) => return Ok ( msg) ,
423
428
Err ( ( _, TryRecvError :: Disconnected ) ) => return Err ( RecvError :: Disconnected ) ,
424
429
Err ( ( inner, TryRecvError :: Empty ) ) if i == 3 => break inner,
@@ -439,10 +444,11 @@ impl<T> Shared<T> {
439
444
& self ,
440
445
deadline : Instant ,
441
446
buf : & mut VecDeque < T > ,
447
+ finished : & Cell < bool > ,
442
448
mpmc_mode : bool ,
443
449
) -> Result < T , RecvTimeoutError > {
444
450
// Attempt a speculative recv. If we are lucky there might be a message in the queue!
445
- let mut inner = match self . try_recv ( || self . wait_inner ( ) , buf, mpmc_mode) {
451
+ let mut inner = match self . try_recv ( || self . wait_inner ( ) , buf, finished , mpmc_mode) {
446
452
Ok ( msg) => return Ok ( msg) ,
447
453
Err ( ( _, TryRecvError :: Disconnected ) ) => return Err ( RecvTimeoutError :: Disconnected ) ,
448
454
Err ( ( inner, TryRecvError :: Empty ) ) => inner,
@@ -468,7 +474,7 @@ impl<T> Shared<T> {
468
474
}
469
475
470
476
// Attempt to receive a message from the queue
471
- inner = match self . try_recv ( || self . wait_inner ( ) , buf, mpmc_mode) {
477
+ inner = match self . try_recv ( || self . wait_inner ( ) , buf, finished , mpmc_mode) {
472
478
Ok ( msg) => return Ok ( msg) ,
473
479
Err ( ( inner, TryRecvError :: Empty ) ) => inner,
474
480
Err ( ( _, TryRecvError :: Disconnected ) ) => return Err ( RecvTimeoutError :: Disconnected ) ,
@@ -555,13 +561,15 @@ pub struct Receiver<T> {
555
561
mpmc_mode : Cell < bool > ,
556
562
/// Buffer for messages (only uses when mpmc_mode is false)
557
563
buffer : RefCell < VecDeque < T > > ,
564
+ /// Whether all receivers have disconnected and there are no messages in any buffer
565
+ finished : Cell < bool > ,
558
566
}
559
567
560
568
impl < T > Receiver < T > {
561
569
/// Wait for an incoming value from the channel associated with this receiver, returning an
562
570
/// error if all channel senders have been dropped.
563
571
pub fn recv ( & self ) -> Result < T , RecvError > {
564
- self . shared . recv ( & mut self . buffer . borrow_mut ( ) , self . mpmc_mode . get ( ) )
572
+ self . shared . recv ( & mut self . buffer . borrow_mut ( ) , & self . finished , self . mpmc_mode . get ( ) )
565
573
}
566
574
567
575
/// Wait for an incoming value from the channel associated with this receiver, returning an
@@ -570,14 +578,20 @@ impl<T> Receiver<T> {
570
578
self . shared . recv_deadline (
571
579
Instant :: now ( ) . checked_add ( timeout) . unwrap ( ) ,
572
580
& mut self . buffer . borrow_mut ( ) ,
581
+ & self . finished ,
573
582
self . mpmc_mode . get ( ) ,
574
583
)
575
584
}
576
585
577
586
/// Wait for an incoming value from the channel associated with this receiver, returning an
578
587
/// error if all channel senders have been dropped or the deadline has passed.
579
588
pub fn recv_deadline ( & self , deadline : Instant ) -> Result < T , RecvTimeoutError > {
580
- self . shared . recv_deadline ( deadline, & mut self . buffer . borrow_mut ( ) , self . mpmc_mode . get ( ) )
589
+ self . shared . recv_deadline (
590
+ deadline,
591
+ & mut self . buffer . borrow_mut ( ) ,
592
+ & self . finished ,
593
+ self . mpmc_mode . get ( )
594
+ )
581
595
}
582
596
583
597
// Takes `&mut self` to avoid >1 task waiting on this channel
@@ -594,7 +608,12 @@ impl<T> Receiver<T> {
594
608
pub fn try_recv ( & self ) -> Result < T , TryRecvError > {
595
609
self
596
610
. shared
597
- . try_recv ( || self . shared . wait_inner ( ) , & mut self . buffer . borrow_mut ( ) , self . mpmc_mode . get ( ) )
611
+ . try_recv (
612
+ || self . shared . wait_inner ( ) ,
613
+ & mut self . buffer . borrow_mut ( ) ,
614
+ & self . finished ,
615
+ self . mpmc_mode . get ( )
616
+ )
598
617
. map_err ( |( _, err) | err)
599
618
}
600
619
@@ -645,6 +664,7 @@ impl<T> Clone for Receiver<T> {
645
664
shared : self . shared . clone ( ) ,
646
665
mpmc_mode : Cell :: new ( true ) ,
647
666
buffer : RefCell :: new ( VecDeque :: new ( ) ) ,
667
+ finished : Cell :: new ( false ) ,
648
668
}
649
669
}
650
670
}
@@ -745,6 +765,7 @@ pub fn unbounded<T>() -> (Sender<T>, Receiver<T>) {
745
765
shared,
746
766
mpmc_mode : Cell :: new ( false ) ,
747
767
buffer : RefCell :: new ( VecDeque :: new ( ) ) ,
768
+ finished : Cell :: new ( false ) ,
748
769
} ,
749
770
)
750
771
}
@@ -779,6 +800,7 @@ pub fn bounded<T>(cap: usize) -> (Sender<T>, Receiver<T>) {
779
800
shared,
780
801
mpmc_mode : Cell :: new ( false ) ,
781
802
buffer : RefCell :: new ( VecDeque :: new ( ) ) ,
803
+ finished : Cell :: new ( false ) ,
782
804
} ,
783
805
)
784
806
}
0 commit comments