Compare commits

..

No commits in common. "a1fd74320b0072f0690382481314c1b1867ae86c" and "38ec8158ddb81675838571732e7fe0a82056cbc4" have entirely different histories.

2 changed files with 0 additions and 137 deletions

View File

@ -1,135 +0,0 @@
use std::{
future::Future,
pin::Pin,
sync::{Mutex, MutexGuard},
task::{Context, Poll, Waker},
};
pub struct Mailbox<T>(Mutex<MailboxInner<T>>);
impl<T> Mailbox<T> {
pub fn new() -> Self {
Mailbox(Mutex::new(MailboxInner {
waker: None,
value: None,
}))
}
}
struct MailboxInner<T> {
waker: Option<Waker>,
value: Option<T>,
}
fn wake<T>(mut mb: MutexGuard<MailboxInner<T>>) {
let waker = mb.waker.take();
drop(mb);
if let Some(waker) = waker {
waker.wake();
}
}
struct MailboxPut<'a, T>(&'a Mailbox<T>, Option<T>);
impl<'a, T> Unpin for MailboxPut<'a, T> {}
impl<'a, T> Future for MailboxPut<'a, T> {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut mb = self.0 .0.lock().unwrap();
let None = mb.value else {
mb.waker = Some(cx.waker().clone());
return Poll::Pending;
};
mb.value = self.1.take();
wake(mb);
Poll::Ready(())
}
}
struct MailboxGet<'a, T>(&'a Mailbox<T>);
impl<'a, T> Future for MailboxGet<'a, T> {
type Output = T;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut mb = self.0 .0.lock().unwrap();
let Some(value) = mb.value.take() else {
mb.waker = Some(cx.waker().clone());
return Poll::Pending;
};
wake(mb);
Poll::Ready(value)
}
}
impl<T> Mailbox<T> {
pub fn put(&self, value: T) -> impl Future<Output = ()> + '_ {
MailboxPut(&self, Some(value))
}
pub fn get(&self) -> impl Future<Output = T> + '_ {
MailboxGet(&self)
}
}
#[cfg(test)]
mod tests {
use std::{pin::pin, sync::Arc, task::Wake};
use super::*;
struct NoopWaker;
impl Wake for NoopWaker {
fn wake(self: std::sync::Arc<Self>) {}
}
fn ready(f: impl Future) -> bool {
let f = pin!(f);
matches!(
f.poll(&mut Context::from_waker(&Arc::new(NoopWaker).into())),
Poll::Ready(_)
)
}
#[test]
fn test_mailbox_empty() {
let mb = Mailbox::<i32>::new();
assert!(!ready(mb.get()));
}
#[test]
fn test_mailbox_once() {
let mb = Mailbox::<i32>::new();
pollster::block_on(mb.put(42));
assert_eq!(pollster::block_on(mb.get()), 42);
assert!(!ready(mb.get()));
}
#[test]
fn test_mailbox_once_oor() {
let mb = Mailbox::<i32>::new();
let f = mb.get();
pollster::block_on(mb.put(42));
assert_eq!(pollster::block_on(f), 42);
}
#[test]
fn test_mailbox_twice_no_wait() {
let mb = Mailbox::<i32>::new();
pollster::block_on(mb.put(42));
assert!(!ready(mb.put(13)));
assert_eq!(pollster::block_on(mb.get()), 42);
assert!(!ready(mb.get()));
}
#[test]
fn test_mailbox_twice_in_order() {
let mb = Mailbox::<i32>::new();
let f = mb.get();
pollster::block_on(mb.put(42));
assert_eq!(pollster::block_on(f), 42);
let f = mb.get();
pollster::block_on(mb.put(13));
assert_eq!(pollster::block_on(f), 13);
assert!(!ready(mb.get()));
}
}

View File

@ -6,8 +6,6 @@ use winit::{
window::{Window, WindowAttributes}, window::{Window, WindowAttributes},
}; };
mod mailbox;
fn main() { fn main() {
let event_loop = EventLoop::new().unwrap(); let event_loop = EventLoop::new().unwrap();