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 core::ops;
15
16 use ylong_io::Interest;
17
18 const READABLE: usize = 0b0_01;
19 const WRITABLE: usize = 0b0_10;
20 const READ_CLOSED: usize = 0b0_0100;
21 const WRITE_CLOSED: usize = 0b0_1000;
22
23 cfg_not_ffrt! {
24 use ylong_io::{Event, EventTrait};
25 }
26
27 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)]
28 pub struct Ready(usize);
29
30 #[derive(Debug)]
31 pub(crate) struct ReadyEvent {
32 tick: u8,
33 pub(crate) ready: Ready,
34 }
35
36 impl Ready {
37 pub const EMPTY: Ready = Ready(0);
38
39 pub const READABLE: Ready = Ready(READABLE);
40
41 pub const WRITABLE: Ready = Ready(WRITABLE);
42
43 pub const READ_CLOSED: Ready = Ready(READ_CLOSED);
44
45 pub const WRITE_CLOSED: Ready = Ready(WRITE_CLOSED);
46
47 pub const ALL: Ready = Ready(READABLE | WRITABLE | READ_CLOSED | WRITE_CLOSED);
48
49 #[cfg(not(feature = "ffrt"))]
from_event(event: &Event) -> Ready50 pub(crate) fn from_event(event: &Event) -> Ready {
51 let mut ready = Ready::EMPTY;
52
53 if event.is_readable() {
54 ready |= Ready::READABLE;
55 }
56
57 if event.is_writable() {
58 ready |= Ready::WRITABLE;
59 }
60
61 if event.is_read_closed() {
62 ready |= Ready::READ_CLOSED;
63 }
64
65 if event.is_write_closed() {
66 ready |= Ready::WRITE_CLOSED;
67 }
68 ready
69 }
70
is_empty(self) -> bool71 pub fn is_empty(self) -> bool {
72 self == Ready::EMPTY
73 }
74
is_readable(self) -> bool75 pub fn is_readable(self) -> bool {
76 (self & Ready::READABLE).0 != 0 || self.is_read_closed()
77 }
78
is_writable(self) -> bool79 pub fn is_writable(self) -> bool {
80 (self & Ready::WRITABLE).0 != 0 || self.is_write_closed()
81 }
82
is_read_closed(self) -> bool83 pub fn is_read_closed(self) -> bool {
84 (self & Ready::READ_CLOSED).0 != 0
85 }
86
is_write_closed(self) -> bool87 pub fn is_write_closed(self) -> bool {
88 (self & Ready::WRITE_CLOSED).0 != 0
89 }
90
from_usize(val: usize) -> Ready91 pub(crate) fn from_usize(val: usize) -> Ready {
92 Ready(val & Ready::ALL.as_usize())
93 }
94
as_usize(self) -> usize95 pub(crate) fn as_usize(self) -> usize {
96 self.0
97 }
98
from_interest(interest: Interest) -> Ready99 pub(crate) fn from_interest(interest: Interest) -> Ready {
100 let mut ready = Ready::EMPTY;
101
102 if interest.is_readable() {
103 ready |= Ready::READABLE;
104 ready |= Ready::READ_CLOSED;
105 }
106
107 if interest.is_writable() {
108 ready |= Ready::WRITABLE;
109 ready |= Ready::WRITE_CLOSED;
110 }
111
112 ready
113 }
114
intersection(self, interest: Interest) -> Ready115 pub(crate) fn intersection(self, interest: Interest) -> Ready {
116 Ready(self.0 & Ready::from_interest(interest).0)
117 }
118
satisfies(self, interest: Interest) -> bool119 pub(crate) fn satisfies(self, interest: Interest) -> bool {
120 self.0 & Ready::from_interest(interest).0 != 0
121 }
122 }
123
124 impl ops::BitOr<Ready> for Ready {
125 type Output = Ready;
126
127 #[inline]
bitor(self, other: Ready) -> Self::Output128 fn bitor(self, other: Ready) -> Self::Output {
129 Ready(self.0 | other.0)
130 }
131 }
132
133 impl ops::BitOrAssign<Ready> for Ready {
134 #[inline]
bitor_assign(&mut self, other: Ready)135 fn bitor_assign(&mut self, other: Ready) {
136 self.0 |= other.0
137 }
138 }
139
140 impl ops::BitAnd<Ready> for Ready {
141 type Output = Ready;
142
143 #[inline]
bitand(self, other: Ready) -> Self::Output144 fn bitand(self, other: Ready) -> Self::Output {
145 Ready(self.0 & other.0)
146 }
147 }
148
149 impl ops::Sub<Ready> for Ready {
150 type Output = Ready;
151
152 #[inline]
sub(self, other: Ready) -> Self::Output153 fn sub(self, other: Ready) -> Self::Output {
154 Ready(self.0 & !other.0)
155 }
156 }
157
158 impl ReadyEvent {
new(tick: u8, ready: Ready) -> Self159 pub fn new(tick: u8, ready: Ready) -> Self {
160 ReadyEvent { tick, ready }
161 }
162
get_tick(&self) -> u8163 pub fn get_tick(&self) -> u8 {
164 self.tick
165 }
166
get_ready(&self) -> Ready167 pub fn get_ready(&self) -> Ready {
168 self.ready
169 }
170 }
171
172 cfg_ffrt! {
173 fn is_readable(event: i32) -> bool {
174 (event as libc::c_int & libc::EPOLLIN) != 0
175 || (event as libc::c_int & libc::EPOLLPRI) != 0
176 }
177
178 fn is_writable(event: i32) -> bool {
179 (event as libc::c_int & libc::EPOLLOUT) != 0
180 }
181
182 fn is_read_closed(event: i32) -> bool {
183 event as libc::c_int & libc::EPOLLHUP != 0
184 || (event as libc::c_int & libc::EPOLLIN != 0
185 && event as libc::c_int & libc::EPOLLRDHUP != 0)
186 }
187
188 fn is_write_closed(event: i32) -> bool {
189 event as libc::c_int & libc::EPOLLHUP != 0
190 || (event as libc::c_int & libc::EPOLLOUT != 0
191 && event as libc::c_int & libc::EPOLLERR != 0)
192 || event as libc::c_int == libc::EPOLLERR
193 }
194
195 pub(crate) fn from_event_inner(event: i32) -> Ready {
196 let mut ready = Ready::EMPTY;
197 if is_readable(event) {
198 ready |= Ready::READABLE;
199 }
200
201 if is_writable(event) {
202 ready |= Ready::WRITABLE;
203 }
204
205 if is_read_closed(event) {
206 ready |= Ready::READ_CLOSED;
207 }
208
209 if is_write_closed(event) {
210 ready |= Ready::WRITE_CLOSED;
211 }
212 ready
213 }
214 }
215
216 // @title ready from_event function ut test
217 // @design conditions of use override
218 // @precon none
219 // @brief 1. Create an event
220 // 2. Call from_event
221 // 3. Verify the returned results
222 // @expect 1. Event readable to get readable Ready instances
223 // 2. Event writable, call writable Ready instances
224 // 3. Event Read Close, Call Read Close Ready Instance
225 // 4. Event Write Close, Call Write Close Ready Instance
226 // @auto Yes
227 #[test]
228 #[cfg(feature = "tcp")]
ut_ready_from_event()229 fn ut_ready_from_event() {
230 ut_ready_from_event_01();
231 ut_ready_from_event_02();
232 ut_ready_from_event_03();
233 ut_ready_from_event_04();
234
235 // Readable
236 fn ut_ready_from_event_01() {
237 let mut event = libc::epoll_event {
238 events: 0b00,
239 u64: 0,
240 };
241 event.events |= libc::EPOLLIN as u32;
242 let ready = Ready::from_event(&event);
243 assert_eq!(ready.0, 0b01);
244 }
245
246 // Writable
247 fn ut_ready_from_event_02() {
248 let mut event = libc::epoll_event {
249 events: 0b00,
250 u64: 0,
251 };
252 event.events |= libc::EPOLLOUT as u32;
253 let ready = Ready::from_event(&event);
254 assert_eq!(ready.0, 0b10);
255 }
256
257 // Read off
258 fn ut_ready_from_event_03() {
259 let mut event = libc::epoll_event {
260 events: 0b00,
261 u64: 0,
262 };
263 event.events |= (libc::EPOLLIN | libc::EPOLLRDHUP) as u32;
264 let ready = Ready::from_event(&event);
265 assert_eq!(ready.0, 0b101);
266 }
267
268 // Write Off
269 fn ut_ready_from_event_04() {
270 let mut event = libc::epoll_event {
271 events: 0x00,
272 u64: 0,
273 };
274 event.events |= (libc::EPOLLOUT | libc::EPOLLERR) as u32;
275 let ready = Ready::from_event(&event);
276 assert_eq!(ready.0, 0b1010);
277 }
278 }
279
280 /// UT test cases for ready from_usize function
281 ///
282 /// # Brief
283 /// 1. Enter a usize, call from_usize
284 /// 2. Verify the returned results
285 #[test]
ut_ready_from_usize()286 fn ut_ready_from_usize() {
287 let ready = Ready::from_usize(0x01);
288 assert_eq!(ready.0, 0x01);
289 }
290
291 /// UT test cases for ready is_empty function
292 ///
293 /// # Brief
294 /// 1. Create a Ready
295 /// 2. Call is_empty
296 /// 3. Verify the returned results
297 #[test]
ut_ready_is_empty()298 fn ut_ready_is_empty() {
299 let ready = Ready::from_usize(0x00);
300 assert!(ready.is_empty());
301
302 let ready = Ready::from_usize(0x01);
303 assert!(!ready.is_empty());
304 }
305
306 /// UT test cases for ready is_readable function
307 ///
308 /// # Brief
309 /// 1. Create a Ready
310 /// 2. Call is_readable
311 /// 3. Verify the returned results
312 #[test]
ut_ready_is_readable()313 fn ut_ready_is_readable() {
314 let ready = Ready::from_usize(0x01);
315 assert!(ready.is_readable());
316
317 let ready = Ready::from_usize(0x02);
318 assert!(!ready.is_readable());
319 }
320
321 /// UT test cases for ready is_writable function
322 ///
323 /// # Brief
324 /// 1. Create a Ready
325 /// 2. Call is_writable
326 /// 3. Verify the returned results
327 #[test]
ut_ready_is_writable()328 fn ut_ready_is_writable() {
329 let ready = Ready::from_usize(0x02);
330 assert!(ready.is_writable());
331
332 let ready = Ready::from_usize(0x01);
333 assert!(!ready.is_writable());
334 }
335
336 /// UT test cases for ready is_read_closed function
337 ///
338 /// # Brief
339 /// 1. Create a Ready
340 /// 2. Call is_read_closed
341 /// 3. Verify the returned results
342 #[test]
ut_ready_is_read_closed()343 fn ut_ready_is_read_closed() {
344 let ready = Ready::from_usize(0x04);
345 assert!(ready.is_read_closed());
346
347 let ready = Ready::from_usize(0x01);
348 assert!(!ready.is_read_closed());
349 }
350
351 /// UT test cases for ready is_write_closed function
352 ///
353 /// # Brief
354 /// 1. Create a Ready
355 /// 2. Call is_write_closed
356 /// 3. Verify the returned results
357 #[test]
ut_ready_is_write_closed()358 fn ut_ready_is_write_closed() {
359 let ready = Ready::from_usize(0x08);
360 assert!(ready.is_write_closed());
361
362 let ready = Ready::from_usize(0x01);
363 assert!(!ready.is_write_closed());
364 }
365
366 /// UT test cases for ready as_usize function
367 ///
368 /// # Brief
369 /// 1. Create a Ready
370 /// 2. Call as_usize
371 /// 3. Verify the returned results
372 #[test]
ut_ready_as_usize()373 fn ut_ready_as_usize() {
374 let ready = Ready::from_usize(0x08);
375 assert_eq!(ready.as_usize(), 0x08);
376 }
377
378 /// UT test cases for ready from_interest function
379 ///
380 /// # Brief
381 /// 1. Create a Interest instances
382 /// 2. Call from_interest
383 /// 3. Verify the returned results
384 #[test]
ut_ready_from_interest()385 fn ut_ready_from_interest() {
386 let interest = Interest::READABLE;
387 let ready = Ready::from_interest(interest);
388 assert_eq!(ready.as_usize(), 0b101);
389
390 let interest = Interest::WRITABLE;
391 let ready = Ready::from_interest(interest);
392 assert_eq!(ready.as_usize(), 0b1010);
393 }
394
395 /// UT test cases for ready intersection function
396 ///
397 /// # Brief
398 /// 1. Create a Interest instances and a Ready instances
399 /// 2. Call intersection
400 /// 3. Verify the returned results
401 #[test]
ut_ready_intersection()402 fn ut_ready_intersection() {
403 let interest = Interest::READABLE;
404 let ready = Ready::from_usize(0b1111);
405 let res = ready.intersection(interest);
406 assert_eq!(res.0, 0b0101);
407 }
408
409 /// UT test cases for ready satisfies function
410 ///
411 /// # Brief
412 /// 1. Create a Interest instances, and a Ready instances
413 /// 2. Call satisfies
414 /// 3. Verify the returned results
415 #[test]
ut_ready_satisfies()416 fn ut_ready_satisfies() {
417 let interest = Interest::READABLE;
418 let ready = Ready::from_usize(0b1111);
419 assert!(ready.satisfies(interest));
420
421 let ready = Ready::from_usize(0b0000);
422 assert!(!ready.satisfies(interest));
423 }
424
425 /// UT test cases for ready bitor function
426 ///
427 /// # Brief
428 /// 1. Create two Ready instances
429 /// 2. Call bitor or use | logical operators
430 /// 3. Verify the returned results
431 #[test]
ut_ready_bitor()432 fn ut_ready_bitor() {
433 let ready1 = Ready::from_usize(0b1010);
434 let ready2 = Ready::from_usize(0b0101);
435 let ready3 = ready1 | ready2;
436 assert_eq!(ready3.0, 0b1111);
437 }
438
439 /// UT test cases for ready bitor_assign function
440 ///
441 /// # Brief
442 /// 1. Create two Ready instances
443 /// 2. Call bitor_assign or use |= logical operators
444 /// 3. Verify the returned results
445 #[test]
ut_ready_bitor_assign()446 fn ut_ready_bitor_assign() {
447 let mut ready1 = Ready::from_usize(0b1010);
448 let ready2 = Ready::from_usize(0b0101);
449 ready1 |= ready2;
450 assert_eq!(ready1.0, 0b1111);
451 }
452
453 /// UT test cases for ready bitand function
454 ///
455 /// # Brief
456 /// 1. Create two Ready instances
457 /// 2. Call bitand or use & logical operators
458 /// 3. Verify the returned results
459 #[test]
ut_ready_bitand()460 fn ut_ready_bitand() {
461 let ready1 = Ready::from_usize(0b1010);
462 let ready2 = Ready::from_usize(0b0101);
463 let ready = ready1 & ready2;
464 assert_eq!(ready.0, 0b0000);
465 }
466
467 /// UT test cases for ready bitsub function
468 ///
469 /// # Brief
470 /// 1. Create two Ready instances
471 /// 2. Call bitsub or use - logical operators
472 /// 3. Verify the returned results
473 #[test]
ut_ready_bitsub()474 fn ut_ready_bitsub() {
475 let ready1 = Ready::from_usize(0b1111);
476 let ready2 = Ready::from_usize(0b0101);
477 let ready = ready1 - ready2;
478 assert_eq!(ready.0, 0b1010);
479 }
480
481 /// UT test cases for ready_event new function
482 ///
483 /// # Brief
484 /// 1. Call new
485 /// 2. Verify the returned results
486 #[test]
ut_ready_event_new()487 fn ut_ready_event_new() {
488 let ready_event = ReadyEvent::new(1u8, Ready::from_usize(0b0101));
489 assert_eq!(ready_event.tick, 1u8);
490 assert_eq!(ready_event.ready.0, 0b0101);
491 }
492
493 /// UT test cases for ready_event get_tick function
494 ///
495 /// # Brief
496 /// 1. Create a ready_event
497 /// 2. Call get_tick
498 /// 3. Verify the returned results
499 #[test]
ut_ready_event_get_tick()500 fn ut_ready_event_get_tick() {
501 let ready_event = ReadyEvent::new(1u8, Ready::from_usize(0b0101));
502 assert_eq!(ready_event.get_tick(), 1u8);
503 }
504
505 /// UT test cases for ready_event get_ready function
506 ///
507 /// # Brief
508 /// 1. Create a ready_event
509 /// 2. Call get_ready
510 /// 3. Verify the returned results
511 #[test]
ut_ready_event_get_ready()512 fn ut_ready_event_get_ready() {
513 let ready_event = ReadyEvent::new(1u8, Ready::from_usize(0b0101));
514 assert_eq!(ready_event.get_ready().0, 0b0101);
515 }
516