Skip to content

Instantly share code, notes, and snippets.

@ubnt-intrepid
Created October 16, 2019 18:03
Show Gist options
  • Select an option

  • Save ubnt-intrepid/cc04010953d1958f0878372e13e85edf to your computer and use it in GitHub Desktop.

Select an option

Save ubnt-intrepid/cc04010953d1958f0878372e13e85edf to your computer and use it in GitHub Desktop.
struct Select<A, B>(Option<(A, B)>);
impl<A:Future, B:Future> Future for Select<A, B> {
type Output = Either<(A::Output, B), (A, B::Output)>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
// omit
}
}
impl<A, B> Drop for Select<A, B> {
fn drop(&mut self) {
// async context の外にいるときの dtor
//
// poll が一度も呼び出されていないか、Readyを返した後の状態になる?
if let Some((a, b)) = &mut self.0 {
unsafe {
ptr::drop_in_place(a);
ptr::drop_in_place(b);
}
}
}
fn poll_drop(self: Pin<&mut Self>, cx: &mut Context) -> Poll<()> {
// async context 内にいるときの非同期 dtor
//
// drop とは異なり、タスクの完了・未完了に関わらず任意のタイミングで呼ばれる可能性がある(多分)
let this = unsafe { self.get_unchecked_mut() };
if let Some((a, b)) = &mut this.0 {
ready!(unsafe { Pin::new_unchecked(a) }.poll_drop(cx));
ready!(unsafe { Pin::new_unchecked(b) }.poll_drop(cx));
}
Poll::Ready(())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment