1use crate::task::{CurrentTask, RunState};
6use crate::vfs::{EpollEventHandler, FdNumber};
7use bitflags::bitflags;
8use futures::stream::AbortHandle;
9use slab::Slab;
10use smallvec::SmallVec;
11use starnix_lifecycle::AtomicCounter;
12use starnix_sync::{
13 EventHandlerReadyQueueLock, EventWaitGuard, FileOpsCore, InterruptibleEvent, LockDepMutex,
14 LockEqualOrBefore, Locked, NotifyKind, PortEvent, PortWaitResult, PortWaiterCallbacksLock,
15 PortWaiterWaitQueuesLock, WaitQueueImplLock, WaiterEventHandlerLock,
16};
17use starnix_types::ownership::debug_assert_no_local_temp_ref;
18use starnix_uapi::error;
19use starnix_uapi::errors::{EINTR, Errno};
20use starnix_uapi::signals::{SIGKILL, SigSet, Signal};
21use starnix_uapi::vfs::FdEvents;
22use std::collections::{HashMap, VecDeque};
23use std::sync::{Arc, Weak};
24use syncio::zxio::zxio_signals_t;
25use syncio::{ZxioSignals, ZxioWeak};
26
27#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
28pub enum ReadyItemKey {
29 FdNumber(FdNumber),
30 Usize(usize),
31}
32
33impl From<FdNumber> for ReadyItemKey {
34 fn from(v: FdNumber) -> Self {
35 Self::FdNumber(v)
36 }
37}
38
39impl From<usize> for ReadyItemKey {
40 fn from(v: usize) -> Self {
41 Self::Usize(v)
42 }
43}
44
45#[derive(Debug, Copy, Clone)]
46pub struct ReadyItem {
47 pub key: ReadyItemKey,
48 pub events: FdEvents,
49}
50
51#[derive(Clone)]
52pub enum EventHandler {
53 None,
58
59 Enqueue {
64 key: ReadyItemKey,
65 queue: Arc<LockDepMutex<VecDeque<ReadyItem>, EventHandlerReadyQueueLock>>,
66 sought_events: FdEvents,
67 },
68
69 HandleOnce(Arc<LockDepMutex<Option<EventHandler>, WaiterEventHandlerLock>>),
74
75 Epoll(EpollEventHandler),
77}
78
79impl EventHandler {
80 pub fn handle(self, events: FdEvents) {
81 match self {
82 Self::None => {}
83 Self::Enqueue { key, queue, sought_events } => {
84 let events = events & sought_events;
85 queue.lock().push_back(ReadyItem { key, events });
86 }
87 Self::HandleOnce(inner) => {
88 if let Some(inner) = inner.lock().take() {
89 inner.handle(events);
90 }
91 }
92 Self::Epoll(e) => e.handle(events),
93 }
94 }
95}
96
97pub struct ZxioSignalHandler {
98 pub zxio: ZxioWeak,
99 pub get_events_from_zxio_signals: fn(zxio_signals_t) -> FdEvents,
100}
101
102pub struct ManyZxHandleSignalHandler {
105 pub count: usize,
106 pub counter: Arc<AtomicCounter<usize>>,
107 pub expected_signals: zx::Signals,
108 pub events: FdEvents,
109}
110
111pub enum SignalHandlerInner {
112 None,
113 Zxio(ZxioSignalHandler),
114 ZxHandle(fn(zx::Signals) -> FdEvents),
115 ManyZxHandle(ManyZxHandleSignalHandler),
116}
117
118pub struct SignalHandler {
119 pub inner: SignalHandlerInner,
120 pub event_handler: EventHandler,
121 pub err_code: Option<Errno>,
122}
123
124impl SignalHandler {
125 fn handle(self, signals: zx::Signals) -> Option<Errno> {
126 let SignalHandler { inner, event_handler, err_code } = self;
127 let events = match inner {
128 SignalHandlerInner::None => None,
129 SignalHandlerInner::Zxio(ZxioSignalHandler { zxio, get_events_from_zxio_signals }) => {
130 if let Some(zxio) = zxio.upgrade() {
131 Some(get_events_from_zxio_signals(zxio.wait_end(signals)))
132 } else {
133 None
134 }
135 }
136 SignalHandlerInner::ZxHandle(get_events_from_zx_signals) => {
137 Some(get_events_from_zx_signals(signals))
138 }
139 SignalHandlerInner::ManyZxHandle(signal_handler) => {
140 if signals.contains(signal_handler.expected_signals) {
141 let new_count = signal_handler.counter.next() + 1;
142 assert!(new_count <= signal_handler.count);
143 if new_count == signal_handler.count {
144 Some(signal_handler.events)
145 } else {
146 None
147 }
148 } else {
149 None
150 }
151 }
152 };
153 if let Some(events) = events {
154 event_handler.handle(events)
155 }
156 err_code
157 }
158}
159
160pub enum WaitCallback {
161 SignalHandler(SignalHandler),
162 EventHandler(EventHandler),
163}
164
165struct WaitCancelerQueue {
166 wait_queue: Weak<LockDepMutex<WaitQueueImpl, WaitQueueImplLock>>,
167 waiter: WaiterRef,
168 wait_key: WaitKey,
169 waiter_id: WaitEntryId,
170}
171
172struct WaitCancelerZxio {
173 zxio: ZxioWeak,
174 inner: PortWaitCanceler,
175}
176
177struct WaitCancelerPort {
178 inner: PortWaitCanceler,
179}
180
181enum WaitCancelerInner {
182 Zxio(WaitCancelerZxio),
183 Queue(WaitCancelerQueue),
184 Port(WaitCancelerPort),
185}
186
187enum NotifiableRef {
188 Port(Arc<PortWaiter>),
189 Event(Arc<InterruptibleEvent>),
190 AbortHandle(Arc<AbortHandle>),
191}
192
193const WAIT_CANCELER_COMMON_SIZE: usize = 2;
194
195pub struct WaitCanceler {
202 cancellers: smallvec::SmallVec<[WaitCancelerInner; WAIT_CANCELER_COMMON_SIZE]>,
203}
204
205impl WaitCanceler {
206 fn new_inner(inner: WaitCancelerInner) -> Self {
207 Self { cancellers: smallvec::smallvec![inner] }
208 }
209
210 pub fn new_noop() -> Self {
211 Self { cancellers: Default::default() }
212 }
213
214 pub fn new_zxio(zxio: ZxioWeak, inner: PortWaitCanceler) -> Self {
215 Self::new_inner(WaitCancelerInner::Zxio(WaitCancelerZxio { zxio, inner }))
216 }
217
218 pub fn new_port(inner: PortWaitCanceler) -> Self {
219 Self::new_inner(WaitCancelerInner::Port(WaitCancelerPort { inner }))
220 }
221
222 pub fn merge(self, other: Self) -> Self {
228 assert!(
231 self.cancellers.len() + other.cancellers.len() <= WAIT_CANCELER_COMMON_SIZE,
232 "WaitCanceler::merge disallows more than {} cancellers, found {} + {}",
233 WAIT_CANCELER_COMMON_SIZE,
234 self.cancellers.len(),
235 other.cancellers.len()
236 );
237 WaitCanceler::merge_unbounded(self, other)
238 }
239
240 pub fn merge_unbounded(
242 Self { mut cancellers }: Self,
243 Self { cancellers: mut other }: Self,
244 ) -> Self {
245 cancellers.append(&mut other);
246 WaitCanceler { cancellers }
247 }
248
249 pub fn cancel(self) {
253 let Self { cancellers } = self;
254 for canceller in cancellers.into_iter().rev() {
255 match canceller {
256 WaitCancelerInner::Zxio(WaitCancelerZxio { zxio, inner }) => {
257 let Some(zxio) = zxio.upgrade() else { return };
258 let (_, signals) = zxio.wait_begin(ZxioSignals::NONE.bits());
259 inner.cancel();
260 zxio.wait_end(signals);
261 }
262 WaitCancelerInner::Queue(WaitCancelerQueue {
263 wait_queue,
264 waiter,
265 wait_key,
266 waiter_id: WaitEntryId { key, id },
267 }) => {
268 let Some(wait_queue) = wait_queue.upgrade() else { return };
269 waiter.remove_callback(&wait_key);
270 waiter.will_remove_from_wait_queue(&wait_key);
271 let mut wait_queue = wait_queue.lock();
272 let waiters = &mut wait_queue.waiters;
273 if let Some(entry) = waiters.get_mut(key) {
274 if entry.id == id {
279 waiters.remove(key);
280 }
281 }
282 }
283 WaitCancelerInner::Port(WaitCancelerPort { inner }) => {
284 inner.cancel();
285 }
286 }
287 }
288 }
289}
290
291pub struct PortWaitCanceler {
298 waiter: Weak<PortWaiter>,
299 key: WaitKey,
300}
301
302impl PortWaitCanceler {
303 pub fn cancel(self) {
307 let Self { waiter, key } = self;
308 if let Some(waiter) = waiter.upgrade() {
309 let _ = waiter.port.cancel(key.raw);
310 waiter.remove_callback(&key);
311 }
312 }
313}
314
315#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
316struct WaitKey {
317 raw: u64,
318}
319
320#[derive(Clone, Copy, Debug)]
322enum WaitEvents {
323 All,
326 Fd(FdEvents),
328 Value(u64),
330 SignalMask(SigSet),
332}
333
334impl WaitEvents {
335 fn intercept(self: &WaitEvents, other: &WaitEvents) -> bool {
337 match (self, other) {
338 (Self::All, _) | (_, Self::All) => true,
339 (Self::Fd(m1), Self::Fd(m2)) => m1.bits() & m2.bits() != 0,
340 (Self::Value(v1), Self::Value(v2)) => v1 == v2,
341 (Self::SignalMask(m1), Self::SignalMask(m2)) => m1.intersects(m2),
343 _ => false,
344 }
345 }
346}
347
348impl WaitCallback {
349 pub fn none() -> EventHandler {
350 EventHandler::None
351 }
352}
353
354bitflags! {
355 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
356 pub struct WaiterOptions: u8 {
357 const IGNORE_SIGNALS = 1 << 0;
359
360 const UNSAFE_CALLSTACK = 1 << 1;
365 }
366}
367
368struct PortWaiter {
372 port: PortEvent,
373 callbacks: LockDepMutex<HashMap<WaitKey, WaitCallback>, PortWaiterCallbacksLock>, next_key: AtomicCounter<u64>,
375 options: WaiterOptions,
376
377 wait_queues: LockDepMutex<
382 HashMap<WaitKey, Weak<LockDepMutex<WaitQueueImpl, WaitQueueImplLock>>>,
383 PortWaiterWaitQueuesLock,
384 >,
385}
386
387impl PortWaiter {
388 fn new(options: WaiterOptions) -> Arc<Self> {
390 Arc::new(PortWaiter {
391 port: PortEvent::new(),
392 callbacks: Default::default(),
393 next_key: AtomicCounter::<u64>::new(1),
394 options,
395 wait_queues: Default::default(),
396 })
397 }
398
399 fn wait_internal(&self, deadline: zx::MonotonicInstant) -> Result<(), Errno> {
401 debug_assert_no_local_temp_ref();
405
406 match self.port.wait(deadline) {
407 PortWaitResult::Notification { kind: NotifyKind::Regular } => Ok(()),
408 PortWaitResult::Notification { kind: NotifyKind::Interrupt } => error!(EINTR),
409 PortWaitResult::Signal { key, observed } => {
410 if let Some(callback) = self.remove_callback(&WaitKey { raw: key }) {
411 match callback {
412 WaitCallback::SignalHandler(handler) => {
413 if let Some(errno) = handler.handle(observed) {
414 return Err(errno);
415 }
416 }
417 WaitCallback::EventHandler(_) => {
418 panic!("wrong type of handler called")
419 }
420 }
421 }
422
423 Ok(())
424 }
425 PortWaitResult::TimedOut => error!(ETIMEDOUT),
426 }
427 }
428
429 fn wait_until<L>(
430 self: &Arc<Self>,
431 locked: &mut Locked<L>,
432 current_task: &CurrentTask,
433 run_state: RunState,
434 deadline: zx::MonotonicInstant,
435 ) -> Result<(), Errno>
436 where
437 L: LockEqualOrBefore<FileOpsCore>,
438 {
439 let is_waiting = deadline.into_nanos() > 0;
440
441 let callback = || {
442 loop {
453 let wait_result = self.wait_internal(deadline);
454 if let Err(errno) = &wait_result {
455 if errno.code == EINTR && !is_waiting {
456 continue; }
458 }
459 return wait_result;
460 }
461 };
462
463 if !self.options.contains(WaiterOptions::UNSAFE_CALLSTACK) {
467 current_task.trigger_delayed_releaser(locked);
468 }
469
470 if is_waiting { current_task.run_in_state(run_state, callback) } else { callback() }
471 }
472
473 fn next_key(&self) -> WaitKey {
474 let key = self.next_key.next();
475 assert!(key != 0, "bad key from u64 wraparound");
477 WaitKey { raw: key }
478 }
479
480 fn register_callback(&self, callback: WaitCallback) -> WaitKey {
481 let key = self.next_key();
482 assert!(
483 self.callbacks.lock().insert(key, callback).is_none(),
484 "unexpected callback already present for key {key:?}"
485 );
486 key
487 }
488
489 fn remove_callback(&self, key: &WaitKey) -> Option<WaitCallback> {
490 self.callbacks.lock().remove(&key)
491 }
492
493 fn wake_immediately(&self, events: FdEvents, handler: EventHandler) {
494 let callback = WaitCallback::EventHandler(handler);
495 let key = self.register_callback(callback);
496 self.queue_events(&key, WaitEvents::Fd(events));
497 }
498
499 fn wake_on_zircon_signals(
505 self: &Arc<Self>,
506 handle: &dyn zx::AsHandleRef,
507 zx_signals: zx::Signals,
508 handler: SignalHandler,
509 ) -> Result<PortWaitCanceler, zx::Status> {
510 let callback = WaitCallback::SignalHandler(handler);
511 let key = self.register_callback(callback);
512 self.port.object_wait_async(
513 handle,
514 key.raw,
515 zx_signals,
516 zx::WaitAsyncOpts::EDGE_TRIGGERED,
517 )?;
518 Ok(PortWaitCanceler { waiter: Arc::downgrade(self), key })
519 }
520
521 fn queue_events(&self, key: &WaitKey, events: WaitEvents) {
522 scopeguard::defer! {
523 self.port.notify(NotifyKind::Regular)
524 }
525
526 let Some(callback) = self.remove_callback(key) else {
538 return;
539 };
540
541 match callback {
542 WaitCallback::EventHandler(handler) => {
543 let events = match events {
544 WaitEvents::All => FdEvents::all(),
547 WaitEvents::Fd(events) => events,
548 WaitEvents::SignalMask(_) => FdEvents::POLLIN,
549 WaitEvents::Value(_) => FdEvents::POLLIN,
550 };
551 handler.handle(events)
552 }
553 WaitCallback::SignalHandler(_) => {
554 panic!("wrong type of handler called")
555 }
556 }
557 }
558
559 fn notify(&self) {
560 self.port.notify(NotifyKind::Regular);
561 }
562
563 fn interrupt(&self) {
564 if self.options.contains(WaiterOptions::IGNORE_SIGNALS) {
565 return;
566 }
567 self.port.notify(NotifyKind::Interrupt);
568 }
569}
570
571impl std::fmt::Debug for PortWaiter {
572 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
573 f.debug_struct("PortWaiter").field("port", &self.port).finish_non_exhaustive()
574 }
575}
576
577#[derive(Debug, Clone)]
579pub struct Waiter {
580 inner: Arc<PortWaiter>,
583}
584
585impl Waiter {
586 pub fn new() -> Self {
588 Self { inner: PortWaiter::new(WaiterOptions::empty()) }
589 }
590
591 pub fn with_options(options: WaiterOptions) -> Self {
593 Self { inner: PortWaiter::new(options) }
594 }
595
596 fn weak(&self) -> WaiterRef {
598 WaiterRef::from_port(&self.inner)
599 }
600
601 pub fn freeze<L>(&self, locked: &mut Locked<L>, current_task: &CurrentTask)
605 where
606 L: LockEqualOrBefore<FileOpsCore>,
607 {
608 while self
609 .inner
610 .wait_until(
611 locked,
612 current_task,
613 RunState::Frozen(self.clone()),
614 zx::MonotonicInstant::INFINITE,
615 )
616 .is_err()
617 {
618 if current_task.read().has_signal_pending(SIGKILL) {
620 break;
621 }
622 }
624 }
625
626 pub fn wait<L>(&self, locked: &mut Locked<L>, current_task: &CurrentTask) -> Result<(), Errno>
630 where
631 L: LockEqualOrBefore<FileOpsCore>,
632 {
633 self.inner.wait_until(
634 locked,
635 current_task,
636 RunState::Waiter(WaiterRef::from_port(&self.inner)),
637 zx::MonotonicInstant::INFINITE,
638 )
639 }
640
641 pub fn wait_until<L>(
664 &self,
665 locked: &mut Locked<L>,
666 current_task: &CurrentTask,
667 deadline: zx::MonotonicInstant,
668 ) -> Result<(), Errno>
669 where
670 L: LockEqualOrBefore<FileOpsCore>,
671 {
672 self.inner.wait_until(
673 locked,
674 current_task,
675 RunState::Waiter(WaiterRef::from_port(&self.inner)),
676 deadline,
677 )
678 }
679
680 fn create_wait_entry(&self, filter: WaitEvents) -> WaitEntry {
681 WaitEntry { waiter: self.weak(), filter, key: self.inner.next_key() }
682 }
683
684 fn create_wait_entry_with_handler(
685 &self,
686 filter: WaitEvents,
687 handler: EventHandler,
688 ) -> WaitEntry {
689 let key = self.inner.register_callback(WaitCallback::EventHandler(handler));
690 WaitEntry { waiter: self.weak(), filter, key }
691 }
692
693 pub fn wake_immediately(&self, events: FdEvents, handler: EventHandler) {
694 self.inner.wake_immediately(events, handler);
695 }
696
697 pub fn wake_on_zircon_signals(
702 &self,
703 handle: &dyn zx::AsHandleRef,
704 zx_signals: zx::Signals,
705 handler: SignalHandler,
706 ) -> Result<PortWaitCanceler, zx::Status> {
707 self.inner.wake_on_zircon_signals(handle, zx_signals, handler)
708 }
709
710 pub fn fake_wait(&self) -> WaitCanceler {
714 WaitCanceler::new_noop()
715 }
716
717 pub fn notify(&self) {
719 self.inner.notify();
720 }
721
722 pub fn interrupt(&self) {
728 self.inner.interrupt();
729 }
730}
731
732impl Drop for Waiter {
733 fn drop(&mut self) {
734 let wait_queues = std::mem::take(&mut *self.inner.wait_queues.lock()).into_values();
737 for wait_queue in wait_queues {
738 if let Some(wait_queue) = wait_queue.upgrade() {
739 wait_queue.lock().waiters.retain(|_, entry| entry.entry.waiter != *self)
740 }
741 }
742 }
743}
744
745impl Default for Waiter {
746 fn default() -> Self {
747 Self::new()
748 }
749}
750
751impl PartialEq for Waiter {
752 fn eq(&self, other: &Self) -> bool {
753 Arc::ptr_eq(&self.inner, &other.inner)
754 }
755}
756
757pub struct SimpleWaiter {
758 event: Arc<InterruptibleEvent>,
759 wait_queues: Vec<Weak<LockDepMutex<WaitQueueImpl, WaitQueueImplLock>>>,
760}
761
762impl SimpleWaiter {
763 pub fn new(event: &Arc<InterruptibleEvent>) -> (SimpleWaiter, EventWaitGuard<'_>) {
764 (SimpleWaiter { event: event.clone(), wait_queues: Default::default() }, event.begin_wait())
765 }
766}
767
768impl Drop for SimpleWaiter {
769 fn drop(&mut self) {
770 for wait_queue in &self.wait_queues {
771 if let Some(wait_queue) = wait_queue.upgrade() {
772 wait_queue.lock().waiters.retain(|_, entry| entry.entry.waiter != self.event)
773 }
774 }
775 }
776}
777
778#[derive(Debug, Clone)]
779enum WaiterKind {
780 Port(Weak<PortWaiter>),
781 Event(Weak<InterruptibleEvent>),
782 AbortHandle(Weak<futures::stream::AbortHandle>),
783}
784
785impl Default for WaiterKind {
786 fn default() -> Self {
787 WaiterKind::Port(Default::default())
788 }
789}
790
791#[derive(Debug, Default, Clone)]
794pub struct WaiterRef(WaiterKind);
795
796impl WaiterRef {
797 fn from_port(waiter: &Arc<PortWaiter>) -> WaiterRef {
798 WaiterRef(WaiterKind::Port(Arc::downgrade(waiter)))
799 }
800
801 fn from_event(event: &Arc<InterruptibleEvent>) -> WaiterRef {
802 WaiterRef(WaiterKind::Event(Arc::downgrade(event)))
803 }
804
805 pub fn from_abort_handle(handle: &Arc<futures::stream::AbortHandle>) -> WaiterRef {
806 WaiterRef(WaiterKind::AbortHandle(Arc::downgrade(handle)))
807 }
808
809 pub fn is_valid(&self) -> bool {
810 match &self.0 {
811 WaiterKind::Port(waiter) => waiter.strong_count() != 0,
812 WaiterKind::Event(event) => event.strong_count() != 0,
813 WaiterKind::AbortHandle(handle) => handle.strong_count() != 0,
814 }
815 }
816
817 pub fn interrupt(&self) {
818 match &self.0 {
819 WaiterKind::Port(waiter) => {
820 if let Some(waiter) = waiter.upgrade() {
821 waiter.interrupt();
822 }
823 }
824 WaiterKind::Event(event) => {
825 if let Some(event) = event.upgrade() {
826 event.interrupt();
827 }
828 }
829 WaiterKind::AbortHandle(handle) => {
830 if let Some(handle) = handle.upgrade() {
831 handle.abort();
832 }
833 }
834 }
835 }
836
837 fn remove_callback(&self, key: &WaitKey) {
838 match &self.0 {
839 WaiterKind::Port(waiter) => {
840 if let Some(waiter) = waiter.upgrade() {
841 waiter.remove_callback(key);
842 }
843 }
844 _ => (),
845 }
846 }
847
848 fn upgrade_notifiable(&self) -> Option<NotifiableRef> {
851 match &self.0 {
852 WaiterKind::Port(waiter) => {
853 if let Some(waiter) = waiter.upgrade() {
854 return Some(NotifiableRef::Port(waiter));
855 }
856 }
857 WaiterKind::Event(event) => {
858 if let Some(event) = event.upgrade() {
859 return Some(NotifiableRef::Event(event));
860 }
861 }
862 WaiterKind::AbortHandle(handle) => {
863 if let Some(handle) = handle.upgrade() {
864 return Some(NotifiableRef::AbortHandle(handle));
865 }
866 }
867 }
868 None
869 }
870
871 fn will_remove_from_wait_queue(&self, key: &WaitKey) {
876 match &self.0 {
877 WaiterKind::Port(waiter) => {
878 if let Some(waiter) = waiter.upgrade() {
879 waiter.wait_queues.lock().remove(key);
880 }
881 }
882 _ => (),
883 }
884 }
885}
886
887impl PartialEq<Waiter> for WaiterRef {
888 fn eq(&self, other: &Waiter) -> bool {
889 match &self.0 {
890 WaiterKind::Port(waiter) => waiter.as_ptr() == Arc::as_ptr(&other.inner),
891 _ => false,
892 }
893 }
894}
895
896impl PartialEq<Arc<InterruptibleEvent>> for WaiterRef {
897 fn eq(&self, other: &Arc<InterruptibleEvent>) -> bool {
898 match &self.0 {
899 WaiterKind::Event(event) => event.as_ptr() == Arc::as_ptr(other),
900 _ => false,
901 }
902 }
903}
904
905impl PartialEq for WaiterRef {
906 fn eq(&self, other: &WaiterRef) -> bool {
907 match (&self.0, &other.0) {
908 (WaiterKind::Port(lhs), WaiterKind::Port(rhs)) => Weak::ptr_eq(lhs, rhs),
909 (WaiterKind::Event(lhs), WaiterKind::Event(rhs)) => Weak::ptr_eq(lhs, rhs),
910 (WaiterKind::AbortHandle(lhs), WaiterKind::AbortHandle(rhs)) => Weak::ptr_eq(lhs, rhs),
911 _ => false,
912 }
913 }
914}
915
916impl NotifiableRef {
917 fn notify(&self, key: &WaitKey, events: WaitEvents) {
918 match self {
919 NotifiableRef::Port(port_waiter) => port_waiter.queue_events(key, events),
920 NotifiableRef::Event(interruptible_event) => interruptible_event.notify(),
921 NotifiableRef::AbortHandle(handle) => handle.abort(),
922 }
923 }
924}
925
926#[derive(Default, Debug, Clone)]
933pub struct WaitQueue(Arc<LockDepMutex<WaitQueueImpl, WaitQueueImplLock>>);
934
935impl WaitQueue {
936 pub fn new() -> Self {
937 Self(Arc::new(WaitQueueImpl::default().into()))
938 }
939}
940
941#[derive(Debug)]
942struct WaitEntryWithId {
943 entry: WaitEntry,
944 id: u64,
948}
949
950struct WaitEntryId {
951 key: usize,
952 id: u64,
953}
954
955#[derive(Default, Debug)]
956struct WaitQueueImpl {
957 next_wait_entry_id: u64,
963 waiters: Slab<WaitEntryWithId>,
967}
968
969#[derive(Debug)]
971struct WaitEntry {
972 waiter: WaiterRef,
974
975 filter: WaitEvents,
977
978 key: WaitKey,
980}
981
982impl WaitQueue {
983 fn add_waiter(&self, entry: WaitEntry) -> WaitEntryId {
984 let mut wait_queue = self.0.lock();
985 let id = wait_queue
986 .next_wait_entry_id
987 .checked_add(1)
988 .expect("all possible wait entry ID values exhausted");
989 wait_queue.next_wait_entry_id = id;
990 WaitEntryId { key: wait_queue.waiters.insert(WaitEntryWithId { entry, id }), id }
991 }
992
993 fn wait_async_entry(&self, waiter: &Waiter, entry: WaitEntry) -> WaitCanceler {
1002 let wait_key = entry.key;
1003 let waiter_id = self.add_waiter(entry);
1004 let wait_queue = Arc::downgrade(&self.0);
1005 waiter.inner.wait_queues.lock().insert(wait_key, wait_queue.clone());
1006 WaitCanceler::new_inner(WaitCancelerInner::Queue(WaitCancelerQueue {
1007 wait_queue,
1008 waiter: waiter.weak(),
1009 wait_key,
1010 waiter_id,
1011 }))
1012 }
1013
1014 pub fn wait_async_value(&self, waiter: &Waiter, value: u64) -> WaitCanceler {
1023 self.wait_async_entry(waiter, waiter.create_wait_entry(WaitEvents::Value(value)))
1024 }
1025
1026 pub fn wait_async_value_with_handler(
1035 &self,
1036 waiter: &Waiter,
1037 value: u64,
1038 handler: EventHandler,
1039 ) -> WaitCanceler {
1040 let entry = waiter.create_wait_entry_with_handler(WaitEvents::Value(value), handler);
1041 self.wait_async_entry(waiter, entry)
1042 }
1043
1044 pub fn wait_async_fd_events(
1053 &self,
1054 waiter: &Waiter,
1055 events: FdEvents,
1056 handler: EventHandler,
1057 ) -> WaitCanceler {
1058 let entry = waiter.create_wait_entry_with_handler(WaitEvents::Fd(events), handler);
1059 self.wait_async_entry(waiter, entry)
1060 }
1061
1062 pub fn wait_async_signal_mask(
1071 &self,
1072 waiter: &Waiter,
1073 mask: SigSet,
1074 handler: EventHandler,
1075 ) -> WaitCanceler {
1076 let entry = waiter.create_wait_entry_with_handler(WaitEvents::SignalMask(mask), handler);
1077 self.wait_async_entry(waiter, entry)
1078 }
1079
1080 pub fn wait_async(&self, waiter: &Waiter) -> WaitCanceler {
1089 self.wait_async_entry(waiter, waiter.create_wait_entry(WaitEvents::All))
1090 }
1091
1092 pub fn wait_async_simple(&self, waiter: &mut SimpleWaiter) {
1093 let entry = WaitEntry {
1094 waiter: WaiterRef::from_event(&waiter.event),
1095 filter: WaitEvents::All,
1096 key: Default::default(),
1097 };
1098 waiter.wait_queues.push(Arc::downgrade(&self.0));
1099 self.add_waiter(entry);
1100 }
1101
1102 fn notify_events_count(&self, mut events: WaitEvents, mut limit: usize) -> usize {
1103 if let WaitEvents::Fd(ref mut fd_events) = events {
1104 *fd_events = fd_events.add_equivalent_fd_events();
1105 }
1106 let mut notifiable_refs = SmallVec::<[(NotifiableRef, WaitKey); 1]>::new();
1112 let mut woken = 0;
1113 {
1114 let mut guard = self.0.lock();
1115 guard.waiters.retain(|_, WaitEntryWithId { entry, id: _ }| {
1116 if limit > 0 && entry.filter.intercept(&events) {
1117 if let Some(notifiable_ref) = entry.waiter.upgrade_notifiable() {
1118 limit -= 1;
1119 woken += 1;
1120 notifiable_refs.push((notifiable_ref, entry.key));
1121 }
1122
1123 entry.waiter.will_remove_from_wait_queue(&entry.key);
1124 false
1125 } else {
1126 true
1127 }
1128 });
1129 }
1130 for (notifiable_ref, key) in notifiable_refs {
1131 notifiable_ref.notify(&key, events);
1132 }
1133 woken
1134 }
1135
1136 pub fn notify_fd_events(&self, events: FdEvents) {
1137 self.notify_events_count(WaitEvents::Fd(events), usize::MAX);
1138 }
1139
1140 pub fn notify_fd_events_count(&self, events: FdEvents, limit: usize) {
1141 self.notify_events_count(WaitEvents::Fd(events), limit);
1142 }
1143
1144 pub fn notify_signal(&self, signal: &Signal) {
1145 let event = WaitEvents::SignalMask(SigSet::from(*signal));
1146 self.notify_events_count(event, usize::MAX);
1147 }
1148
1149 pub fn notify_value(&self, value: u64) {
1150 self.notify_events_count(WaitEvents::Value(value), usize::MAX);
1151 }
1152
1153 pub fn notify_unordered_count(&self, limit: usize) {
1154 self.notify_events_count(WaitEvents::All, limit);
1155 }
1156
1157 pub fn notify_all(&self) {
1158 self.notify_unordered_count(usize::MAX);
1159 }
1160
1161 pub fn is_empty(&self) -> bool {
1163 self.0.lock().waiters.is_empty()
1164 }
1165}
1166
1167pub struct TypedWaitQueue<T: Into<u64>> {
1169 wait_queue: WaitQueue,
1170 value_type: std::marker::PhantomData<T>,
1171}
1172
1173impl<T: Into<u64>> Default for TypedWaitQueue<T> {
1175 fn default() -> Self {
1176 Self { wait_queue: Default::default(), value_type: Default::default() }
1177 }
1178}
1179
1180impl<T: Into<u64>> TypedWaitQueue<T> {
1181 pub fn wait_async_value(&self, waiter: &Waiter, value: T) -> WaitCanceler {
1182 self.wait_queue.wait_async_value(waiter, value.into())
1183 }
1184
1185 pub fn wait_async_value_with_handler(
1186 &self,
1187 waiter: &Waiter,
1188 value: T,
1189 handler: EventHandler,
1190 ) -> WaitCanceler {
1191 self.wait_queue.wait_async_value_with_handler(waiter, value.into(), handler)
1192 }
1193
1194 pub fn notify_value(&self, value: T) {
1195 self.wait_queue.notify_value(value.into())
1196 }
1197}
1198
1199#[cfg(test)]
1200mod tests {
1201 use super::*;
1202 use crate::fs::fuchsia::create_fuchsia_pipe;
1203 use crate::signals::SignalInfo;
1204 use crate::task::TaskFlags;
1205 use crate::testing::{spawn_kernel_and_run, spawn_kernel_and_run_sync};
1206 use crate::vfs::buffers::{VecInputBuffer, VecOutputBuffer};
1207 use crate::vfs::eventfd::{EventFdType, new_eventfd};
1208 use assert_matches::assert_matches;
1209 use starnix_sync::Unlocked;
1210 use starnix_uapi::open_flags::OpenFlags;
1211 use starnix_uapi::signals::SIGUSR1;
1212
1213 const KEY: ReadyItemKey = ReadyItemKey::Usize(1234);
1214
1215 #[::fuchsia::test]
1216 async fn test_async_wait_exec() {
1217 spawn_kernel_and_run(async |locked, current_task| {
1218 let (local_socket, remote_socket) = zx::Socket::create_stream();
1219 let pipe =
1220 create_fuchsia_pipe(locked, ¤t_task, remote_socket, OpenFlags::RDWR).unwrap();
1221
1222 const MEM_SIZE: usize = 1024;
1223 let mut output_buffer = VecOutputBuffer::new(MEM_SIZE);
1224
1225 let test_string = "hello startnix".to_string();
1226 let queue: Arc<LockDepMutex<VecDeque<ReadyItem>, EventHandlerReadyQueueLock>> =
1227 Default::default();
1228 let handler = EventHandler::Enqueue {
1229 key: KEY,
1230 queue: queue.clone(),
1231 sought_events: FdEvents::all(),
1232 };
1233 let waiter = Waiter::new();
1234 pipe.wait_async(locked, ¤t_task, &waiter, FdEvents::POLLIN, handler)
1235 .expect("wait_async");
1236 let test_string_clone = test_string.clone();
1237
1238 let write_count = AtomicCounter::<usize>::default();
1239 std::thread::scope(|s| {
1240 let thread = s.spawn(|| {
1241 let test_data = test_string_clone.as_bytes();
1242 let no_written = local_socket.write(test_data).unwrap();
1243 assert_eq!(0, write_count.add(no_written));
1244 assert_eq!(no_written, test_data.len());
1245 });
1246
1247 assert!(queue.lock().is_empty());
1250 waiter.wait(locked, ¤t_task).unwrap();
1251 thread.join().expect("join thread")
1252 });
1253 queue.lock().iter().for_each(|item| assert!(item.events.contains(FdEvents::POLLIN)));
1254
1255 let read_size = pipe.read(locked, ¤t_task, &mut output_buffer).unwrap();
1256
1257 let no_written = write_count.get();
1258 assert_eq!(no_written, read_size);
1259
1260 assert_eq!(output_buffer.data(), test_string.as_bytes());
1261 })
1262 .await;
1263 }
1264
1265 #[::fuchsia::test]
1266 async fn test_async_wait_cancel() {
1267 for do_cancel in [true, false] {
1268 spawn_kernel_and_run(async move |locked, current_task| {
1269 let event = new_eventfd(locked, ¤t_task, 0, EventFdType::Counter, true);
1270 let waiter = Waiter::new();
1271 let queue: Arc<LockDepMutex<VecDeque<ReadyItem>, EventHandlerReadyQueueLock>> =
1272 Default::default();
1273 let handler = EventHandler::Enqueue {
1274 key: KEY,
1275 queue: queue.clone(),
1276 sought_events: FdEvents::all(),
1277 };
1278 let wait_canceler = event
1279 .wait_async(locked, ¤t_task, &waiter, FdEvents::POLLIN, handler)
1280 .expect("wait_async");
1281 if do_cancel {
1282 wait_canceler.cancel();
1283 }
1284 let add_val = 1u64;
1285 assert_eq!(
1286 event
1287 .write(
1288 locked,
1289 ¤t_task,
1290 &mut VecInputBuffer::new(&add_val.to_ne_bytes())
1291 )
1292 .unwrap(),
1293 std::mem::size_of::<u64>()
1294 );
1295
1296 let wait_result =
1297 waiter.wait_until(locked, ¤t_task, zx::MonotonicInstant::ZERO);
1298 let final_count = queue.lock().len();
1299 if do_cancel {
1300 assert_eq!(wait_result, error!(ETIMEDOUT));
1301 assert_eq!(0, final_count);
1302 } else {
1303 assert_eq!(wait_result, Ok(()));
1304 assert_eq!(1, final_count);
1305 }
1306 })
1307 .await;
1308 }
1309 }
1310
1311 #[::fuchsia::test]
1312 async fn single_waiter_multiple_waits_cancel_one_waiter_still_notified() {
1313 spawn_kernel_and_run(async |locked, current_task| {
1314 let wait_queue = WaitQueue::default();
1315 let waiter = Waiter::new();
1316 let wk1 = wait_queue.wait_async(&waiter);
1317 let _wk2 = wait_queue.wait_async(&waiter);
1318 wk1.cancel();
1319 wait_queue.notify_all();
1320 assert!(waiter.wait_until(locked, ¤t_task, zx::MonotonicInstant::ZERO).is_ok());
1321 })
1322 .await;
1323 }
1324
1325 #[::fuchsia::test]
1326 async fn multiple_waiters_cancel_one_other_still_notified() {
1327 spawn_kernel_and_run(async |locked, current_task| {
1328 let wait_queue = WaitQueue::default();
1329 let waiter1 = Waiter::new();
1330 let waiter2 = Waiter::new();
1331 let wk1 = wait_queue.wait_async(&waiter1);
1332 let _wk2 = wait_queue.wait_async(&waiter2);
1333 wk1.cancel();
1334 wait_queue.notify_all();
1335 assert!(waiter1.wait_until(locked, ¤t_task, zx::MonotonicInstant::ZERO).is_err());
1336 assert!(waiter2.wait_until(locked, ¤t_task, zx::MonotonicInstant::ZERO).is_ok());
1337 })
1338 .await;
1339 }
1340
1341 #[::fuchsia::test]
1342 async fn test_wait_queue() {
1343 spawn_kernel_and_run(async |locked, current_task| {
1344 let queue = WaitQueue::default();
1345
1346 let waiters = <[Waiter; 3]>::default();
1347 waiters.iter().for_each(|w| {
1348 queue.wait_async(w);
1349 });
1350
1351 let woken = |locked: &mut Locked<Unlocked>| {
1352 waiters
1353 .iter()
1354 .filter(|w| {
1355 w.wait_until(locked, ¤t_task, zx::MonotonicInstant::ZERO).is_ok()
1356 })
1357 .count()
1358 };
1359
1360 const INITIAL_NOTIFY_COUNT: usize = 2;
1361 let total_waiters = waiters.len();
1362 queue.notify_unordered_count(INITIAL_NOTIFY_COUNT);
1363 assert_eq!(INITIAL_NOTIFY_COUNT, woken(locked));
1364
1365 queue.notify_all();
1367 assert_eq!(total_waiters - INITIAL_NOTIFY_COUNT, woken(locked));
1368 })
1369 .await;
1370 }
1371
1372 #[::fuchsia::test]
1373 async fn waiter_kind_abort_handle() {
1374 spawn_kernel_and_run_sync(|_locked, current_task| {
1375 let mut executor = fuchsia_async::TestExecutor::new();
1376 let (abort_handle, abort_registration) = futures::stream::AbortHandle::new_pair();
1377 let abort_handle = Arc::new(abort_handle);
1378 let waiter_ref = WaiterRef::from_abort_handle(&abort_handle);
1379
1380 let mut fut = futures::stream::Abortable::new(
1381 futures::future::pending::<()>(),
1382 abort_registration,
1383 );
1384
1385 assert_matches!(executor.run_until_stalled(&mut fut), std::task::Poll::Pending);
1386
1387 waiter_ref.interrupt();
1388 let output = current_task.run_in_state(RunState::Waiter(waiter_ref), move || {
1389 match executor.run_singlethreaded(&mut fut) {
1390 Ok(()) => unreachable!("future never terminates normally"),
1391 Err(futures::stream::Aborted) => Ok(()),
1392 }
1393 });
1394
1395 assert_eq!(output, Ok(()));
1396 })
1397 .await;
1398 }
1399
1400 #[::fuchsia::test]
1401 async fn freeze_with_pending_sigusr1() {
1402 spawn_kernel_and_run(async |_locked, current_task| {
1403 {
1404 let mut task_state = current_task.task.write();
1405 let siginfo = SignalInfo::kernel(SIGUSR1);
1406 task_state.enqueue_signal(siginfo);
1407 task_state.set_flags(TaskFlags::SIGNALS_AVAILABLE, true);
1408 }
1409
1410 let output: Result<(), Errno> = current_task
1411 .run_in_state(RunState::Event(InterruptibleEvent::new()), move || {
1412 unreachable!("callback should not be called")
1413 });
1414 assert_eq!(output, error!(EINTR));
1415
1416 let output = current_task.run_in_state(RunState::Frozen(Waiter::new()), move || Ok(()));
1417 assert_eq!(output, Ok(()));
1418 })
1419 .await;
1420 }
1421
1422 #[::fuchsia::test]
1423 async fn freeze_with_pending_sigkill() {
1424 spawn_kernel_and_run(async |_locked, current_task| {
1425 {
1426 let mut task_state = current_task.task.write();
1427 let siginfo = SignalInfo::kernel(SIGKILL);
1428 task_state.enqueue_signal(siginfo);
1429 task_state.set_flags(TaskFlags::SIGNALS_AVAILABLE, true);
1430 }
1431
1432 let output: Result<(), _> = current_task
1433 .run_in_state(RunState::Frozen(Waiter::new()), move || {
1434 unreachable!("callback should not be called")
1435 });
1436 assert_eq!(output, error!(EINTR));
1437 })
1438 .await;
1439 }
1440
1441 #[::fuchsia::test]
1442 async fn test_async_typed_wait_value_with_handler() {
1443 spawn_kernel_and_run(async |locked, current_task| {
1444 let queue: Arc<LockDepMutex<VecDeque<ReadyItem>, EventHandlerReadyQueueLock>> =
1445 Default::default();
1446 let handler = EventHandler::Enqueue {
1447 key: KEY,
1448 queue: queue.clone(),
1449 sought_events: FdEvents::all(),
1450 };
1451 let waiter = Waiter::new();
1452 let wait_queue = TypedWaitQueue::<u64>::default();
1453
1454 let test_value = 100u64;
1455 let _wait_canceler =
1456 wait_queue.wait_async_value_with_handler(&waiter, test_value, handler);
1457
1458 assert!(queue.lock().is_empty());
1459
1460 wait_queue.notify_value(test_value + 1);
1462 assert!(queue.lock().is_empty());
1463
1464 wait_queue.notify_value(test_value);
1466
1467 waiter.wait(locked, ¤t_task).expect("wait failed");
1468
1469 let ready_items = queue.lock();
1471 assert_eq!(ready_items.len(), 1);
1472 assert!(ready_items[0].events.contains(FdEvents::POLLIN));
1473 })
1474 .await;
1475 }
1476}