1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use std::future::Future;
use std::io;
use std::mem::ManuallyDrop;
use std::pin::Pin;
use std::task::{Context, Poll};
use futures_core::ready;
use crate::{Event, Drive, Ring};
pub struct Submission<E: Event, D: Drive> {
ring: Ring<D>,
event: Option<ManuallyDrop<E>>,
}
impl<E: Event, D: Drive> Submission<E, D> {
pub fn new(event: E, driver: D) -> Submission<E, D> {
Submission {
ring: Ring::new(driver),
event: Some(ManuallyDrop::new(event)),
}
}
pub fn driver(&self) -> &D {
self.ring.driver()
}
fn split(self: Pin<&mut Self>) -> (Pin<&mut Ring<D>>, &mut Option<ManuallyDrop<E>>) {
unsafe {
let this = Pin::get_unchecked_mut(self);
(Pin::new_unchecked(&mut this.ring), &mut this.event)
}
}
}
impl<E, D> Future for Submission<E, D> where
E: Event,
D: Drive,
{
type Output = (E, io::Result<usize>);
fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
let (ring, event) = self.split();
let result = if let Some(event) = event {
ready!(ring.poll(ctx, event.is_eager(), |sqe| unsafe { event.prepare(sqe) }))
} else {
panic!("polled Submission after completion")
};
Poll::Ready((ManuallyDrop::into_inner(event.take().unwrap()), result))
}
}
impl<E: Event, D: Drive> Drop for Submission<E, D> {
fn drop(&mut self) {
if let Some(event) = &mut self.event {
let cancellation = unsafe { Event::cancel(event) };
self.ring.cancel(cancellation);
}
}
}