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