pub struct WW_Promise_Waiter<T> {
data: RefCell<Option<T>>,}
impl<T> Future for WW_Promise_Waiter<T> {
type Output = T;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut v: Option<T> = None;
std::mem::swap(self.data.borrow_mut().deref_mut(), &mut v);
match v {
None => Poll::Pending,
Some(x) => Poll::Ready(x),}}}
Is there anything dangerous I should be aware of regarding the above code?
The intended usage is that this is a Future waiting for a message. When the message arrives, it'll be thrown into the RefCell<Option<T>>, and the poll call will return Ready. Until then, it will return Pending.
If you write impl Future for yourself, it's you who need to notify the runtime that some event is happened and the poll should be called. Good runtimes don't busy-poll its tasks as it would overly consume the CPU resource. Instead, each impl Future notify the runtime using wakers obtained via cx.waker().clone() when some event happens which potentially advance the future's state.
Side note: if you only take and set the value, Cell<Option<T>> would be better than the RefCell. Also, it's generally a good idea to run cargo fmt once before sharing some code.
This is not necessarily a problem; it's fine for futures to be !Sync. (A multi-threaded executor might work only with Sync futures, but single-threaded executors do exist and shouldn't need that constraint.)
Conceptually, yes. But you may need to split the waker from the impl Future part since the future should be owned by the .await caller while the waker may need to be owned by some external callback mechanism, or the sender.
Hmm, 'split' may not be a sufficient description. Usually this kind of constructs are implemented as separate Sender and Receiver structs and some Inner struct shared between them using refcounts. You can check the structure of the oneshot channel implementation of the futures crate, but since you don't need thread-safety actual implementation can be much simpler.