1 use std::fmt;
2 
3 use miow::iocp::CompletionStatus;
4 
5 use super::afd;
6 use crate::Token;
7 
8 #[derive(Clone)]
9 pub struct Event {
10     pub flags: u32,
11     pub data: u64,
12 }
13 
token(event: &Event) -> Token14 pub fn token(event: &Event) -> Token {
15     Token(event.data as usize)
16 }
17 
18 impl Event {
new(token: Token) -> Event19     pub(super) fn new(token: Token) -> Event {
20         Event {
21             flags: 0,
22             data: usize::from(token) as u64,
23         }
24     }
25 
set_readable(&mut self)26     pub(super) fn set_readable(&mut self) {
27         self.flags |= afd::POLL_RECEIVE
28     }
29 
30     #[cfg(feature = "os-ext")]
set_writable(&mut self)31     pub(super) fn set_writable(&mut self) {
32         self.flags |= afd::POLL_SEND;
33     }
34 
from_completion_status(status: &CompletionStatus) -> Event35     pub(super) fn from_completion_status(status: &CompletionStatus) -> Event {
36         Event {
37             flags: status.bytes_transferred(),
38             data: status.token() as u64,
39         }
40     }
41 
to_completion_status(&self) -> CompletionStatus42     pub(super) fn to_completion_status(&self) -> CompletionStatus {
43         CompletionStatus::new(self.flags, self.data as usize, std::ptr::null_mut())
44     }
45 }
46 
47 pub(crate) const READABLE_FLAGS: u32 = afd::POLL_RECEIVE
48     | afd::POLL_DISCONNECT
49     | afd::POLL_ACCEPT
50     | afd::POLL_ABORT
51     | afd::POLL_CONNECT_FAIL;
52 pub(crate) const WRITABLE_FLAGS: u32 = afd::POLL_SEND | afd::POLL_ABORT | afd::POLL_CONNECT_FAIL;
53 pub(crate) const ERROR_FLAGS: u32 = afd::POLL_CONNECT_FAIL;
54 pub(crate) const READ_CLOSED_FLAGS: u32 =
55     afd::POLL_DISCONNECT | afd::POLL_ABORT | afd::POLL_CONNECT_FAIL;
56 pub(crate) const WRITE_CLOSED_FLAGS: u32 = afd::POLL_ABORT | afd::POLL_CONNECT_FAIL;
57 
is_readable(event: &Event) -> bool58 pub fn is_readable(event: &Event) -> bool {
59     event.flags & READABLE_FLAGS != 0
60 }
61 
is_writable(event: &Event) -> bool62 pub fn is_writable(event: &Event) -> bool {
63     event.flags & WRITABLE_FLAGS != 0
64 }
65 
is_error(event: &Event) -> bool66 pub fn is_error(event: &Event) -> bool {
67     event.flags & ERROR_FLAGS != 0
68 }
69 
is_read_closed(event: &Event) -> bool70 pub fn is_read_closed(event: &Event) -> bool {
71     event.flags & READ_CLOSED_FLAGS != 0
72 }
73 
is_write_closed(event: &Event) -> bool74 pub fn is_write_closed(event: &Event) -> bool {
75     event.flags & WRITE_CLOSED_FLAGS != 0
76 }
77 
is_priority(event: &Event) -> bool78 pub fn is_priority(event: &Event) -> bool {
79     event.flags & afd::POLL_RECEIVE_EXPEDITED != 0
80 }
81 
is_aio(_: &Event) -> bool82 pub fn is_aio(_: &Event) -> bool {
83     // Not supported.
84     false
85 }
86 
is_lio(_: &Event) -> bool87 pub fn is_lio(_: &Event) -> bool {
88     // Not supported.
89     false
90 }
91 
debug_details(f: &mut fmt::Formatter<'_>, event: &Event) -> fmt::Result92 pub fn debug_details(f: &mut fmt::Formatter<'_>, event: &Event) -> fmt::Result {
93     #[allow(clippy::trivially_copy_pass_by_ref)]
94     fn check_flags(got: &u32, want: &u32) -> bool {
95         (got & want) != 0
96     }
97     debug_detail!(
98         FlagsDetails(u32),
99         check_flags,
100         afd::POLL_RECEIVE,
101         afd::POLL_RECEIVE_EXPEDITED,
102         afd::POLL_SEND,
103         afd::POLL_DISCONNECT,
104         afd::POLL_ABORT,
105         afd::POLL_LOCAL_CLOSE,
106         afd::POLL_CONNECT,
107         afd::POLL_ACCEPT,
108         afd::POLL_CONNECT_FAIL,
109     );
110 
111     f.debug_struct("event")
112         .field("flags", &FlagsDetails(event.flags))
113         .field("data", &event.data)
114         .finish()
115 }
116 
117 pub struct Events {
118     /// Raw I/O event completions are filled in here by the call to `get_many`
119     /// on the completion port above. These are then processed to run callbacks
120     /// which figure out what to do after the event is done.
121     pub statuses: Box<[CompletionStatus]>,
122 
123     /// Literal events returned by `get` to the upwards `EventLoop`. This file
124     /// doesn't really modify this (except for the waker), instead almost all
125     /// events are filled in by the `ReadinessQueue` from the `poll` module.
126     pub events: Vec<Event>,
127 }
128 
129 impl Events {
with_capacity(cap: usize) -> Events130     pub fn with_capacity(cap: usize) -> Events {
131         // Note that it's possible for the output `events` to grow beyond the
132         // capacity as it can also include deferred events, but that's certainly
133         // not the end of the world!
134         Events {
135             statuses: vec![CompletionStatus::zero(); cap].into_boxed_slice(),
136             events: Vec::with_capacity(cap),
137         }
138     }
139 
is_empty(&self) -> bool140     pub fn is_empty(&self) -> bool {
141         self.events.is_empty()
142     }
143 
capacity(&self) -> usize144     pub fn capacity(&self) -> usize {
145         self.events.capacity()
146     }
147 
len(&self) -> usize148     pub fn len(&self) -> usize {
149         self.events.len()
150     }
151 
get(&self, idx: usize) -> Option<&Event>152     pub fn get(&self, idx: usize) -> Option<&Event> {
153         self.events.get(idx)
154     }
155 
clear(&mut self)156     pub fn clear(&mut self) {
157         self.events.clear();
158         for status in self.statuses.iter_mut() {
159             *status = CompletionStatus::zero();
160         }
161     }
162 }
163