1
0
Fork 0
forked from wry/wry

utils: use UnsafeCell in AsyncQueue

This commit is contained in:
Julian Orth 2022-05-13 20:15:31 +02:00
parent 22b7fb2ced
commit f50964d110

View file

@ -1,14 +1,17 @@
use std::{ use {
cell::{Cell, RefCell}, crate::utils::ptr_ext::{MutPtrExt, PtrExt},
collections::VecDeque, std::{
future::Future, cell::{Cell, UnsafeCell},
mem, collections::VecDeque,
pin::Pin, future::Future,
task::{Context, Poll, Waker}, mem,
pin::Pin,
task::{Context, Poll, Waker},
},
}; };
pub struct AsyncQueue<T> { pub struct AsyncQueue<T> {
data: RefCell<VecDeque<T>>, data: UnsafeCell<VecDeque<T>>,
waiter: Cell<Option<Waker>>, waiter: Cell<Option<Waker>>,
} }
@ -27,14 +30,16 @@ impl<T> AsyncQueue<T> {
} }
pub fn push(&self, t: T) { pub fn push(&self, t: T) {
self.data.borrow_mut().push_back(t); unsafe {
self.data.get().deref_mut().push_back(t);
}
if let Some(waiter) = self.waiter.take() { if let Some(waiter) = self.waiter.take() {
waiter.wake(); waiter.wake();
} }
} }
pub fn try_pop(&self) -> Option<T> { pub fn try_pop(&self) -> Option<T> {
self.data.borrow_mut().pop_front() unsafe { self.data.get().deref_mut().pop_front() }
} }
pub fn pop<'a>(&'a self) -> AsyncQueuePop<'a, T> { pub fn pop<'a>(&'a self) -> AsyncQueuePop<'a, T> {
@ -46,12 +51,14 @@ impl<T> AsyncQueue<T> {
} }
pub fn clear(&self) { pub fn clear(&self) {
mem::take(&mut *self.data.borrow_mut()); unsafe {
mem::take(self.data.get().deref_mut());
}
self.waiter.take(); self.waiter.take();
} }
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.data.borrow_mut().is_empty() unsafe { self.data.get().deref().is_empty() }
} }
} }
@ -80,7 +87,7 @@ impl<'a, T> Future for AsyncQueueNonEmpty<'a, T> {
type Output = (); type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.queue.data.borrow_mut().len() > 0 { if unsafe { self.queue.data.get().deref().len() } > 0 {
Poll::Ready(()) Poll::Ready(())
} else { } else {
self.queue.waiter.set(Some(cx.waker().clone())); self.queue.waiter.set(Some(cx.waker().clone()));