Use Options instead of a custom enum

It looks bad either way
This commit is contained in:
numzero 2025-01-11 00:23:30 +03:00
parent 8ea6684335
commit 8007922721

View File

@ -9,13 +9,16 @@ pub struct Mailbox<T>(Mutex<MailboxInner<T>>);
impl<T> Mailbox<T> { impl<T> Mailbox<T> {
pub fn new() -> Self { pub fn new() -> Self {
Mailbox(Mutex::new(MailboxInner::Empty(None))) Mailbox(Mutex::new(MailboxInner {
waker: None,
value: None,
}))
} }
} }
enum MailboxInner<T> { struct MailboxInner<T> {
Empty(Option<Waker>), waker: Option<Waker>,
Full(Option<Waker>, T), value: Option<T>,
} }
struct MailboxPut<'a, T>(&'a Mailbox<T>, Option<T>); struct MailboxPut<'a, T>(&'a Mailbox<T>, Option<T>);
@ -25,18 +28,18 @@ impl<'a, T> Future for MailboxPut<'a, T> {
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut mb = self.0 .0.lock().unwrap(); let mut mb = self.0 .0.lock().unwrap();
match &mut *mb { match mb.value {
MailboxInner::Empty(ref mut waker) => { None => {
let waker = waker.take(); let waker = mb.waker.take();
*mb = MailboxInner::Full(None, self.1.take().expect("Mailbox future overpooled!")); mb.value = self.1.take();
drop(mb); drop(mb);
if let Some(waker) = waker { if let Some(waker) = waker {
waker.wake(); waker.wake();
} }
Poll::Ready(()) Poll::Ready(())
} }
MailboxInner::Full(ref mut waker, _) => { Some(_) => {
*waker = Some(cx.waker().clone()); mb.waker = Some(cx.waker().clone());
Poll::Pending Poll::Pending
} }
} }
@ -49,13 +52,13 @@ impl<'a, T> Future for MailboxGet<'a, T> {
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut mb = self.0 .0.lock().unwrap(); let mut mb = self.0 .0.lock().unwrap();
let old = std::mem::replace(&mut *mb, MailboxInner::Empty(None)); match mb.value.take() {
match old { None => {
MailboxInner::Empty(_) => { mb.waker = Some(cx.waker().clone());
*mb = MailboxInner::Empty(Some(cx.waker().clone()));
Poll::Pending Poll::Pending
} }
MailboxInner::Full(waker, value) => { Some(value) => {
let waker = mb.waker.take();
drop(mb); drop(mb);
if let Some(waker) = waker { if let Some(waker) = waker {
waker.wake(); waker.wake();