Skip to content

Value sent through mpsc::Permit should be immediately dropped when receiver is already dropped #7714

@tabokie

Description

@tabokie

Version

Latest (1.48.0)

Platform

Doesn't matter.

Description

Even though not documented explicitly, but the current behavior is, all values stored in the channel are dropped when the sole receiver is dropped:

fn drop(&mut self) {
use super::block::Read::Value;
self.close();
self.inner.rx_fields.with_mut(|rx_fields_ptr| {
let rx_fields = unsafe { &mut *rx_fields_ptr };
struct Guard<'a, T, S: Semaphore> {
list: &'a mut list::Rx<T>,
tx: &'a list::Tx<T>,
sem: &'a S,
}
impl<'a, T, S: Semaphore> Guard<'a, T, S> {
fn drain(&mut self) {
// call T's destructor.
while let Some(Value(_)) = self.list.pop(self.tx) {
self.sem.add_permit();
}
}
}
impl<'a, T, S: Semaphore> Drop for Guard<'a, T, S> {
fn drop(&mut self) {
self.drain();
}
}
let mut guard = Guard {
list: &mut rx_fields.list,
tx: &self.inner.tx,
sem: &self.inner.semaphore,
};
guard.drain();
});
}

It is natural for user to consider "receiver dropped -> values dropped" an invariant.

But it doesn't hold in this sequence of event:

  • Sender acquires a permit
  • Receiver is dropped
  • Sender publishes a value using the permit

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-tokioArea: The main tokio crateC-bugCategory: This is a bug.M-syncModule: tokio/sync

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions