starnix_core/fs/fuchsia/
zxio.rs1use crate::task::{
6 EventHandler, SignalHandler, SignalHandlerInner, WaitCanceler, Waiter, ZxioSignalHandler,
7};
8use starnix_uapi::error;
9use starnix_uapi::errors::Errno;
10use starnix_uapi::vfs::FdEvents;
11
12use syncio::{Zxio, ZxioSignals, zxio};
13
14fn get_zxio_signals_from_events(events: FdEvents) -> zxio::zxio_signals_t {
15 let mut signals = ZxioSignals::NONE;
16
17 if events.contains(FdEvents::POLLIN) {
18 signals |= ZxioSignals::READABLE;
19 }
20 if events.contains(FdEvents::POLLPRI) {
21 signals |= ZxioSignals::OUT_OF_BAND;
22 }
23 if events.contains(FdEvents::POLLOUT) {
24 signals |= ZxioSignals::WRITABLE;
25 }
26 if events.contains(FdEvents::POLLERR) {
27 signals |= ZxioSignals::ERROR;
28 }
29 if events.contains(FdEvents::POLLHUP) {
30 signals |= ZxioSignals::PEER_CLOSED;
31 }
32 if events.contains(FdEvents::POLLRDHUP) {
33 signals |= ZxioSignals::READ_DISABLED;
34 }
35
36 signals.bits()
37}
38
39fn get_events_from_zxio_signals(signals: zxio::zxio_signals_t) -> FdEvents {
40 let zxio_signals = ZxioSignals::from_bits_truncate(signals);
41
42 let mut events = FdEvents::empty();
43
44 if zxio_signals.contains(ZxioSignals::READABLE) {
45 events |= FdEvents::POLLIN;
46 }
47 if zxio_signals.contains(ZxioSignals::OUT_OF_BAND) {
48 events |= FdEvents::POLLPRI;
49 }
50 if zxio_signals.contains(ZxioSignals::WRITABLE) {
51 events |= FdEvents::POLLOUT;
52 }
53 if zxio_signals.contains(ZxioSignals::ERROR) {
54 events |= FdEvents::POLLERR;
55 }
56 if zxio_signals.contains(ZxioSignals::PEER_CLOSED) {
57 events |= FdEvents::POLLHUP;
58 }
59 if zxio_signals.contains(ZxioSignals::READ_DISABLED) {
60 events |= FdEvents::POLLRDHUP;
61 }
62
63 events
64}
65
66pub fn zxio_wait_async(
67 zxio: &Zxio,
68 waiter: &Waiter,
69 events: FdEvents,
70 event_handler: EventHandler,
71) -> WaitCanceler {
72 let (handle, signals) = zxio.wait_begin(get_zxio_signals_from_events(events));
73 if handle.is_invalid() {
74 let observed_zxio_signals = zxio.wait_end(zx::Signals::empty());
75 let observed_events = get_events_from_zxio_signals(observed_zxio_signals);
76 waiter.wake_immediately(observed_events, event_handler);
77 return WaitCanceler::new_noop();
78 }
79
80 let signal_handler = SignalHandler {
81 inner: SignalHandlerInner::Zxio(ZxioSignalHandler {
82 zxio: zxio.downgrade(),
83 get_events_from_zxio_signals,
84 }),
85 event_handler,
86 err_code: None,
87 };
88
89 WaitCanceler::new_zxio(
91 zxio.downgrade(),
92 waiter.wake_on_zircon_signals(&handle, signals, signal_handler).unwrap(),
93 )
94}
95
96pub fn zxio_query_events(zxio: &Zxio) -> Result<FdEvents, Errno> {
97 let (handle, signals) = zxio.wait_begin(ZxioSignals::all().bits());
98 let observed_signals = if handle.is_invalid() {
99 zx::Signals::empty()
100 } else {
101 match handle.wait(signals, zx::MonotonicInstant::INFINITE_PAST).to_result() {
102 Ok(signals) => signals,
103 Err(zx::Status::TIMED_OUT) => zx::Signals::empty(),
104 Err(e) => return error!(EIO, e),
105 }
106 };
107 let observed_zxio_signals = zxio.wait_end(observed_signals);
108 Ok(get_events_from_zxio_signals(observed_zxio_signals))
109}