/rust/registry/src/index.crates.io-1949cf8c6b5b557f/mio-1.0.3/src/event/event.rs
Line | Count | Source |
1 | | use crate::{sys, Token}; |
2 | | |
3 | | use std::fmt; |
4 | | |
5 | | /// A readiness event. |
6 | | /// |
7 | | /// `Event` is a readiness state paired with a [`Token`]. It is returned by |
8 | | /// [`Poll::poll`]. |
9 | | /// |
10 | | /// For more documentation on polling and events, see [`Poll`]. |
11 | | /// |
12 | | /// [`Poll::poll`]: ../struct.Poll.html#method.poll |
13 | | /// [`Poll`]: ../struct.Poll.html |
14 | | /// [`Token`]: ../struct.Token.html |
15 | | #[derive(Clone)] |
16 | | #[repr(transparent)] |
17 | | pub struct Event { |
18 | | inner: sys::Event, |
19 | | } |
20 | | |
21 | | impl Event { |
22 | | /// Returns the event's token. |
23 | 0 | pub fn token(&self) -> Token { |
24 | 0 | sys::event::token(&self.inner) |
25 | 0 | } |
26 | | |
27 | | /// Returns true if the event contains readable readiness. |
28 | | /// |
29 | | /// # Notes |
30 | | /// |
31 | | /// Out-of-band (OOB) data also triggers readable events. But most |
32 | | /// applications don't actually read OOB data, this could leave an |
33 | | /// application open to a Denial-of-Service (Dos) attack, see |
34 | | /// <https://github.com/sandstorm-io/sandstorm-website/blob/58f93346028c0576e8147627667328eaaf4be9fa/_posts/2015-04-08-osx-security-bug.md>. |
35 | | /// However because Mio uses edge-triggers it will not result in an infinite |
36 | | /// loop as described in the article above. |
37 | 0 | pub fn is_readable(&self) -> bool { |
38 | 0 | sys::event::is_readable(&self.inner) |
39 | 0 | } |
40 | | |
41 | | /// Returns true if the event contains writable readiness. |
42 | 0 | pub fn is_writable(&self) -> bool { |
43 | 0 | sys::event::is_writable(&self.inner) |
44 | 0 | } |
45 | | |
46 | | /// Returns true if the event contains error readiness. |
47 | | /// |
48 | | /// Error events occur when the socket enters an error state. In this case, |
49 | | /// the socket will also receive a readable or writable event. Reading or |
50 | | /// writing to the socket will result in an error. |
51 | | /// |
52 | | /// # Notes |
53 | | /// |
54 | | /// Method is available on all platforms, but not all platforms trigger the |
55 | | /// error event. |
56 | | /// |
57 | | /// The table below shows what flags are checked on what OS. |
58 | | /// |
59 | | /// | [OS selector] | Flag(s) checked | |
60 | | /// |---------------|-----------------| |
61 | | /// | [epoll] | `EPOLLERR` | |
62 | | /// | [kqueue] | `EV_ERROR` and `EV_EOF` with `fflags` set to `0`. | |
63 | | /// |
64 | | /// [OS selector]: ../struct.Poll.html#implementation-notes |
65 | | /// [epoll]: https://man7.org/linux/man-pages/man7/epoll.7.html |
66 | | /// [kqueue]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 |
67 | 0 | pub fn is_error(&self) -> bool { |
68 | 0 | sys::event::is_error(&self.inner) |
69 | 0 | } |
70 | | |
71 | | /// Returns true if the event contains read closed readiness. |
72 | | /// |
73 | | /// # Notes |
74 | | /// |
75 | | /// Read closed readiness can be expected after any of the following have |
76 | | /// occurred: |
77 | | /// * The local stream has shutdown the read half of its socket |
78 | | /// * The local stream has shutdown both the read half and the write half |
79 | | /// of its socket |
80 | | /// * The peer stream has shutdown the write half its socket; this sends a |
81 | | /// `FIN` packet that has been received by the local stream |
82 | | /// |
83 | | /// Method is a best effort implementation. While some platforms may not |
84 | | /// return readiness when read half is closed, it is guaranteed that |
85 | | /// false-positives will not occur. |
86 | | /// |
87 | | /// The table below shows what flags are checked on what OS. |
88 | | /// |
89 | | /// | [OS selector] | Flag(s) checked | |
90 | | /// |---------------|-----------------| |
91 | | /// | [epoll] | `EPOLLHUP`, or | |
92 | | /// | | `EPOLLIN` and `EPOLLRDHUP` | |
93 | | /// | [kqueue] | `EV_EOF` | |
94 | | /// |
95 | | /// [OS selector]: ../struct.Poll.html#implementation-notes |
96 | | /// [epoll]: https://man7.org/linux/man-pages/man7/epoll.7.html |
97 | | /// [kqueue]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 |
98 | 0 | pub fn is_read_closed(&self) -> bool { |
99 | 0 | sys::event::is_read_closed(&self.inner) |
100 | 0 | } |
101 | | |
102 | | /// Returns true if the event contains write closed readiness. |
103 | | /// |
104 | | /// # Notes |
105 | | /// |
106 | | /// On [epoll] this is essentially a check for `EPOLLHUP` flag as the |
107 | | /// local stream shutting down its write half does not trigger this event. |
108 | | /// |
109 | | /// On [kqueue] the local stream shutting down the write half of its |
110 | | /// socket will trigger this event. |
111 | | /// |
112 | | /// Method is a best effort implementation. While some platforms may not |
113 | | /// return readiness when write half is closed, it is guaranteed that |
114 | | /// false-positives will not occur. |
115 | | /// |
116 | | /// The table below shows what flags are checked on what OS. |
117 | | /// |
118 | | /// | [OS selector] | Flag(s) checked | |
119 | | /// |---------------|-----------------| |
120 | | /// | [epoll] | `EPOLLHUP`, or | |
121 | | /// | | only `EPOLLERR`, or | |
122 | | /// | | `EPOLLOUT` and `EPOLLERR` | |
123 | | /// | [kqueue] | `EV_EOF` | |
124 | | /// |
125 | | /// [OS selector]: ../struct.Poll.html#implementation-notes |
126 | | /// [epoll]: https://man7.org/linux/man-pages/man7/epoll.7.html |
127 | | /// [kqueue]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 |
128 | 0 | pub fn is_write_closed(&self) -> bool { |
129 | 0 | sys::event::is_write_closed(&self.inner) |
130 | 0 | } |
131 | | |
132 | | /// Returns true if the event contains priority readiness. |
133 | | /// |
134 | | /// # Notes |
135 | | /// |
136 | | /// Method is available on all platforms, but not all platforms trigger the |
137 | | /// priority event. |
138 | | /// |
139 | | /// The table below shows what flags are checked on what OS. |
140 | | /// |
141 | | /// | [OS selector] | Flag(s) checked | |
142 | | /// |---------------|-----------------| |
143 | | /// | [epoll] | `EPOLLPRI` | |
144 | | /// | [kqueue] | *Not supported* | |
145 | | /// |
146 | | /// [OS selector]: ../struct.Poll.html#implementation-notes |
147 | | /// [epoll]: https://man7.org/linux/man-pages/man7/epoll.7.html |
148 | | /// [kqueue]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 |
149 | | #[inline] |
150 | 0 | pub fn is_priority(&self) -> bool { |
151 | 0 | sys::event::is_priority(&self.inner) |
152 | 0 | } Unexecuted instantiation: <mio::event::event::Event>::is_priority Unexecuted instantiation: <mio::event::event::Event>::is_priority |
153 | | |
154 | | /// Returns true if the event contains AIO readiness. |
155 | | /// |
156 | | /// # Notes |
157 | | /// |
158 | | /// Method is available on all platforms, but not all platforms support AIO. |
159 | | /// |
160 | | /// The table below shows what flags are checked on what OS. |
161 | | /// |
162 | | /// | [OS selector] | Flag(s) checked | |
163 | | /// |---------------|-----------------| |
164 | | /// | [epoll] | *Not supported* | |
165 | | /// | [kqueue]<sup>1</sup> | `EVFILT_AIO` | |
166 | | /// |
167 | | /// 1: Only supported on DragonFly BSD, FreeBSD, iOS and macOS. |
168 | | /// |
169 | | /// [OS selector]: ../struct.Poll.html#implementation-notes |
170 | | /// [epoll]: https://man7.org/linux/man-pages/man7/epoll.7.html |
171 | | /// [kqueue]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 |
172 | 0 | pub fn is_aio(&self) -> bool { |
173 | 0 | sys::event::is_aio(&self.inner) |
174 | 0 | } |
175 | | |
176 | | /// Returns true if the event contains LIO readiness. |
177 | | /// |
178 | | /// # Notes |
179 | | /// |
180 | | /// Method is available on all platforms, but only FreeBSD supports LIO. On |
181 | | /// FreeBSD this method checks the `EVFILT_LIO` flag. |
182 | 0 | pub fn is_lio(&self) -> bool { |
183 | 0 | sys::event::is_lio(&self.inner) |
184 | 0 | } |
185 | | |
186 | | /// Create a reference to an `Event` from a platform specific event. |
187 | 0 | pub(crate) fn from_sys_event_ref(sys_event: &sys::Event) -> &Event { |
188 | | unsafe { |
189 | | // This is safe because the memory layout of `Event` is |
190 | | // the same as `sys::Event` due to the `repr(transparent)` attribute. |
191 | 0 | &*(sys_event as *const sys::Event as *const Event) |
192 | | } |
193 | 0 | } |
194 | | } |
195 | | |
196 | | /// When the [alternate] flag is enabled this will print platform specific |
197 | | /// details, for example the fields of the `kevent` structure on platforms that |
198 | | /// use `kqueue(2)`. Note however that the output of this implementation is |
199 | | /// **not** consider a part of the stable API. |
200 | | /// |
201 | | /// [alternate]: fmt::Formatter::alternate |
202 | | impl fmt::Debug for Event { |
203 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
204 | 0 | let alternate = f.alternate(); |
205 | 0 | let mut d = f.debug_struct("Event"); |
206 | 0 | d.field("token", &self.token()) |
207 | 0 | .field("readable", &self.is_readable()) |
208 | 0 | .field("writable", &self.is_writable()) |
209 | 0 | .field("error", &self.is_error()) |
210 | 0 | .field("read_closed", &self.is_read_closed()) |
211 | 0 | .field("write_closed", &self.is_write_closed()) |
212 | 0 | .field("priority", &self.is_priority()) |
213 | 0 | .field("aio", &self.is_aio()) |
214 | 0 | .field("lio", &self.is_lio()); |
215 | | |
216 | 0 | if alternate { |
217 | | struct EventDetails<'a>(&'a sys::Event); |
218 | | |
219 | | impl<'a> fmt::Debug for EventDetails<'a> { |
220 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
221 | 0 | sys::event::debug_details(f, self.0) |
222 | 0 | } |
223 | | } |
224 | | |
225 | 0 | d.field("details", &EventDetails(&self.inner)).finish() |
226 | | } else { |
227 | 0 | d.finish() |
228 | | } |
229 | 0 | } |
230 | | } |