impl<T> Stream for UnboundedReceiver<T> {
type Item = T;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<T>> {
// Try to read a message off of the message queue.
match self.next_message() {
Poll::Ready(msg) => {
if msg.is_none() {
self.inner = None;
}
Poll::Ready(msg)
}
Poll::Pending => {
println!(
"scw00 regist waker done {:?} {:?}",
cx.waker(),
std::thread::current().id()
);
// There are no messages to read, in this case, park.
self.inner.as_ref().unwrap().recv_task.register(cx.waker());
// Check queue again after parking to prevent race condition:
// a message could be added to the queue after previous `next_message`
// before `register` call.
self.next_message()
}
}
}
// Push message to the queue and signal to the receiver
fn queue_push_and_signal(&self, msg: T) {
// Push the message onto the message queue
self.inner.message_queue.push(msg);
// Signal to the receiver that a message has been enqueued. If the
// receiver is parked, this will unpark the task.
if let Some(waker) = self.inner.recv_task.take() {
println!(
"scw00 take waker {:?} {:?}",
waker,
std::thread::current().id()
);
waker.wake()
} else {
println!("scw00 missing waker {:?}", std::thread::current().id())
}
}
I found mpsc::channel can miss some event when I sending data from different thread.