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