1use std::mem;
2use std::mem::MaybeUninit;
3use std::ops::{Deref, DerefMut};
4use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};
5use std::slice;
6#[cfg(debug_assertions)]
7use std::sync::atomic::{AtomicUsize, Ordering};
8use std::time::Duration;
9use std::{cmp, io, ptr};
10
11use crate::Interest;
12use crate::Token;
13
14#[cfg(debug_assertions)]
16static NEXT_ID: AtomicUsize = AtomicUsize::new(1);
17
18#[cfg(not(target_os = "netbsd"))]
20type Count = libc::c_int;
21#[cfg(target_os = "netbsd")]
22type Count = libc::size_t;
23
24#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
26type Filter = libc::c_short;
27#[cfg(any(
28 target_os = "ios",
29 target_os = "macos",
30 target_os = "tvos",
31 target_os = "visionos",
32 target_os = "watchos"
33))]
34type Filter = i16;
35#[cfg(target_os = "netbsd")]
36type Filter = u32;
37
38#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
40type Flags = libc::c_ushort;
41#[cfg(any(
42 target_os = "ios",
43 target_os = "macos",
44 target_os = "tvos",
45 target_os = "visionos",
46 target_os = "watchos"
47))]
48type Flags = u16;
49#[cfg(target_os = "netbsd")]
50type Flags = u32;
51
52type UData = *mut libc::c_void;
54
55macro_rules! kevent {
56 ($id: expr, $filter: expr, $flags: expr, $data: expr) => {
57 libc::kevent {
58 ident: $id as libc::uintptr_t,
59 filter: $filter as Filter,
60 flags: $flags,
61 udata: $data as UData,
62 ..unsafe { mem::zeroed() }
63 }
64 };
65}
66
67#[derive(Debug)]
68pub struct Selector {
69 #[cfg(debug_assertions)]
70 id: usize,
71 kq: OwnedFd,
72}
73
74impl Selector {
75 pub fn new() -> io::Result<Selector> {
76 let kq = unsafe { OwnedFd::from_raw_fd(syscall!(kqueue())?) };
78 syscall!(fcntl(kq.as_raw_fd(), libc::F_SETFD, libc::FD_CLOEXEC))?;
79 Ok(Selector {
80 #[cfg(debug_assertions)]
81 id: NEXT_ID.fetch_add(1, Ordering::Relaxed),
82 kq,
83 })
84 }
85
86 pub fn try_clone(&self) -> io::Result<Selector> {
87 self.kq.try_clone().map(|kq| Selector {
88 #[cfg(debug_assertions)]
90 id: self.id,
91 kq,
92 })
93 }
94
95 pub fn select(&self, events: &mut Events, timeout: Option<Duration>) -> io::Result<()> {
96 let timeout = timeout.map(|to| libc::timespec {
97 tv_sec: cmp::min(to.as_secs(), libc::time_t::MAX as u64) as libc::time_t,
98 tv_nsec: libc::c_long::from(to.subsec_nanos() as i32),
103 });
104 let timeout = timeout
105 .as_ref()
106 .map(|s| s as *const _)
107 .unwrap_or(ptr::null_mut());
108
109 events.clear();
110 syscall!(kevent(
111 self.kq.as_raw_fd(),
112 ptr::null(),
113 0,
114 events.as_mut_ptr().cast(),
115 events.capacity() as Count,
116 timeout,
117 ))
118 .map(|n_events| {
119 unsafe { events.set_len(n_events as usize) };
122 })
123 }
124
125 #[cfg_attr(not(feature = "os-ext"), allow(dead_code))]
126 pub fn register(&self, fd: RawFd, token: Token, interests: Interest) -> io::Result<()> {
127 let flags = libc::EV_CLEAR | libc::EV_RECEIPT | libc::EV_ADD;
128 let mut changes: [MaybeUninit<libc::kevent>; 2] =
130 [MaybeUninit::uninit(), MaybeUninit::uninit()];
131 let mut n_changes = 0;
132
133 if interests.is_writable() {
134 let kevent = kevent!(fd, libc::EVFILT_WRITE, flags, token.0);
135 changes[n_changes] = MaybeUninit::new(kevent);
136 n_changes += 1;
137 }
138
139 if interests.is_readable() {
140 let kevent = kevent!(fd, libc::EVFILT_READ, flags, token.0);
141 changes[n_changes] = MaybeUninit::new(kevent);
142 n_changes += 1;
143 }
144
145 let changes = unsafe {
158 slice::from_raw_parts_mut(changes[0].as_mut_ptr(), n_changes)
161 };
162 kevent_register(self.kq.as_raw_fd(), changes, &[libc::EPIPE as i64])
163 }
164
165 cfg_any_os_ext! {
166 pub fn reregister(&self, fd: RawFd, token: Token, interests: Interest) -> io::Result<()> {
167 let flags = libc::EV_CLEAR | libc::EV_RECEIPT;
168 let write_flags = if interests.is_writable() {
169 flags | libc::EV_ADD
170 } else {
171 flags | libc::EV_DELETE
172 };
173 let read_flags = if interests.is_readable() {
174 flags | libc::EV_ADD
175 } else {
176 flags | libc::EV_DELETE
177 };
178
179 let mut changes: [libc::kevent; 2] = [
180 kevent!(fd, libc::EVFILT_WRITE, write_flags, token.0),
181 kevent!(fd, libc::EVFILT_READ, read_flags, token.0),
182 ];
183
184 kevent_register(
193 self.kq.as_raw_fd(),
194 &mut changes,
195 &[libc::ENOENT as i64, libc::EPIPE as i64],
196 )
197 }
198
199 pub fn deregister(&self, fd: RawFd) -> io::Result<()> {
200 let flags = libc::EV_DELETE | libc::EV_RECEIPT;
201 let mut changes: [libc::kevent; 2] = [
202 kevent!(fd, libc::EVFILT_WRITE, flags, 0),
203 kevent!(fd, libc::EVFILT_READ, flags, 0),
204 ];
205
206 kevent_register(self.kq.as_raw_fd(), &mut changes, &[libc::ENOENT as i64])
212 }
213 }
214
215 #[cfg(any(
217 target_os = "freebsd",
218 target_os = "ios",
219 target_os = "macos",
220 target_os = "tvos",
221 target_os = "visionos",
222 target_os = "watchos"
223 ))]
224 pub fn setup_waker(&self, token: Token) -> io::Result<()> {
225 let mut kevent = kevent!(
227 0,
228 libc::EVFILT_USER,
229 libc::EV_ADD | libc::EV_CLEAR | libc::EV_RECEIPT,
230 token.0
231 );
232
233 let kq = self.kq.as_raw_fd();
234 syscall!(kevent(kq, &kevent, 1, &mut kevent, 1, ptr::null())).and_then(|_| {
235 if (kevent.flags & libc::EV_ERROR) != 0 && kevent.data != 0 {
236 Err(io::Error::from_raw_os_error(kevent.data as i32))
237 } else {
238 Ok(())
239 }
240 })
241 }
242
243 #[cfg(any(
245 target_os = "freebsd",
246 target_os = "ios",
247 target_os = "macos",
248 target_os = "tvos",
249 target_os = "visionos",
250 target_os = "watchos"
251 ))]
252 pub fn wake(&self, token: Token) -> io::Result<()> {
253 let mut kevent = kevent!(
254 0,
255 libc::EVFILT_USER,
256 libc::EV_ADD | libc::EV_RECEIPT,
257 token.0
258 );
259 kevent.fflags = libc::NOTE_TRIGGER;
260
261 let kq = self.kq.as_raw_fd();
262 syscall!(kevent(kq, &kevent, 1, &mut kevent, 1, ptr::null())).and_then(|_| {
263 if (kevent.flags & libc::EV_ERROR) != 0 && kevent.data != 0 {
264 Err(io::Error::from_raw_os_error(kevent.data as i32))
265 } else {
266 Ok(())
267 }
268 })
269 }
270}
271
272fn kevent_register(
274 kq: RawFd,
275 changes: &mut [libc::kevent],
276 ignored_errors: &[i64],
277) -> io::Result<()> {
278 syscall!(kevent(
279 kq,
280 changes.as_ptr(),
281 changes.len() as Count,
282 changes.as_mut_ptr(),
283 changes.len() as Count,
284 ptr::null(),
285 ))
286 .map(|_| ())
287 .or_else(|err| {
288 if err.raw_os_error() == Some(libc::EINTR) {
292 Ok(())
293 } else {
294 Err(err)
295 }
296 })
297 .and_then(|()| check_errors(changes, ignored_errors))
298}
299
300fn check_errors(events: &[libc::kevent], ignored_errors: &[i64]) -> io::Result<()> {
302 for event in events {
303 let data = event.data as _;
306 if (event.flags & libc::EV_ERROR != 0) && data != 0 && !ignored_errors.contains(&data) {
309 return Err(io::Error::from_raw_os_error(data as i32));
310 }
311 }
312 Ok(())
313}
314
315cfg_io_source! {
316 #[cfg(debug_assertions)]
317 impl Selector {
318 pub fn id(&self) -> usize {
319 self.id
320 }
321 }
322}
323
324impl AsFd for Selector {
325 fn as_fd(&self) -> BorrowedFd<'_> {
326 self.kq.as_fd()
327 }
328}
329
330impl AsRawFd for Selector {
331 fn as_raw_fd(&self) -> RawFd {
332 self.kq.as_raw_fd()
333 }
334}
335
336#[repr(transparent)]
337#[derive(Clone)]
338pub struct Event(libc::kevent);
339
340unsafe impl Send for Event {}
341unsafe impl Sync for Event {}
342
343impl Deref for Event {
344 type Target = libc::kevent;
345
346 fn deref(&self) -> &Self::Target {
347 &self.0
348 }
349}
350
351impl DerefMut for Event {
352 fn deref_mut(&mut self) -> &mut Self::Target {
353 &mut self.0
354 }
355}
356
357pub struct Events(Vec<Event>);
358
359impl Deref for Events {
360 type Target = Vec<Event>;
361
362 fn deref(&self) -> &Self::Target {
363 &self.0
364 }
365}
366
367impl DerefMut for Events {
368 fn deref_mut(&mut self) -> &mut Self::Target {
369 &mut self.0
370 }
371}
372
373impl Events {
374 pub fn with_capacity(capacity: usize) -> Events {
375 Events(Vec::with_capacity(capacity))
376 }
377}
378
379unsafe impl Send for Events {}
385unsafe impl Sync for Events {}
386
387pub mod event {
388 use std::fmt;
389
390 use crate::sys::Event;
391 use crate::Token;
392
393 use super::{Filter, Flags};
394
395 pub fn token(event: &Event) -> Token {
396 Token(event.0.udata as usize)
397 }
398
399 pub fn is_readable(event: &Event) -> bool {
400 event.0.filter == libc::EVFILT_READ || {
401 #[cfg(any(
402 target_os = "freebsd",
403 target_os = "ios",
404 target_os = "macos",
405 target_os = "tvos",
406 target_os = "visionos",
407 target_os = "watchos"
408 ))]
409 {
413 event.filter == libc::EVFILT_USER
414 }
415 #[cfg(not(any(
416 target_os = "freebsd",
417 target_os = "ios",
418 target_os = "macos",
419 target_os = "tvos",
420 target_os = "visionos",
421 target_os = "watchos"
422 )))]
423 {
424 false
425 }
426 }
427 }
428
429 pub fn is_writable(event: &Event) -> bool {
430 event.0.filter == libc::EVFILT_WRITE
431 }
432
433 pub fn is_error(event: &Event) -> bool {
434 (event.0.flags & libc::EV_ERROR) != 0 ||
435 (event.0.flags & libc::EV_EOF) != 0 && event.0.fflags != 0
438 }
439
440 pub fn is_read_closed(event: &Event) -> bool {
441 event.0.filter == libc::EVFILT_READ && event.0.flags & libc::EV_EOF != 0
442 }
443
444 pub fn is_write_closed(event: &Event) -> bool {
445 event.0.filter == libc::EVFILT_WRITE && event.0.flags & libc::EV_EOF != 0
446 }
447
448 pub fn is_priority(_: &Event) -> bool {
449 false
451 }
452
453 #[allow(unused_variables)] pub fn is_aio(event: &Event) -> bool {
455 #[cfg(any(
456 target_os = "dragonfly",
457 target_os = "freebsd",
458 target_os = "ios",
459 target_os = "macos",
460 target_os = "tvos",
461 target_os = "visionos",
462 target_os = "watchos",
463 ))]
464 {
465 event.0.filter == libc::EVFILT_AIO
466 }
467 #[cfg(not(any(
468 target_os = "dragonfly",
469 target_os = "freebsd",
470 target_os = "ios",
471 target_os = "macos",
472 target_os = "tvos",
473 target_os = "visionos",
474 target_os = "watchos",
475 )))]
476 {
477 false
478 }
479 }
480
481 #[allow(unused_variables)] pub fn is_lio(event: &Event) -> bool {
483 #[cfg(target_os = "freebsd")]
484 {
485 event.0.filter == libc::EVFILT_LIO
486 }
487 #[cfg(not(target_os = "freebsd"))]
488 {
489 false
490 }
491 }
492
493 pub fn debug_details(f: &mut fmt::Formatter<'_>, event: &Event) -> fmt::Result {
494 debug_detail!(
495 FilterDetails(Filter),
496 PartialEq::eq,
497 libc::EVFILT_READ,
498 libc::EVFILT_WRITE,
499 libc::EVFILT_AIO,
500 libc::EVFILT_VNODE,
501 libc::EVFILT_PROC,
502 libc::EVFILT_SIGNAL,
503 libc::EVFILT_TIMER,
504 #[cfg(target_os = "freebsd")]
505 libc::EVFILT_PROCDESC,
506 #[cfg(any(
507 target_os = "freebsd",
508 target_os = "dragonfly",
509 target_os = "ios",
510 target_os = "macos",
511 target_os = "tvos",
512 target_os = "visionos",
513 target_os = "watchos",
514 ))]
515 libc::EVFILT_FS,
516 #[cfg(target_os = "freebsd")]
517 libc::EVFILT_LIO,
518 #[cfg(any(
519 target_os = "freebsd",
520 target_os = "dragonfly",
521 target_os = "ios",
522 target_os = "macos",
523 target_os = "tvos",
524 target_os = "visionos",
525 target_os = "watchos",
526 ))]
527 libc::EVFILT_USER,
528 #[cfg(target_os = "freebsd")]
529 libc::EVFILT_SENDFILE,
530 #[cfg(target_os = "freebsd")]
531 libc::EVFILT_EMPTY,
532 #[cfg(target_os = "dragonfly")]
533 libc::EVFILT_EXCEPT,
534 #[cfg(any(
535 target_os = "ios",
536 target_os = "macos",
537 target_os = "tvos",
538 target_os = "visionos",
539 target_os = "watchos"
540 ))]
541 libc::EVFILT_MACHPORT,
542 #[cfg(any(
543 target_os = "ios",
544 target_os = "macos",
545 target_os = "tvos",
546 target_os = "visionos",
547 target_os = "watchos"
548 ))]
549 libc::EVFILT_VM,
550 );
551
552 #[allow(clippy::trivially_copy_pass_by_ref)]
553 fn check_flag(got: &Flags, want: &Flags) -> bool {
554 (got & want) != 0
555 }
556 debug_detail!(
557 FlagsDetails(Flags),
558 check_flag,
559 libc::EV_ADD,
560 libc::EV_DELETE,
561 libc::EV_ENABLE,
562 libc::EV_DISABLE,
563 libc::EV_ONESHOT,
564 libc::EV_CLEAR,
565 libc::EV_RECEIPT,
566 libc::EV_DISPATCH,
567 #[cfg(target_os = "freebsd")]
568 libc::EV_DROP,
569 libc::EV_FLAG1,
570 libc::EV_ERROR,
571 libc::EV_EOF,
572 #[cfg(not(target_os = "openbsd"))]
574 libc::EV_SYSFLAGS,
575 #[cfg(any(
576 target_os = "ios",
577 target_os = "macos",
578 target_os = "tvos",
579 target_os = "visionos",
580 target_os = "watchos"
581 ))]
582 libc::EV_FLAG0,
583 #[cfg(any(
584 target_os = "ios",
585 target_os = "macos",
586 target_os = "tvos",
587 target_os = "visionos",
588 target_os = "watchos"
589 ))]
590 libc::EV_POLL,
591 #[cfg(any(
592 target_os = "ios",
593 target_os = "macos",
594 target_os = "tvos",
595 target_os = "visionos",
596 target_os = "watchos"
597 ))]
598 libc::EV_OOBAND,
599 #[cfg(target_os = "dragonfly")]
600 libc::EV_NODATA,
601 );
602
603 #[allow(clippy::trivially_copy_pass_by_ref)]
604 fn check_fflag(got: &u32, want: &u32) -> bool {
605 (got & want) != 0
606 }
607 debug_detail!(
608 FflagsDetails(u32),
609 check_fflag,
610 #[cfg(any(
611 target_os = "dragonfly",
612 target_os = "freebsd",
613 target_os = "ios",
614 target_os = "macos",
615 target_os = "tvos",
616 target_os = "visionos",
617 target_os = "watchos",
618 ))]
619 libc::NOTE_TRIGGER,
620 #[cfg(any(
621 target_os = "dragonfly",
622 target_os = "freebsd",
623 target_os = "ios",
624 target_os = "macos",
625 target_os = "tvos",
626 target_os = "visionos",
627 target_os = "watchos",
628 ))]
629 libc::NOTE_FFNOP,
630 #[cfg(any(
631 target_os = "dragonfly",
632 target_os = "freebsd",
633 target_os = "ios",
634 target_os = "macos",
635 target_os = "tvos",
636 target_os = "visionos",
637 target_os = "watchos",
638 ))]
639 libc::NOTE_FFAND,
640 #[cfg(any(
641 target_os = "dragonfly",
642 target_os = "freebsd",
643 target_os = "ios",
644 target_os = "macos",
645 target_os = "tvos",
646 target_os = "visionos",
647 target_os = "watchos",
648 ))]
649 libc::NOTE_FFOR,
650 #[cfg(any(
651 target_os = "dragonfly",
652 target_os = "freebsd",
653 target_os = "ios",
654 target_os = "macos",
655 target_os = "tvos",
656 target_os = "visionos",
657 target_os = "watchos",
658 ))]
659 libc::NOTE_FFCOPY,
660 #[cfg(any(
661 target_os = "dragonfly",
662 target_os = "freebsd",
663 target_os = "ios",
664 target_os = "macos",
665 target_os = "tvos",
666 target_os = "visionos",
667 target_os = "watchos",
668 ))]
669 libc::NOTE_FFCTRLMASK,
670 #[cfg(any(
671 target_os = "dragonfly",
672 target_os = "freebsd",
673 target_os = "ios",
674 target_os = "macos",
675 target_os = "tvos",
676 target_os = "visionos",
677 target_os = "watchos",
678 ))]
679 libc::NOTE_FFLAGSMASK,
680 libc::NOTE_LOWAT,
681 libc::NOTE_DELETE,
682 libc::NOTE_WRITE,
683 #[cfg(target_os = "dragonfly")]
684 libc::NOTE_OOB,
685 #[cfg(target_os = "openbsd")]
686 libc::NOTE_EOF,
687 #[cfg(any(
688 target_os = "ios",
689 target_os = "macos",
690 target_os = "tvos",
691 target_os = "visionos",
692 target_os = "watchos"
693 ))]
694 libc::NOTE_EXTEND,
695 libc::NOTE_ATTRIB,
696 libc::NOTE_LINK,
697 libc::NOTE_RENAME,
698 libc::NOTE_REVOKE,
699 #[cfg(any(
700 target_os = "ios",
701 target_os = "macos",
702 target_os = "tvos",
703 target_os = "visionos",
704 target_os = "watchos"
705 ))]
706 libc::NOTE_NONE,
707 #[cfg(any(target_os = "openbsd"))]
708 libc::NOTE_TRUNCATE,
709 libc::NOTE_EXIT,
710 libc::NOTE_FORK,
711 libc::NOTE_EXEC,
712 #[cfg(any(
713 target_os = "ios",
714 target_os = "macos",
715 target_os = "tvos",
716 target_os = "visionos",
717 target_os = "watchos"
718 ))]
719 libc::NOTE_SIGNAL,
720 #[cfg(any(
721 target_os = "ios",
722 target_os = "macos",
723 target_os = "tvos",
724 target_os = "visionos",
725 target_os = "watchos"
726 ))]
727 libc::NOTE_EXITSTATUS,
728 #[cfg(any(
729 target_os = "ios",
730 target_os = "macos",
731 target_os = "tvos",
732 target_os = "visionos",
733 target_os = "watchos"
734 ))]
735 libc::NOTE_EXIT_DETAIL,
736 libc::NOTE_PDATAMASK,
737 libc::NOTE_PCTRLMASK,
738 #[cfg(any(
739 target_os = "dragonfly",
740 target_os = "freebsd",
741 target_os = "netbsd",
742 target_os = "openbsd",
743 ))]
744 libc::NOTE_TRACK,
745 #[cfg(any(
746 target_os = "dragonfly",
747 target_os = "freebsd",
748 target_os = "netbsd",
749 target_os = "openbsd",
750 ))]
751 libc::NOTE_TRACKERR,
752 #[cfg(any(
753 target_os = "dragonfly",
754 target_os = "freebsd",
755 target_os = "netbsd",
756 target_os = "openbsd",
757 ))]
758 libc::NOTE_CHILD,
759 #[cfg(any(
760 target_os = "ios",
761 target_os = "macos",
762 target_os = "tvos",
763 target_os = "visionos",
764 target_os = "watchos"
765 ))]
766 libc::NOTE_EXIT_DETAIL_MASK,
767 #[cfg(any(
768 target_os = "ios",
769 target_os = "macos",
770 target_os = "tvos",
771 target_os = "visionos",
772 target_os = "watchos"
773 ))]
774 libc::NOTE_EXIT_DECRYPTFAIL,
775 #[cfg(any(
776 target_os = "ios",
777 target_os = "macos",
778 target_os = "tvos",
779 target_os = "visionos",
780 target_os = "watchos"
781 ))]
782 libc::NOTE_EXIT_MEMORY,
783 #[cfg(any(
784 target_os = "ios",
785 target_os = "macos",
786 target_os = "tvos",
787 target_os = "visionos",
788 target_os = "watchos"
789 ))]
790 libc::NOTE_EXIT_CSERROR,
791 #[cfg(any(
792 target_os = "ios",
793 target_os = "macos",
794 target_os = "tvos",
795 target_os = "visionos",
796 target_os = "watchos"
797 ))]
798 libc::NOTE_VM_PRESSURE,
799 #[cfg(any(
800 target_os = "ios",
801 target_os = "macos",
802 target_os = "tvos",
803 target_os = "visionos",
804 target_os = "watchos"
805 ))]
806 libc::NOTE_VM_PRESSURE_TERMINATE,
807 #[cfg(any(
808 target_os = "ios",
809 target_os = "macos",
810 target_os = "tvos",
811 target_os = "visionos",
812 target_os = "watchos"
813 ))]
814 libc::NOTE_VM_PRESSURE_SUDDEN_TERMINATE,
815 #[cfg(any(
816 target_os = "ios",
817 target_os = "macos",
818 target_os = "tvos",
819 target_os = "visionos",
820 target_os = "watchos"
821 ))]
822 libc::NOTE_VM_ERROR,
823 #[cfg(any(
824 target_os = "freebsd",
825 target_os = "ios",
826 target_os = "macos",
827 target_os = "tvos",
828 target_os = "visionos",
829 target_os = "watchos"
830 ))]
831 libc::NOTE_SECONDS,
832 #[cfg(any(target_os = "freebsd"))]
833 libc::NOTE_MSECONDS,
834 #[cfg(any(
835 target_os = "freebsd",
836 target_os = "ios",
837 target_os = "macos",
838 target_os = "tvos",
839 target_os = "visionos",
840 target_os = "watchos"
841 ))]
842 libc::NOTE_USECONDS,
843 #[cfg(any(
844 target_os = "freebsd",
845 target_os = "ios",
846 target_os = "macos",
847 target_os = "tvos",
848 target_os = "visionos",
849 target_os = "watchos"
850 ))]
851 libc::NOTE_NSECONDS,
852 #[cfg(any(
853 target_os = "ios",
854 target_os = "macos",
855 target_os = "tvos",
856 target_os = "visionos",
857 target_os = "watchos"
858 ))]
859 libc::NOTE_ABSOLUTE,
860 #[cfg(any(
861 target_os = "ios",
862 target_os = "macos",
863 target_os = "tvos",
864 target_os = "visionos",
865 target_os = "watchos"
866 ))]
867 libc::NOTE_LEEWAY,
868 #[cfg(any(
869 target_os = "ios",
870 target_os = "macos",
871 target_os = "tvos",
872 target_os = "visionos",
873 target_os = "watchos"
874 ))]
875 libc::NOTE_CRITICAL,
876 #[cfg(any(
877 target_os = "ios",
878 target_os = "macos",
879 target_os = "tvos",
880 target_os = "visionos",
881 target_os = "watchos"
882 ))]
883 libc::NOTE_BACKGROUND,
884 );
885
886 let ident = event.0.ident;
888 let data = event.0.data;
889 let udata = event.0.udata;
890 f.debug_struct("kevent")
891 .field("ident", &ident)
892 .field("filter", &FilterDetails(event.0.filter))
893 .field("flags", &FlagsDetails(event.0.flags))
894 .field("fflags", &FflagsDetails(event.0.fflags))
895 .field("data", &data)
896 .field("udata", &udata)
897 .finish()
898 }
899}
900
901pub(crate) use crate::sys::unix::waker::Waker;
903
904cfg_io_source! {
905 mod stateless_io_source;
906 pub(crate) use stateless_io_source::IoSourceState;
907}
908
909#[test]
910#[cfg(feature = "os-ext")]
911fn does_not_register_rw() {
912 use crate::unix::SourceFd;
913 use crate::{Poll, Token};
914
915 let kq = unsafe { libc::kqueue() };
916 let mut kqf = SourceFd(&kq);
917 let poll = Poll::new().unwrap();
918
919 poll.registry()
922 .register(&mut kqf, Token(1234), Interest::READABLE)
923 .unwrap();
924}