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, InterruptibleEvent, LockDepMutex, NotifyKind,
14 PortEvent, PortWaitResult, PortWaiterCallbacksLock, PortWaiterWaitQueuesLock,
15 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 UNSAFE_CALLSTACK = 1 << 0;
362 }
363}
364
365struct PortWaiter {
369 port: PortEvent,
370 callbacks: LockDepMutex<HashMap<WaitKey, WaitCallback>, PortWaiterCallbacksLock>, next_key: AtomicCounter<u64>,
372 options: WaiterOptions,
373
374 wait_queues: LockDepMutex<
379 HashMap<WaitKey, Weak<LockDepMutex<WaitQueueImpl, WaitQueueImplLock>>>,
380 PortWaiterWaitQueuesLock,
381 >,
382}
383
384impl PortWaiter {
385 fn new(options: WaiterOptions) -> Arc<Self> {
387 Arc::new(PortWaiter {
388 port: PortEvent::new(),
389 callbacks: Default::default(),
390 next_key: AtomicCounter::<u64>::new(1),
391 options,
392 wait_queues: Default::default(),
393 })
394 }
395
396 fn wait_internal(&self, deadline: zx::MonotonicInstant) -> Result<(), Errno> {
398 debug_assert_no_local_temp_ref();
402
403 match self.port.wait(deadline) {
404 PortWaitResult::Notification { kind: NotifyKind::Regular } => Ok(()),
405 PortWaitResult::Notification { kind: NotifyKind::Interrupt } => error!(EINTR),
406 PortWaitResult::Signal { key, observed } => {
407 if let Some(callback) = self.remove_callback(&WaitKey { raw: key }) {
408 match callback {
409 WaitCallback::SignalHandler(handler) => {
410 if let Some(errno) = handler.handle(observed) {
411 return Err(errno);
412 }
413 }
414 WaitCallback::EventHandler(_) => {
415 panic!("wrong type of handler called")
416 }
417 }
418 }
419
420 Ok(())
421 }
422 PortWaitResult::TimedOut => error!(ETIMEDOUT),
423 }
424 }
425
426 fn wait_until(
427 self: &Arc<Self>,
428 current_task: &CurrentTask,
429 run_state: RunState,
430 deadline: zx::MonotonicInstant,
431 ) -> Result<(), Errno> {
432 let is_waiting = deadline.into_nanos() > 0;
433
434 let callback = || {
435 loop {
446 let wait_result = self.wait_internal(deadline);
447 if let Err(errno) = &wait_result {
448 if errno.code == EINTR && !is_waiting {
449 continue; }
451 }
452 return wait_result;
453 }
454 };
455
456 if !self.options.contains(WaiterOptions::UNSAFE_CALLSTACK) {
460 current_task.trigger_delayed_releaser();
461 }
462
463 if is_waiting { current_task.run_in_state(run_state, callback) } else { callback() }
464 }
465
466 fn next_key(&self) -> WaitKey {
467 let key = self.next_key.next();
468 assert!(key != 0, "bad key from u64 wraparound");
470 WaitKey { raw: key }
471 }
472
473 fn register_callback(&self, callback: WaitCallback) -> WaitKey {
474 let key = self.next_key();
475 assert!(
476 self.callbacks.lock().insert(key, callback).is_none(),
477 "unexpected callback already present for key {key:?}"
478 );
479 key
480 }
481
482 fn remove_callback(&self, key: &WaitKey) -> Option<WaitCallback> {
483 self.callbacks.lock().remove(&key)
484 }
485
486 fn wake_immediately(&self, events: FdEvents, handler: EventHandler) {
487 let callback = WaitCallback::EventHandler(handler);
488 let key = self.register_callback(callback);
489 self.queue_events(&key, WaitEvents::Fd(events));
490 }
491
492 fn wake_on_zircon_signals(
498 self: &Arc<Self>,
499 handle: &dyn zx::AsHandleRef,
500 zx_signals: zx::Signals,
501 handler: SignalHandler,
502 ) -> Result<PortWaitCanceler, zx::Status> {
503 let callback = WaitCallback::SignalHandler(handler);
504 let key = self.register_callback(callback);
505 self.port.object_wait_async(
506 handle,
507 key.raw,
508 zx_signals,
509 zx::WaitAsyncOpts::EDGE_TRIGGERED,
510 )?;
511 Ok(PortWaitCanceler { waiter: Arc::downgrade(self), key })
512 }
513
514 fn queue_events(&self, key: &WaitKey, events: WaitEvents) {
515 scopeguard::defer! {
516 self.port.notify(NotifyKind::Regular)
517 }
518
519 let Some(callback) = self.remove_callback(key) else {
531 return;
532 };
533
534 match callback {
535 WaitCallback::EventHandler(handler) => {
536 let events = match events {
537 WaitEvents::All => FdEvents::all(),
540 WaitEvents::Fd(events) => events,
541 WaitEvents::SignalMask(_) => FdEvents::POLLIN,
542 WaitEvents::Value(_) => FdEvents::POLLIN,
543 };
544 handler.handle(events)
545 }
546 WaitCallback::SignalHandler(_) => {
547 panic!("wrong type of handler called")
548 }
549 }
550 }
551
552 fn notify(&self) {
553 self.port.notify(NotifyKind::Regular);
554 }
555
556 fn interrupt(&self) {
557 self.port.notify(NotifyKind::Interrupt);
558 }
559}
560
561impl std::fmt::Debug for PortWaiter {
562 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
563 f.debug_struct("PortWaiter").field("port", &self.port).finish_non_exhaustive()
564 }
565}
566
567#[derive(Debug, Clone)]
569pub struct Waiter {
570 inner: Arc<PortWaiter>,
573}
574
575impl Waiter {
576 pub fn new() -> Self {
578 Self { inner: PortWaiter::new(WaiterOptions::empty()) }
579 }
580
581 pub fn with_options(options: WaiterOptions) -> Self {
583 Self { inner: PortWaiter::new(options) }
584 }
585
586 fn weak(&self) -> WaiterRef {
588 WaiterRef::from_port(&self.inner)
589 }
590
591 pub fn freeze(&self, current_task: &CurrentTask) {
595 while self
596 .inner
597 .wait_until(
598 current_task,
599 RunState::Frozen(self.clone()),
600 zx::MonotonicInstant::INFINITE,
601 )
602 .is_err()
603 {
604 if current_task.is_exitted() || current_task.read().has_signal_pending(SIGKILL) {
606 break;
607 }
608 }
610 }
611
612 pub fn stop(&self, current_task: &CurrentTask) {
616 let _ = self.inner.wait_until(
620 current_task,
621 RunState::TracingStopped,
622 zx::MonotonicInstant::INFINITE,
623 );
624 }
625
626 pub fn wait(&self, current_task: &CurrentTask) -> Result<(), Errno> {
630 self.inner.wait_until(
631 current_task,
632 RunState::Waiter(WaiterRef::from_port(&self.inner)),
633 zx::MonotonicInstant::INFINITE,
634 )
635 }
636
637 pub fn wait_until(
660 &self,
661 current_task: &CurrentTask,
662 deadline: zx::MonotonicInstant,
663 ) -> Result<(), Errno> {
664 self.inner.wait_until(
665 current_task,
666 RunState::Waiter(WaiterRef::from_port(&self.inner)),
667 deadline,
668 )
669 }
670
671 fn create_wait_entry(&self, filter: WaitEvents) -> WaitEntry {
672 WaitEntry { waiter: self.weak(), filter, key: self.inner.next_key() }
673 }
674
675 fn create_wait_entry_with_handler(
676 &self,
677 filter: WaitEvents,
678 handler: EventHandler,
679 ) -> WaitEntry {
680 let key = self.inner.register_callback(WaitCallback::EventHandler(handler));
681 WaitEntry { waiter: self.weak(), filter, key }
682 }
683
684 pub fn wake_immediately(&self, events: FdEvents, handler: EventHandler) {
685 self.inner.wake_immediately(events, handler);
686 }
687
688 pub fn wake_on_zircon_signals(
693 &self,
694 handle: &dyn zx::AsHandleRef,
695 zx_signals: zx::Signals,
696 handler: SignalHandler,
697 ) -> Result<PortWaitCanceler, zx::Status> {
698 self.inner.wake_on_zircon_signals(handle, zx_signals, handler)
699 }
700
701 pub fn fake_wait(&self) -> WaitCanceler {
705 WaitCanceler::new_noop()
706 }
707
708 pub fn notify(&self) {
710 self.inner.notify();
711 }
712
713 pub fn interrupt(&self) {
717 self.inner.interrupt();
718 }
719}
720
721impl Drop for Waiter {
722 fn drop(&mut self) {
723 let wait_queues = std::mem::take(&mut *self.inner.wait_queues.lock()).into_values();
726 for wait_queue in wait_queues {
727 if let Some(wait_queue) = wait_queue.upgrade() {
728 wait_queue.lock().waiters.retain(|_, entry| entry.entry.waiter != *self)
729 }
730 }
731 }
732}
733
734impl Default for Waiter {
735 fn default() -> Self {
736 Self::new()
737 }
738}
739
740impl PartialEq for Waiter {
741 fn eq(&self, other: &Self) -> bool {
742 Arc::ptr_eq(&self.inner, &other.inner)
743 }
744}
745
746pub struct SimpleWaiter {
747 event: Arc<InterruptibleEvent>,
748 wait_queues: Vec<Weak<LockDepMutex<WaitQueueImpl, WaitQueueImplLock>>>,
749}
750
751impl SimpleWaiter {
752 pub fn new(event: &Arc<InterruptibleEvent>) -> (SimpleWaiter, EventWaitGuard<'_>) {
753 (SimpleWaiter { event: event.clone(), wait_queues: Default::default() }, event.begin_wait())
754 }
755}
756
757impl Drop for SimpleWaiter {
758 fn drop(&mut self) {
759 for wait_queue in &self.wait_queues {
760 if let Some(wait_queue) = wait_queue.upgrade() {
761 wait_queue.lock().waiters.retain(|_, entry| entry.entry.waiter != self.event)
762 }
763 }
764 }
765}
766
767#[derive(Debug, Clone)]
768enum WaiterKind {
769 Port(Weak<PortWaiter>),
770 Event(Weak<InterruptibleEvent>),
771 AbortHandle(Weak<futures::stream::AbortHandle>),
772}
773
774impl Default for WaiterKind {
775 fn default() -> Self {
776 WaiterKind::Port(Default::default())
777 }
778}
779
780#[derive(Debug, Default, Clone)]
783pub struct WaiterRef(WaiterKind);
784
785impl WaiterRef {
786 fn from_port(waiter: &Arc<PortWaiter>) -> WaiterRef {
787 WaiterRef(WaiterKind::Port(Arc::downgrade(waiter)))
788 }
789
790 fn from_event(event: &Arc<InterruptibleEvent>) -> WaiterRef {
791 WaiterRef(WaiterKind::Event(Arc::downgrade(event)))
792 }
793
794 pub fn from_abort_handle(handle: &Arc<futures::stream::AbortHandle>) -> WaiterRef {
795 WaiterRef(WaiterKind::AbortHandle(Arc::downgrade(handle)))
796 }
797
798 pub fn is_valid(&self) -> bool {
799 match &self.0 {
800 WaiterKind::Port(waiter) => waiter.strong_count() != 0,
801 WaiterKind::Event(event) => event.strong_count() != 0,
802 WaiterKind::AbortHandle(handle) => handle.strong_count() != 0,
803 }
804 }
805
806 pub fn interrupt(&self) {
807 match &self.0 {
808 WaiterKind::Port(waiter) => {
809 if let Some(waiter) = waiter.upgrade() {
810 waiter.interrupt();
811 }
812 }
813 WaiterKind::Event(event) => {
814 if let Some(event) = event.upgrade() {
815 event.interrupt();
816 }
817 }
818 WaiterKind::AbortHandle(handle) => {
819 if let Some(handle) = handle.upgrade() {
820 handle.abort();
821 }
822 }
823 }
824 }
825
826 fn remove_callback(&self, key: &WaitKey) {
827 match &self.0 {
828 WaiterKind::Port(waiter) => {
829 if let Some(waiter) = waiter.upgrade() {
830 waiter.remove_callback(key);
831 }
832 }
833 _ => (),
834 }
835 }
836
837 fn upgrade_notifiable(&self) -> Option<NotifiableRef> {
840 match &self.0 {
841 WaiterKind::Port(waiter) => {
842 if let Some(waiter) = waiter.upgrade() {
843 return Some(NotifiableRef::Port(waiter));
844 }
845 }
846 WaiterKind::Event(event) => {
847 if let Some(event) = event.upgrade() {
848 return Some(NotifiableRef::Event(event));
849 }
850 }
851 WaiterKind::AbortHandle(handle) => {
852 if let Some(handle) = handle.upgrade() {
853 return Some(NotifiableRef::AbortHandle(handle));
854 }
855 }
856 }
857 None
858 }
859
860 fn will_remove_from_wait_queue(&self, key: &WaitKey) {
865 match &self.0 {
866 WaiterKind::Port(waiter) => {
867 if let Some(waiter) = waiter.upgrade() {
868 waiter.wait_queues.lock().remove(key);
869 }
870 }
871 _ => (),
872 }
873 }
874}
875
876impl PartialEq<Waiter> for WaiterRef {
877 fn eq(&self, other: &Waiter) -> bool {
878 match &self.0 {
879 WaiterKind::Port(waiter) => waiter.as_ptr() == Arc::as_ptr(&other.inner),
880 _ => false,
881 }
882 }
883}
884
885impl PartialEq<Arc<InterruptibleEvent>> for WaiterRef {
886 fn eq(&self, other: &Arc<InterruptibleEvent>) -> bool {
887 match &self.0 {
888 WaiterKind::Event(event) => event.as_ptr() == Arc::as_ptr(other),
889 _ => false,
890 }
891 }
892}
893
894impl PartialEq for WaiterRef {
895 fn eq(&self, other: &WaiterRef) -> bool {
896 match (&self.0, &other.0) {
897 (WaiterKind::Port(lhs), WaiterKind::Port(rhs)) => Weak::ptr_eq(lhs, rhs),
898 (WaiterKind::Event(lhs), WaiterKind::Event(rhs)) => Weak::ptr_eq(lhs, rhs),
899 (WaiterKind::AbortHandle(lhs), WaiterKind::AbortHandle(rhs)) => Weak::ptr_eq(lhs, rhs),
900 _ => false,
901 }
902 }
903}
904
905impl NotifiableRef {
906 fn notify(&self, key: &WaitKey, events: WaitEvents) {
907 match self {
908 NotifiableRef::Port(port_waiter) => port_waiter.queue_events(key, events),
909 NotifiableRef::Event(interruptible_event) => interruptible_event.notify(),
910 NotifiableRef::AbortHandle(handle) => handle.abort(),
911 }
912 }
913}
914
915#[derive(Default, Debug, Clone)]
922pub struct WaitQueue(Arc<LockDepMutex<WaitQueueImpl, WaitQueueImplLock>>);
923
924impl WaitQueue {
925 pub fn new() -> Self {
926 Self(Arc::new(WaitQueueImpl::default().into()))
927 }
928}
929
930#[derive(Debug)]
931struct WaitEntryWithId {
932 entry: WaitEntry,
933 id: u64,
937}
938
939struct WaitEntryId {
940 key: usize,
941 id: u64,
942}
943
944#[derive(Default, Debug)]
945struct WaitQueueImpl {
946 next_wait_entry_id: u64,
952 waiters: Slab<WaitEntryWithId>,
956}
957
958#[derive(Debug)]
960struct WaitEntry {
961 waiter: WaiterRef,
963
964 filter: WaitEvents,
966
967 key: WaitKey,
969}
970
971impl WaitQueue {
972 fn add_waiter(&self, entry: WaitEntry) -> WaitEntryId {
973 let mut wait_queue = self.0.lock();
974 let id = wait_queue
975 .next_wait_entry_id
976 .checked_add(1)
977 .expect("all possible wait entry ID values exhausted");
978 wait_queue.next_wait_entry_id = id;
979 WaitEntryId { key: wait_queue.waiters.insert(WaitEntryWithId { entry, id }), id }
980 }
981
982 fn wait_async_entry(&self, waiter: &Waiter, entry: WaitEntry) -> WaitCanceler {
991 let wait_key = entry.key;
992 let waiter_id = self.add_waiter(entry);
993 let wait_queue = Arc::downgrade(&self.0);
994 waiter.inner.wait_queues.lock().insert(wait_key, wait_queue.clone());
995 WaitCanceler::new_inner(WaitCancelerInner::Queue(WaitCancelerQueue {
996 wait_queue,
997 waiter: waiter.weak(),
998 wait_key,
999 waiter_id,
1000 }))
1001 }
1002
1003 pub fn wait_async_value(&self, waiter: &Waiter, value: u64) -> WaitCanceler {
1012 self.wait_async_entry(waiter, waiter.create_wait_entry(WaitEvents::Value(value)))
1013 }
1014
1015 pub fn wait_async_value_with_handler(
1024 &self,
1025 waiter: &Waiter,
1026 value: u64,
1027 handler: EventHandler,
1028 ) -> WaitCanceler {
1029 let entry = waiter.create_wait_entry_with_handler(WaitEvents::Value(value), handler);
1030 self.wait_async_entry(waiter, entry)
1031 }
1032
1033 pub fn wait_async_fd_events(
1042 &self,
1043 waiter: &Waiter,
1044 events: FdEvents,
1045 handler: EventHandler,
1046 ) -> WaitCanceler {
1047 let entry = waiter.create_wait_entry_with_handler(WaitEvents::Fd(events), handler);
1048 self.wait_async_entry(waiter, entry)
1049 }
1050
1051 pub fn wait_async_signal_mask(
1060 &self,
1061 waiter: &Waiter,
1062 mask: SigSet,
1063 handler: EventHandler,
1064 ) -> WaitCanceler {
1065 let entry = waiter.create_wait_entry_with_handler(WaitEvents::SignalMask(mask), handler);
1066 self.wait_async_entry(waiter, entry)
1067 }
1068
1069 pub fn wait_async(&self, waiter: &Waiter) -> WaitCanceler {
1078 self.wait_async_entry(waiter, waiter.create_wait_entry(WaitEvents::All))
1079 }
1080
1081 pub fn wait_async_simple(&self, waiter: &mut SimpleWaiter) {
1082 let entry = WaitEntry {
1083 waiter: WaiterRef::from_event(&waiter.event),
1084 filter: WaitEvents::All,
1085 key: Default::default(),
1086 };
1087 waiter.wait_queues.push(Arc::downgrade(&self.0));
1088 self.add_waiter(entry);
1089 }
1090
1091 fn notify_events_count(&self, mut events: WaitEvents, mut limit: usize) -> usize {
1092 if let WaitEvents::Fd(ref mut fd_events) = events {
1093 *fd_events = fd_events.add_equivalent_fd_events();
1094 }
1095 let mut notifiable_refs = SmallVec::<[(NotifiableRef, WaitKey); 1]>::new();
1101 let mut woken = 0;
1102 {
1103 let mut guard = self.0.lock();
1104 guard.waiters.retain(|_, WaitEntryWithId { entry, id: _ }| {
1105 if limit > 0 && entry.filter.intercept(&events) {
1106 if let Some(notifiable_ref) = entry.waiter.upgrade_notifiable() {
1107 limit -= 1;
1108 woken += 1;
1109 notifiable_refs.push((notifiable_ref, entry.key));
1110 }
1111
1112 entry.waiter.will_remove_from_wait_queue(&entry.key);
1113 false
1114 } else {
1115 true
1116 }
1117 });
1118 }
1119 for (notifiable_ref, key) in notifiable_refs {
1120 notifiable_ref.notify(&key, events);
1121 }
1122 woken
1123 }
1124
1125 pub fn notify_fd_events(&self, events: FdEvents) {
1126 self.notify_events_count(WaitEvents::Fd(events), usize::MAX);
1127 }
1128
1129 pub fn notify_fd_events_count(&self, events: FdEvents, limit: usize) {
1130 self.notify_events_count(WaitEvents::Fd(events), limit);
1131 }
1132
1133 pub fn notify_signal(&self, signal: &Signal) {
1134 let event = WaitEvents::SignalMask(SigSet::from(*signal));
1135 self.notify_events_count(event, usize::MAX);
1136 }
1137
1138 pub fn notify_value(&self, value: u64) {
1139 self.notify_events_count(WaitEvents::Value(value), usize::MAX);
1140 }
1141
1142 pub fn notify_unordered_count(&self, limit: usize) {
1143 self.notify_events_count(WaitEvents::All, limit);
1144 }
1145
1146 pub fn notify_all(&self) {
1147 self.notify_unordered_count(usize::MAX);
1148 }
1149
1150 pub fn is_empty(&self) -> bool {
1152 self.0.lock().waiters.is_empty()
1153 }
1154}
1155
1156pub struct TypedWaitQueue<T: Into<u64>> {
1158 wait_queue: WaitQueue,
1159 value_type: std::marker::PhantomData<T>,
1160}
1161
1162impl<T: Into<u64>> Default for TypedWaitQueue<T> {
1164 fn default() -> Self {
1165 Self { wait_queue: Default::default(), value_type: Default::default() }
1166 }
1167}
1168
1169impl<T: Into<u64>> TypedWaitQueue<T> {
1170 pub fn wait_async_value(&self, waiter: &Waiter, value: T) -> WaitCanceler {
1171 self.wait_queue.wait_async_value(waiter, value.into())
1172 }
1173
1174 pub fn wait_async_value_with_handler(
1175 &self,
1176 waiter: &Waiter,
1177 value: T,
1178 handler: EventHandler,
1179 ) -> WaitCanceler {
1180 self.wait_queue.wait_async_value_with_handler(waiter, value.into(), handler)
1181 }
1182
1183 pub fn notify_value(&self, value: T) {
1184 self.wait_queue.notify_value(value.into())
1185 }
1186}
1187
1188#[cfg(test)]
1189mod tests {
1190 use super::*;
1191 use crate::fs::fuchsia::create_fuchsia_pipe;
1192 use crate::signals::SignalInfo;
1193 use crate::task::{TaskFlags, TaskStateCode};
1194 use crate::testing::{spawn_kernel_and_run, spawn_kernel_and_run_sync};
1195 use crate::vfs::buffers::{VecInputBuffer, VecOutputBuffer};
1196 use crate::vfs::eventfd::{EventFdType, new_eventfd};
1197 use assert_matches::assert_matches;
1198 use starnix_uapi::open_flags::OpenFlags;
1199 use starnix_uapi::signals::SIGUSR1;
1200
1201 const KEY: ReadyItemKey = ReadyItemKey::Usize(1234);
1202
1203 #[::fuchsia::test]
1204 async fn test_async_wait_exec() {
1205 spawn_kernel_and_run(async |current_task| {
1206 let (local_socket, remote_socket) = zx::Socket::create_stream();
1207 let pipe = create_fuchsia_pipe(¤t_task, remote_socket, OpenFlags::RDWR).unwrap();
1208
1209 const MEM_SIZE: usize = 1024;
1210 let mut output_buffer = VecOutputBuffer::new(MEM_SIZE);
1211
1212 let test_string = "hello startnix".to_string();
1213 let queue: Arc<LockDepMutex<VecDeque<ReadyItem>, EventHandlerReadyQueueLock>> =
1214 Default::default();
1215 let handler = EventHandler::Enqueue {
1216 key: KEY,
1217 queue: queue.clone(),
1218 sought_events: FdEvents::all(),
1219 };
1220 let waiter = Waiter::new();
1221 pipe.wait_async(¤t_task, &waiter, FdEvents::POLLIN, handler).expect("wait_async");
1222 let test_string_clone = test_string.clone();
1223
1224 let write_count = AtomicCounter::<usize>::default();
1225 std::thread::scope(|s| {
1226 let thread = s.spawn(|| {
1227 let test_data = test_string_clone.as_bytes();
1228 let no_written = local_socket.write(test_data).unwrap();
1229 assert_eq!(0, write_count.add(no_written));
1230 assert_eq!(no_written, test_data.len());
1231 });
1232
1233 assert!(queue.lock().is_empty());
1236 waiter.wait(¤t_task).unwrap();
1237 thread.join().expect("join thread")
1238 });
1239 queue.lock().iter().for_each(|item| assert!(item.events.contains(FdEvents::POLLIN)));
1240
1241 let read_size = pipe.read(¤t_task, &mut output_buffer).unwrap();
1242
1243 let no_written = write_count.get();
1244 assert_eq!(no_written, read_size);
1245
1246 assert_eq!(output_buffer.data(), test_string.as_bytes());
1247 })
1248 .await;
1249 }
1250
1251 #[::fuchsia::test]
1252 async fn test_async_wait_cancel() {
1253 for do_cancel in [true, false] {
1254 spawn_kernel_and_run(async move |current_task| {
1255 let event = new_eventfd(¤t_task, 0, EventFdType::Counter, true);
1256 let waiter = Waiter::new();
1257 let queue: Arc<LockDepMutex<VecDeque<ReadyItem>, EventHandlerReadyQueueLock>> =
1258 Default::default();
1259 let handler = EventHandler::Enqueue {
1260 key: KEY,
1261 queue: queue.clone(),
1262 sought_events: FdEvents::all(),
1263 };
1264 let wait_canceler = event
1265 .wait_async(¤t_task, &waiter, FdEvents::POLLIN, handler)
1266 .expect("wait_async");
1267 if do_cancel {
1268 wait_canceler.cancel();
1269 }
1270 let add_val = 1u64;
1271 assert_eq!(
1272 event
1273 .write(¤t_task, &mut VecInputBuffer::new(&add_val.to_ne_bytes()))
1274 .unwrap(),
1275 std::mem::size_of::<u64>()
1276 );
1277
1278 let wait_result = waiter.wait_until(¤t_task, zx::MonotonicInstant::ZERO);
1279 let final_count = queue.lock().len();
1280 if do_cancel {
1281 assert_eq!(wait_result, error!(ETIMEDOUT));
1282 assert_eq!(0, final_count);
1283 } else {
1284 assert_eq!(wait_result, Ok(()));
1285 assert_eq!(1, final_count);
1286 }
1287 })
1288 .await;
1289 }
1290 }
1291
1292 #[::fuchsia::test]
1293 async fn single_waiter_multiple_waits_cancel_one_waiter_still_notified() {
1294 spawn_kernel_and_run(async |current_task| {
1295 let wait_queue = WaitQueue::default();
1296 let waiter = Waiter::new();
1297 let wk1 = wait_queue.wait_async(&waiter);
1298 let _wk2 = wait_queue.wait_async(&waiter);
1299 wk1.cancel();
1300 wait_queue.notify_all();
1301 assert!(waiter.wait_until(¤t_task, zx::MonotonicInstant::ZERO).is_ok());
1302 })
1303 .await;
1304 }
1305
1306 #[::fuchsia::test]
1307 async fn multiple_waiters_cancel_one_other_still_notified() {
1308 spawn_kernel_and_run(async |current_task| {
1309 let wait_queue = WaitQueue::default();
1310 let waiter1 = Waiter::new();
1311 let waiter2 = Waiter::new();
1312 let wk1 = wait_queue.wait_async(&waiter1);
1313 let _wk2 = wait_queue.wait_async(&waiter2);
1314 wk1.cancel();
1315 wait_queue.notify_all();
1316 assert!(waiter1.wait_until(¤t_task, zx::MonotonicInstant::ZERO).is_err());
1317 assert!(waiter2.wait_until(¤t_task, zx::MonotonicInstant::ZERO).is_ok());
1318 })
1319 .await;
1320 }
1321
1322 #[::fuchsia::test]
1323 async fn test_wait_queue() {
1324 spawn_kernel_and_run(async |current_task| {
1325 let queue = WaitQueue::default();
1326
1327 let waiters = <[Waiter; 3]>::default();
1328 waiters.iter().for_each(|w| {
1329 queue.wait_async(w);
1330 });
1331
1332 let woken = || {
1333 waiters
1334 .iter()
1335 .filter(|w| w.wait_until(¤t_task, zx::MonotonicInstant::ZERO).is_ok())
1336 .count()
1337 };
1338
1339 const INITIAL_NOTIFY_COUNT: usize = 2;
1340 let total_waiters = waiters.len();
1341 queue.notify_unordered_count(INITIAL_NOTIFY_COUNT);
1342 assert_eq!(INITIAL_NOTIFY_COUNT, woken());
1343
1344 queue.notify_all();
1346 assert_eq!(total_waiters - INITIAL_NOTIFY_COUNT, woken());
1347 })
1348 .await;
1349 }
1350
1351 #[::fuchsia::test]
1352 async fn waiter_kind_abort_handle() {
1353 spawn_kernel_and_run_sync(|current_task| {
1354 let mut executor = fuchsia_async::TestExecutor::new();
1355 let (abort_handle, abort_registration) = futures::stream::AbortHandle::new_pair();
1356 let abort_handle = Arc::new(abort_handle);
1357 let waiter_ref = WaiterRef::from_abort_handle(&abort_handle);
1358
1359 let mut fut = futures::stream::Abortable::new(
1360 futures::future::pending::<()>(),
1361 abort_registration,
1362 );
1363
1364 assert_matches!(executor.run_until_stalled(&mut fut), std::task::Poll::Pending);
1365
1366 waiter_ref.interrupt();
1367 let output = current_task.run_in_state(RunState::Waiter(waiter_ref), move || {
1368 match executor.run_singlethreaded(&mut fut) {
1369 Ok(()) => unreachable!("future never terminates normally"),
1370 Err(futures::stream::Aborted) => Ok(()),
1371 }
1372 });
1373
1374 assert_eq!(output, Ok(()));
1375 })
1376 .await;
1377 }
1378
1379 #[::fuchsia::test]
1380 async fn freeze_with_pending_sigusr1() {
1381 spawn_kernel_and_run(async |current_task| {
1382 {
1383 let mut task_state = current_task.task.write();
1384 let siginfo = SignalInfo::kernel(SIGUSR1);
1385 task_state.enqueue_signal(siginfo);
1386 task_state.set_flags(TaskFlags::SIGNALS_AVAILABLE, true);
1387 }
1388
1389 let output: Result<(), Errno> = current_task
1390 .run_in_state(RunState::Event(InterruptibleEvent::new()), move || {
1391 unreachable!("callback should not be called")
1392 });
1393 assert_eq!(output, error!(EINTR));
1394
1395 let output = current_task.run_in_state(RunState::Frozen(Waiter::new()), move || Ok(()));
1396 assert_eq!(output, Ok(()));
1397 })
1398 .await;
1399 }
1400
1401 #[::fuchsia::test]
1402 async fn freeze_with_pending_sigkill() {
1403 spawn_kernel_and_run(async |current_task| {
1404 {
1405 let mut task_state = current_task.task.write();
1406 let siginfo = SignalInfo::kernel(SIGKILL);
1407 task_state.enqueue_signal(siginfo);
1408 task_state.set_flags(TaskFlags::SIGNALS_AVAILABLE, true);
1409 }
1410
1411 let output: Result<(), _> = current_task
1412 .run_in_state(RunState::Frozen(Waiter::new()), move || {
1413 unreachable!("callback should not be called")
1414 });
1415 assert_eq!(output, error!(EINTR));
1416 })
1417 .await;
1418 }
1419
1420 #[::fuchsia::test]
1421 async fn tracing_stopped_with_pending_sigusr1() {
1422 spawn_kernel_and_run(async |current_task| {
1423 {
1424 let mut task_state = current_task.task.write();
1425 let siginfo = SignalInfo::kernel(SIGUSR1);
1426 task_state.enqueue_signal(siginfo);
1427 }
1428
1429 let task = Arc::clone(¤t_task.task);
1430 let output = current_task.run_in_state(RunState::TracingStopped, move || {
1431 assert_eq!(task.state_code(), TaskStateCode::TracingStop);
1432 Ok(())
1433 });
1434 assert_eq!(output, Ok(()));
1435 assert_eq!(current_task.task.state_code(), TaskStateCode::Running);
1436
1437 let waiter = Waiter::new();
1438 waiter.notify();
1439 waiter.stop(¤t_task);
1440 })
1441 .await;
1442 }
1443
1444 #[::fuchsia::test]
1445 async fn tracing_stopped_with_pending_sigkill() {
1446 spawn_kernel_and_run(async |current_task| {
1447 {
1448 let mut task_state = current_task.task.write();
1449 let siginfo = SignalInfo::kernel(SIGKILL);
1450 task_state.enqueue_signal(siginfo);
1451 }
1452
1453 let output: Result<(), _> = current_task
1454 .run_in_state(RunState::TracingStopped, move || {
1455 unreachable!("callback should not be called")
1456 });
1457 assert_eq!(output, error!(EINTR));
1458
1459 let waiter = Waiter::new();
1460 waiter.stop(¤t_task);
1461 })
1462 .await;
1463 }
1464
1465 #[::fuchsia::test]
1466 async fn wait_while_stopping_returns_eintr() {
1467 spawn_kernel_and_run(async |current_task| {
1468 current_task.write().set_stopped(
1469 crate::ptrace::StopState::GroupStopping,
1470 None,
1471 Some(current_task),
1472 None,
1473 );
1474
1475 let output: Result<(), Errno> = current_task
1476 .run_in_state(RunState::Event(InterruptibleEvent::new()), move || {
1477 unreachable!("callback should not be called")
1478 });
1479 assert_eq!(output, error!(EINTR));
1480 })
1481 .await;
1482 }
1483
1484 #[::fuchsia::test]
1485 async fn test_async_typed_wait_value_with_handler() {
1486 spawn_kernel_and_run(async |current_task| {
1487 let queue: Arc<LockDepMutex<VecDeque<ReadyItem>, EventHandlerReadyQueueLock>> =
1488 Default::default();
1489 let handler = EventHandler::Enqueue {
1490 key: KEY,
1491 queue: queue.clone(),
1492 sought_events: FdEvents::all(),
1493 };
1494 let waiter = Waiter::new();
1495 let wait_queue = TypedWaitQueue::<u64>::default();
1496
1497 let test_value = 100u64;
1498 let _wait_canceler =
1499 wait_queue.wait_async_value_with_handler(&waiter, test_value, handler);
1500
1501 assert!(queue.lock().is_empty());
1502
1503 wait_queue.notify_value(test_value + 1);
1505 assert!(queue.lock().is_empty());
1506
1507 wait_queue.notify_value(test_value);
1509
1510 waiter.wait(¤t_task).expect("wait failed");
1511
1512 let ready_items = queue.lock();
1514 assert_eq!(ready_items.len(), 1);
1515 assert!(ready_items[0].events.contains(FdEvents::POLLIN));
1516 })
1517 .await;
1518 }
1519}