1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::fmt;
15 
16 use crate::sys::windows::afd::{
17     POLL_ABORT, POLL_ACCEPT, POLL_CONNECT_FAIL, POLL_DISCONNECT, POLL_RECEIVE, POLL_SEND,
18 };
19 use crate::sys::windows::iocp::CompletionStatus;
20 use crate::{EventTrait, Token};
21 
22 /// An io event
23 #[derive(Debug)]
24 pub struct Event {
25     pub(crate) flags: u32,
26     pub(crate) data: u64,
27 }
28 
29 impl Event {
30     /// Creates a new `Event` with `Token`.
new(token: Token) -> Event31     pub(crate) fn new(token: Token) -> Event {
32         Event {
33             flags: 0,
34             data: usize::from(token) as u64,
35         }
36     }
37 
38     /// Sets `Event` as readable.
set_readable(&mut self)39     pub(super) fn set_readable(&mut self) {
40         self.flags |= POLL_RECEIVE
41     }
42 
43     /// Converts `Event` to `CompletionStatus`.
as_completion_status(&self) -> CompletionStatus44     pub(super) fn as_completion_status(&self) -> CompletionStatus {
45         CompletionStatus::new(self.flags, self.data as usize, std::ptr::null_mut())
46     }
47 
48     /// Converts `CompletionStatus` to `Event`.
from_completion_status(status: &CompletionStatus) -> Event49     pub(super) fn from_completion_status(status: &CompletionStatus) -> Event {
50         Event {
51             flags: status.bytes_transferred(),
52             data: status.token() as u64,
53         }
54     }
55 }
56 
57 /// Storage completed events
58 pub struct Events {
59     pub(crate) status: Box<[CompletionStatus]>,
60     pub(crate) events: Vec<Event>,
61 }
62 
63 impl Events {
64     /// Creates a new `Events`.
with_capacity(cap: usize) -> Events65     pub fn with_capacity(cap: usize) -> Events {
66         Events {
67             status: vec![CompletionStatus::zero(); cap].into_boxed_slice(),
68             events: Vec::with_capacity(cap),
69         }
70     }
71 
72     /// Clear the Events
clear(&mut self)73     pub fn clear(&mut self) {
74         self.events.clear();
75         for status in self.status.iter_mut() {
76             *status = CompletionStatus::zero();
77         }
78     }
79 
80     /// Returns an iterator over the slice.
81     /// The iterator yields all items from start to end.
iter(&self) -> IterEvent82     pub fn iter(&self) -> IterEvent {
83         IterEvent {
84             iter: &self.events,
85             index: 0,
86         }
87     }
88 
89     /// Returns true if the vector contains no elements.
is_empty(&self) -> bool90     pub fn is_empty(&self) -> bool {
91         self.events.is_empty()
92     }
93 
94     /// Returns len of Events.
len(&self) -> usize95     pub fn len(&self) -> usize {
96         self.events.len()
97     }
98 }
99 
100 impl fmt::Debug for Events {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result101     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102         f.debug_list().entries(self).finish()
103     }
104 }
105 
106 impl<'a> IntoIterator for &'a Events {
107     type Item = &'a Event;
108     type IntoIter = IterEvent<'a>;
109 
into_iter(self) -> Self::IntoIter110     fn into_iter(self) -> Self::IntoIter {
111         self.iter()
112     }
113 }
114 
115 pub struct IterEvent<'a> {
116     iter: &'a Vec<Event>,
117     index: usize,
118 }
119 
120 impl<'a> Iterator for IterEvent<'a> {
121     type Item = &'a Event;
next(&mut self) -> Option<Self::Item>122     fn next(&mut self) -> Option<Self::Item> {
123         if self.index < self.iter.len() {
124             self.index += 1;
125             Some(&self.iter[self.index - 1])
126         } else {
127             None
128         }
129     }
130 
count(self) -> usize131     fn count(self) -> usize {
132         self.iter.len()
133     }
134 }
135 
136 pub(crate) const READABLE_FLAGS: u32 =
137     POLL_RECEIVE | POLL_DISCONNECT | POLL_ABORT | POLL_ACCEPT | POLL_CONNECT_FAIL;
138 pub(crate) const WRITABLE_FLAGS: u32 = POLL_SEND | POLL_ABORT | POLL_CONNECT_FAIL;
139 pub(crate) const READ_CLOSED_FLAGS: u32 = POLL_DISCONNECT | POLL_ABORT | POLL_CONNECT_FAIL;
140 pub(crate) const WRITE_CLOSED_FLAGS: u32 = POLL_ABORT | POLL_CONNECT_FAIL;
141 pub(crate) const ERROR_FLAGS: u32 = POLL_CONNECT_FAIL;
142 
143 impl EventTrait for Event {
token(&self) -> Token144     fn token(&self) -> Token {
145         Token(self.data as usize)
146     }
147 
is_readable(&self) -> bool148     fn is_readable(&self) -> bool {
149         self.flags & READABLE_FLAGS != 0
150     }
151 
is_writable(&self) -> bool152     fn is_writable(&self) -> bool {
153         (self.flags & WRITABLE_FLAGS) != 0
154     }
155 
is_read_closed(&self) -> bool156     fn is_read_closed(&self) -> bool {
157         self.flags & READ_CLOSED_FLAGS != 0
158     }
159 
is_write_closed(&self) -> bool160     fn is_write_closed(&self) -> bool {
161         self.flags & WRITE_CLOSED_FLAGS != 0
162     }
163 
is_error(&self) -> bool164     fn is_error(&self) -> bool {
165         self.flags & ERROR_FLAGS != 0
166     }
167 }
168