1use crate::task::{CurrentTask, RunState};
6use crate::vfs::{EpollEventHandler, FdNumber};
7use bitflags::bitflags;
8use futures::stream::AbortHandle;
9use rustc_hash::FxHashMap;
10use slab::Slab;
11use smallvec::SmallVec;
12use starnix_lifecycle::AtomicCounter;
13use starnix_sync::{
14 EventHandlerReadyQueueLock, EventWaitGuard, InterruptibleEvent, LockDepMutex, NotifyKind,
15 ObjectWaitGuard, ObjectWaiter, PortEvent, PortWaitResult, PortWaiterCallbacksLock,
16 PortWaiterWaitQueuesLock, WaitQueueImplLock, WaiterEventHandlerLock,
17};
18use starnix_types::ownership::debug_assert_no_local_temp_ref;
19use starnix_uapi::error;
20use starnix_uapi::errors::{EINTR, Errno};
21use starnix_uapi::signals::{SIGKILL, SigSet, Signal};
22use starnix_uapi::vfs::FdEvents;
23use std::collections::VecDeque;
24use std::sync::{Arc, Weak};
25use syncio::zxio::zxio_signals_t;
26use syncio::{ZxioSignals, ZxioWeak};
27
28#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
29pub enum ReadyItemKey {
30 FdNumber(FdNumber),
31 Usize(usize),
32}
33
34impl From<FdNumber> for ReadyItemKey {
35 fn from(v: FdNumber) -> Self {
36 Self::FdNumber(v)
37 }
38}
39
40impl From<usize> for ReadyItemKey {
41 fn from(v: usize) -> Self {
42 Self::Usize(v)
43 }
44}
45
46#[derive(Debug, Copy, Clone)]
47pub struct ReadyItem {
48 pub key: ReadyItemKey,
49 pub events: FdEvents,
50}
51
52#[derive(Clone)]
53pub enum EventHandler {
54 None,
59
60 Enqueue {
65 key: ReadyItemKey,
66 queue: Arc<LockDepMutex<VecDeque<ReadyItem>, EventHandlerReadyQueueLock>>,
67 sought_events: FdEvents,
68 },
69
70 HandleOnce(Arc<LockDepMutex<Option<EventHandler>, WaiterEventHandlerLock>>),
75
76 Epoll(EpollEventHandler),
78}
79
80impl EventHandler {
81 pub fn handle(self, events: FdEvents) {
82 match self {
83 Self::None => {}
84 Self::Enqueue { key, queue, sought_events } => {
85 let events = events & sought_events;
86 queue.lock().push_back(ReadyItem { key, events });
87 }
88 Self::HandleOnce(inner) => {
89 if let Some(inner) = inner.lock().take() {
90 inner.handle(events);
91 }
92 }
93 Self::Epoll(e) => e.handle(events),
94 }
95 }
96}
97
98pub struct ZxioSignalHandler {
99 pub zxio: ZxioWeak,
100 pub get_events_from_zxio_signals: fn(zxio_signals_t) -> FdEvents,
101}
102
103pub struct ManyZxHandleSignalHandler {
106 pub count: usize,
107 pub counter: Arc<AtomicCounter<usize>>,
108 pub expected_signals: zx::Signals,
109 pub events: FdEvents,
110}
111
112pub enum SignalHandlerInner {
113 None,
114 Zxio(ZxioSignalHandler),
115 ZxHandle(fn(zx::Signals) -> FdEvents),
116 ManyZxHandle(ManyZxHandleSignalHandler),
117}
118
119pub struct SignalHandler {
120 pub inner: SignalHandlerInner,
121 pub event_handler: EventHandler,
122 pub err_code: Option<Errno>,
123}
124
125impl SignalHandler {
126 fn handle(self, signals: zx::Signals) -> Option<Errno> {
127 let SignalHandler { inner, event_handler, err_code } = self;
128 let events = match inner {
129 SignalHandlerInner::None => None,
130 SignalHandlerInner::Zxio(ZxioSignalHandler { zxio, get_events_from_zxio_signals }) => {
131 if let Some(zxio) = zxio.upgrade() {
132 Some(get_events_from_zxio_signals(zxio.wait_end(signals)))
133 } else {
134 None
135 }
136 }
137 SignalHandlerInner::ZxHandle(get_events_from_zx_signals) => {
138 Some(get_events_from_zx_signals(signals))
139 }
140 SignalHandlerInner::ManyZxHandle(signal_handler) => {
141 if signals.contains(signal_handler.expected_signals) {
142 let new_count = signal_handler.counter.next() + 1;
143 assert!(new_count <= signal_handler.count);
144 if new_count == signal_handler.count {
145 Some(signal_handler.events)
146 } else {
147 None
148 }
149 } else {
150 None
151 }
152 }
153 };
154 if let Some(events) = events {
155 event_handler.handle(events)
156 }
157 err_code
158 }
159}
160
161pub enum WaitCallback {
162 SignalHandler(SignalHandler),
163 EventHandler(EventHandler),
164}
165
166struct WaitCancelerQueue {
167 wait_queue: Weak<LockDepMutex<WaitQueueImpl, WaitQueueImplLock>>,
168 waiter: WaiterRef,
169 wait_key: WaitKey,
170 waiter_id: WaitEntryId,
171}
172
173struct WaitCancelerZxio {
174 zxio: ZxioWeak,
175 inner: PortWaitCanceler,
176}
177
178struct WaitCancelerPort {
179 inner: PortWaitCanceler,
180}
181
182enum WaitCancelerInner {
183 Zxio(WaitCancelerZxio),
184 Queue(WaitCancelerQueue),
185 Port(WaitCancelerPort),
186}
187
188enum NotifiableRef {
189 Port(Arc<PortWaiter>),
190 Event(Arc<InterruptibleEvent>),
191 AbortHandle(Arc<AbortHandle>),
192}
193
194const WAIT_CANCELER_COMMON_SIZE: usize = 2;
195
196pub struct WaitCanceler {
203 cancellers: smallvec::SmallVec<[WaitCancelerInner; WAIT_CANCELER_COMMON_SIZE]>,
204}
205
206impl WaitCanceler {
207 fn new_inner(inner: WaitCancelerInner) -> Self {
208 Self { cancellers: smallvec::smallvec![inner] }
209 }
210
211 pub fn new_noop() -> Self {
212 Self { cancellers: Default::default() }
213 }
214
215 pub fn new_zxio(zxio: ZxioWeak, inner: PortWaitCanceler) -> Self {
216 Self::new_inner(WaitCancelerInner::Zxio(WaitCancelerZxio { zxio, inner }))
217 }
218
219 pub fn new_port(inner: PortWaitCanceler) -> Self {
220 Self::new_inner(WaitCancelerInner::Port(WaitCancelerPort { inner }))
221 }
222
223 pub fn merge(self, other: Self) -> Self {
229 assert!(
232 self.cancellers.len() + other.cancellers.len() <= WAIT_CANCELER_COMMON_SIZE,
233 "WaitCanceler::merge disallows more than {} cancellers, found {} + {}",
234 WAIT_CANCELER_COMMON_SIZE,
235 self.cancellers.len(),
236 other.cancellers.len()
237 );
238 WaitCanceler::merge_unbounded(self, other)
239 }
240
241 pub fn merge_unbounded(
243 Self { mut cancellers }: Self,
244 Self { cancellers: mut other }: Self,
245 ) -> Self {
246 cancellers.append(&mut other);
247 WaitCanceler { cancellers }
248 }
249
250 pub fn cancel(self) {
254 let Self { cancellers } = self;
255 for canceller in cancellers.into_iter().rev() {
256 match canceller {
257 WaitCancelerInner::Zxio(WaitCancelerZxio { zxio, inner }) => {
258 let Some(zxio) = zxio.upgrade() else { return };
259 let (_, signals) = zxio.wait_begin(ZxioSignals::NONE.bits());
260 inner.cancel();
261 zxio.wait_end(signals);
262 }
263 WaitCancelerInner::Queue(WaitCancelerQueue {
264 wait_queue,
265 waiter,
266 wait_key,
267 waiter_id: WaitEntryId { key, id },
268 }) => {
269 let Some(wait_queue) = wait_queue.upgrade() else { return };
270 waiter.remove_callback(&wait_key);
271 waiter.will_remove_from_wait_queue(&wait_key);
272 let mut wait_queue = wait_queue.lock();
273 let waiters = &mut wait_queue.waiters;
274 if let Some(entry) = waiters.get_mut(key) {
275 if entry.id == id {
280 waiters.remove(key);
281 }
282 }
283 }
284 WaitCancelerInner::Port(WaitCancelerPort { inner }) => {
285 inner.cancel();
286 }
287 }
288 }
289 }
290}
291
292pub struct PortWaitCanceler {
299 waiter: Weak<PortWaiter>,
300 key: WaitKey,
301}
302
303impl PortWaitCanceler {
304 pub fn cancel(self) {
308 let Self { waiter, key } = self;
309 if let Some(waiter) = waiter.upgrade() {
310 let _ = waiter.port.cancel(key.raw);
311 waiter.remove_callback(&key);
312 }
313 }
314}
315
316#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
317struct WaitKey {
318 raw: u64,
319}
320
321#[derive(Clone, Copy, Debug)]
323enum WaitEvents {
324 All,
327 Fd(FdEvents),
329 Value(u64),
331 SignalMask(SigSet),
333}
334
335impl WaitEvents {
336 fn intercept(self: &WaitEvents, other: &WaitEvents) -> bool {
338 match (self, other) {
339 (Self::All, _) | (_, Self::All) => true,
340 (Self::Fd(m1), Self::Fd(m2)) => m1.bits() & m2.bits() != 0,
341 (Self::Value(v1), Self::Value(v2)) => v1 == v2,
342 (Self::SignalMask(m1), Self::SignalMask(m2)) => m1.intersects(m2),
344 _ => false,
345 }
346 }
347}
348
349impl WaitCallback {
350 pub fn none() -> EventHandler {
351 EventHandler::None
352 }
353}
354
355bitflags! {
356 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
357 pub struct WaiterOptions: u8 {
358 const UNSAFE_CALLSTACK = 1 << 0;
363 }
364}
365
366struct PortWaiter {
370 port: PortEvent,
371 callbacks: LockDepMutex<FxHashMap<WaitKey, WaitCallback>, PortWaiterCallbacksLock>, next_key: AtomicCounter<u64>,
375 options: WaiterOptions,
376
377 wait_queues: LockDepMutex<
382 FxHashMap<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(
430 self: &Arc<Self>,
431 current_task: &CurrentTask,
432 run_state: RunState,
433 deadline: zx::MonotonicInstant,
434 ) -> Result<(), Errno> {
435 let is_waiting = deadline.into_nanos() > 0;
436
437 let callback = || {
438 loop {
449 let wait_result = self.wait_internal(deadline);
450 if let Err(errno) = &wait_result {
451 if errno.code == EINTR && !is_waiting {
452 continue; }
454 }
455 return wait_result;
456 }
457 };
458
459 if !self.options.contains(WaiterOptions::UNSAFE_CALLSTACK) {
463 current_task.trigger_delayed_releaser();
464 }
465
466 if is_waiting { current_task.run_in_state(run_state, callback) } else { callback() }
467 }
468
469 fn next_key(&self) -> WaitKey {
470 let key = self.next_key.next();
471 assert!(key != 0, "bad key from u64 wraparound");
473 WaitKey { raw: key }
474 }
475
476 fn register_callback(&self, callback: WaitCallback) -> WaitKey {
477 let key = self.next_key();
478 assert!(
479 self.callbacks.lock().insert(key, callback).is_none(),
480 "unexpected callback already present for key {key:?}"
481 );
482 key
483 }
484
485 fn remove_callback(&self, key: &WaitKey) -> Option<WaitCallback> {
486 self.callbacks.lock().remove(&key)
487 }
488
489 fn wake_immediately(&self, events: FdEvents, handler: EventHandler) {
490 let callback = WaitCallback::EventHandler(handler);
491 let key = self.register_callback(callback);
492 self.queue_events(&key, WaitEvents::Fd(events));
493 }
494
495 fn wake_on_zircon_signals(
501 self: &Arc<Self>,
502 handle: &dyn zx::AsHandleRef,
503 zx_signals: zx::Signals,
504 handler: SignalHandler,
505 ) -> Result<PortWaitCanceler, zx::Status> {
506 let callback = WaitCallback::SignalHandler(handler);
507 let key = self.register_callback(callback);
508 self.port.object_wait_async(
509 handle,
510 key.raw,
511 zx_signals,
512 zx::WaitAsyncOpts::EDGE_TRIGGERED,
513 )?;
514 Ok(PortWaitCanceler { waiter: Arc::downgrade(self), key })
515 }
516
517 fn queue_events(&self, key: &WaitKey, events: WaitEvents) {
518 scopeguard::defer! {
519 self.port.notify(NotifyKind::Regular)
520 }
521
522 let Some(callback) = self.remove_callback(key) else {
534 return;
535 };
536
537 match callback {
538 WaitCallback::EventHandler(handler) => {
539 let events = match events {
540 WaitEvents::All => FdEvents::all(),
543 WaitEvents::Fd(events) => events,
544 WaitEvents::SignalMask(_) => FdEvents::POLLIN,
545 WaitEvents::Value(_) => FdEvents::POLLIN,
546 };
547 handler.handle(events)
548 }
549 WaitCallback::SignalHandler(_) => {
550 panic!("wrong type of handler called")
551 }
552 }
553 }
554
555 fn notify(&self) {
556 self.port.notify(NotifyKind::Regular);
557 }
558
559 fn interrupt(&self) {
560 self.port.notify(NotifyKind::Interrupt);
561 }
562}
563
564impl std::fmt::Debug for PortWaiter {
565 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
566 f.debug_struct("PortWaiter").field("port", &self.port).finish_non_exhaustive()
567 }
568}
569
570#[derive(Debug, Clone)]
572pub struct Waiter {
573 inner: Arc<PortWaiter>,
576}
577
578impl Waiter {
579 pub fn new() -> Self {
581 Self { inner: PortWaiter::new(WaiterOptions::empty()) }
582 }
583
584 pub fn with_options(options: WaiterOptions) -> Self {
586 Self { inner: PortWaiter::new(options) }
587 }
588
589 fn weak(&self) -> WaiterRef {
591 WaiterRef::from_port(&self.inner)
592 }
593
594 pub fn freeze(&self, current_task: &CurrentTask) {
598 while self
599 .inner
600 .wait_until(
601 current_task,
602 RunState::Frozen(self.clone()),
603 zx::MonotonicInstant::INFINITE,
604 )
605 .is_err()
606 {
607 if current_task.is_exitted() || current_task.read().has_signal_pending(SIGKILL) {
609 break;
610 }
611 }
613 }
614
615 pub fn stop(&self, current_task: &CurrentTask) {
619 let _ = self.inner.wait_until(
623 current_task,
624 RunState::TracingStopped,
625 zx::MonotonicInstant::INFINITE,
626 );
627 }
628
629 pub fn wait(&self, current_task: &CurrentTask) -> Result<(), Errno> {
633 self.inner.wait_until(
634 current_task,
635 RunState::Waiter(WaiterRef::from_port(&self.inner)),
636 zx::MonotonicInstant::INFINITE,
637 )
638 }
639
640 pub fn wait_until(
663 &self,
664 current_task: &CurrentTask,
665 deadline: zx::MonotonicInstant,
666 ) -> Result<(), Errno> {
667 self.inner.wait_until(
668 current_task,
669 RunState::Waiter(WaiterRef::from_port(&self.inner)),
670 deadline,
671 )
672 }
673
674 fn create_wait_entry(&self, filter: WaitEvents) -> WaitEntry {
675 WaitEntry { waiter: self.weak(), filter, key: self.inner.next_key() }
676 }
677
678 fn create_wait_entry_with_handler(
679 &self,
680 filter: WaitEvents,
681 handler: EventHandler,
682 ) -> WaitEntry {
683 let key = self.inner.register_callback(WaitCallback::EventHandler(handler));
684 WaitEntry { waiter: self.weak(), filter, key }
685 }
686
687 pub fn wake_immediately(&self, events: FdEvents, handler: EventHandler) {
688 self.inner.wake_immediately(events, handler);
689 }
690
691 pub fn wake_on_zircon_signals(
696 &self,
697 handle: &dyn zx::AsHandleRef,
698 zx_signals: zx::Signals,
699 handler: SignalHandler,
700 ) -> Result<PortWaitCanceler, zx::Status> {
701 self.inner.wake_on_zircon_signals(handle, zx_signals, handler)
702 }
703
704 pub fn fake_wait(&self) -> WaitCanceler {
708 WaitCanceler::new_noop()
709 }
710
711 pub fn notify(&self) {
713 self.inner.notify();
714 }
715
716 pub fn interrupt(&self) {
720 self.inner.interrupt();
721 }
722}
723
724impl Drop for Waiter {
725 fn drop(&mut self) {
726 let wait_queues = std::mem::take(&mut *self.inner.wait_queues.lock()).into_values();
729 for wait_queue in wait_queues {
730 if let Some(wait_queue) = wait_queue.upgrade() {
731 wait_queue.lock().waiters.retain(|_, entry| entry.entry.waiter != *self)
732 }
733 }
734 }
735}
736
737impl Default for Waiter {
738 fn default() -> Self {
739 Self::new()
740 }
741}
742
743impl PartialEq for Waiter {
744 fn eq(&self, other: &Self) -> bool {
745 Arc::ptr_eq(&self.inner, &other.inner)
746 }
747}
748
749pub struct SimpleWaiter {
750 event: Arc<InterruptibleEvent>,
751 wait_queues: Vec<Weak<LockDepMutex<WaitQueueImpl, WaitQueueImplLock>>>,
752}
753
754impl SimpleWaiter {
755 pub fn new(event: &Arc<InterruptibleEvent>) -> (SimpleWaiter, EventWaitGuard<'_>) {
756 (SimpleWaiter { event: event.clone(), wait_queues: Default::default() }, event.begin_wait())
757 }
758}
759
760impl Drop for SimpleWaiter {
761 fn drop(&mut self) {
762 for wait_queue in &self.wait_queues {
763 if let Some(wait_queue) = wait_queue.upgrade() {
764 wait_queue.lock().waiters.retain(|_, entry| entry.entry.waiter != self.event)
765 }
766 }
767 }
768}
769
770#[derive(Debug, Clone)]
771enum WaiterKind {
772 Port(Weak<PortWaiter>),
773 Event(Weak<InterruptibleEvent>),
774 AbortHandle(Weak<futures::stream::AbortHandle>),
775 ObjectWaiter(Weak<ObjectWaiter>),
776}
777
778impl Default for WaiterKind {
779 fn default() -> Self {
780 WaiterKind::Port(Default::default())
781 }
782}
783
784#[derive(Debug, Default, Clone)]
787pub struct WaiterRef(WaiterKind);
788
789impl WaiterRef {
790 fn from_port(waiter: &Arc<PortWaiter>) -> WaiterRef {
791 WaiterRef(WaiterKind::Port(Arc::downgrade(waiter)))
792 }
793
794 fn from_event(event: &Arc<InterruptibleEvent>) -> WaiterRef {
795 WaiterRef(WaiterKind::Event(Arc::downgrade(event)))
796 }
797
798 pub fn from_abort_handle(handle: &Arc<futures::stream::AbortHandle>) -> WaiterRef {
799 WaiterRef(WaiterKind::AbortHandle(Arc::downgrade(handle)))
800 }
801
802 pub fn from_object_waiter(guard: &ObjectWaitGuard<'_>) -> WaiterRef {
811 WaiterRef(WaiterKind::ObjectWaiter(Arc::downgrade(guard.waiter())))
812 }
813
814 pub fn is_valid(&self) -> bool {
815 match &self.0 {
816 WaiterKind::Port(waiter) => waiter.strong_count() != 0,
817 WaiterKind::Event(event) => event.strong_count() != 0,
818 WaiterKind::AbortHandle(handle) => handle.strong_count() != 0,
819 WaiterKind::ObjectWaiter(waiter) => waiter.strong_count() != 0,
820 }
821 }
822
823 pub fn interrupt(&self) {
824 match &self.0 {
825 WaiterKind::Port(waiter) => {
826 if let Some(waiter) = waiter.upgrade() {
827 waiter.interrupt();
828 }
829 }
830 WaiterKind::Event(event) => {
831 if let Some(event) = event.upgrade() {
832 event.interrupt();
833 }
834 }
835 WaiterKind::AbortHandle(handle) => {
836 if let Some(handle) = handle.upgrade() {
837 handle.abort();
838 }
839 }
840 WaiterKind::ObjectWaiter(waiter) => {
841 if let Some(waiter) = waiter.upgrade() {
842 waiter.interrupt();
843 }
844 }
845 }
846 }
847
848 fn remove_callback(&self, key: &WaitKey) {
849 match &self.0 {
850 WaiterKind::Port(waiter) => {
851 if let Some(waiter) = waiter.upgrade() {
852 waiter.remove_callback(key);
853 }
854 }
855 _ => (),
856 }
857 }
858
859 fn upgrade_notifiable(&self) -> Option<NotifiableRef> {
862 match &self.0 {
863 WaiterKind::Port(waiter) => {
864 if let Some(waiter) = waiter.upgrade() {
865 return Some(NotifiableRef::Port(waiter));
866 }
867 }
868 WaiterKind::Event(event) => {
869 if let Some(event) = event.upgrade() {
870 return Some(NotifiableRef::Event(event));
871 }
872 }
873 WaiterKind::AbortHandle(handle) => {
874 if let Some(handle) = handle.upgrade() {
875 return Some(NotifiableRef::AbortHandle(handle));
876 }
877 }
878 WaiterKind::ObjectWaiter(_) => (),
880 }
881 None
882 }
883
884 fn will_remove_from_wait_queue(&self, key: &WaitKey) {
889 match &self.0 {
890 WaiterKind::Port(waiter) => {
891 if let Some(waiter) = waiter.upgrade() {
892 waiter.wait_queues.lock().remove(key);
893 }
894 }
895 _ => (),
896 }
897 }
898}
899
900impl PartialEq<Waiter> for WaiterRef {
901 fn eq(&self, other: &Waiter) -> bool {
902 match &self.0 {
903 WaiterKind::Port(waiter) => waiter.as_ptr() == Arc::as_ptr(&other.inner),
904 _ => false,
905 }
906 }
907}
908
909impl PartialEq<Arc<InterruptibleEvent>> for WaiterRef {
910 fn eq(&self, other: &Arc<InterruptibleEvent>) -> bool {
911 match &self.0 {
912 WaiterKind::Event(event) => event.as_ptr() == Arc::as_ptr(other),
913 _ => false,
914 }
915 }
916}
917
918impl PartialEq for WaiterRef {
919 fn eq(&self, other: &WaiterRef) -> bool {
920 match (&self.0, &other.0) {
921 (WaiterKind::Port(lhs), WaiterKind::Port(rhs)) => Weak::ptr_eq(lhs, rhs),
922 (WaiterKind::Event(lhs), WaiterKind::Event(rhs)) => Weak::ptr_eq(lhs, rhs),
923 (WaiterKind::AbortHandle(lhs), WaiterKind::AbortHandle(rhs)) => Weak::ptr_eq(lhs, rhs),
924 (WaiterKind::ObjectWaiter(lhs), WaiterKind::ObjectWaiter(rhs)) => {
925 Weak::ptr_eq(lhs, rhs)
926 }
927 _ => false,
928 }
929 }
930}
931
932impl NotifiableRef {
933 fn notify(&self, key: &WaitKey, events: WaitEvents) {
934 match self {
935 NotifiableRef::Port(port_waiter) => port_waiter.queue_events(key, events),
936 NotifiableRef::Event(interruptible_event) => interruptible_event.notify(),
937 NotifiableRef::AbortHandle(handle) => handle.abort(),
938 }
939 }
940}
941
942#[derive(Default, Debug, Clone)]
949pub struct WaitQueue(Arc<LockDepMutex<WaitQueueImpl, WaitQueueImplLock>>);
950
951impl WaitQueue {
952 pub fn new() -> Self {
953 Self(Arc::new(WaitQueueImpl::default().into()))
954 }
955}
956
957#[derive(Debug)]
958struct WaitEntryWithId {
959 entry: WaitEntry,
960 id: u64,
964}
965
966struct WaitEntryId {
967 key: usize,
968 id: u64,
969}
970
971#[derive(Default, Debug)]
972struct WaitQueueImpl {
973 next_wait_entry_id: u64,
979 waiters: Slab<WaitEntryWithId>,
983}
984
985#[derive(Debug)]
987struct WaitEntry {
988 waiter: WaiterRef,
990
991 filter: WaitEvents,
993
994 key: WaitKey,
996}
997
998impl WaitQueue {
999 fn add_waiter(&self, entry: WaitEntry) -> WaitEntryId {
1000 let mut wait_queue = self.0.lock();
1001 let id = wait_queue
1002 .next_wait_entry_id
1003 .checked_add(1)
1004 .expect("all possible wait entry ID values exhausted");
1005 wait_queue.next_wait_entry_id = id;
1006 WaitEntryId { key: wait_queue.waiters.insert(WaitEntryWithId { entry, id }), id }
1007 }
1008
1009 fn wait_async_entry(&self, waiter: &Waiter, entry: WaitEntry) -> WaitCanceler {
1018 let wait_key = entry.key;
1019 let waiter_id = self.add_waiter(entry);
1020 let wait_queue = Arc::downgrade(&self.0);
1021 waiter.inner.wait_queues.lock().insert(wait_key, wait_queue.clone());
1022 WaitCanceler::new_inner(WaitCancelerInner::Queue(WaitCancelerQueue {
1023 wait_queue,
1024 waiter: waiter.weak(),
1025 wait_key,
1026 waiter_id,
1027 }))
1028 }
1029
1030 pub fn wait_async_value(&self, waiter: &Waiter, value: u64) -> WaitCanceler {
1039 self.wait_async_entry(waiter, waiter.create_wait_entry(WaitEvents::Value(value)))
1040 }
1041
1042 pub fn wait_async_value_with_handler(
1051 &self,
1052 waiter: &Waiter,
1053 value: u64,
1054 handler: EventHandler,
1055 ) -> WaitCanceler {
1056 let entry = waiter.create_wait_entry_with_handler(WaitEvents::Value(value), handler);
1057 self.wait_async_entry(waiter, entry)
1058 }
1059
1060 pub fn wait_async_fd_events(
1069 &self,
1070 waiter: &Waiter,
1071 events: FdEvents,
1072 handler: EventHandler,
1073 ) -> WaitCanceler {
1074 let entry = waiter.create_wait_entry_with_handler(WaitEvents::Fd(events), handler);
1075 self.wait_async_entry(waiter, entry)
1076 }
1077
1078 pub fn wait_async_signal_mask(
1087 &self,
1088 waiter: &Waiter,
1089 mask: SigSet,
1090 handler: EventHandler,
1091 ) -> WaitCanceler {
1092 let entry = waiter.create_wait_entry_with_handler(WaitEvents::SignalMask(mask), handler);
1093 self.wait_async_entry(waiter, entry)
1094 }
1095
1096 pub fn wait_async(&self, waiter: &Waiter) -> WaitCanceler {
1105 self.wait_async_entry(waiter, waiter.create_wait_entry(WaitEvents::All))
1106 }
1107
1108 pub fn wait_async_simple(&self, waiter: &mut SimpleWaiter) {
1109 let entry = WaitEntry {
1110 waiter: WaiterRef::from_event(&waiter.event),
1111 filter: WaitEvents::All,
1112 key: Default::default(),
1113 };
1114 waiter.wait_queues.push(Arc::downgrade(&self.0));
1115 self.add_waiter(entry);
1116 }
1117
1118 fn notify_events_count(&self, mut events: WaitEvents, mut limit: usize) -> usize {
1119 if let WaitEvents::Fd(ref mut fd_events) = events {
1120 *fd_events = fd_events.add_equivalent_fd_events();
1121 }
1122 let mut notifiable_refs = SmallVec::<[(NotifiableRef, WaitKey); 1]>::new();
1128 let mut woken = 0;
1129 {
1130 let mut guard = self.0.lock();
1131 guard.waiters.retain(|_, WaitEntryWithId { entry, id: _ }| {
1132 if limit > 0 && entry.filter.intercept(&events) {
1133 if let Some(notifiable_ref) = entry.waiter.upgrade_notifiable() {
1134 limit -= 1;
1135 woken += 1;
1136 notifiable_refs.push((notifiable_ref, entry.key));
1137 }
1138
1139 entry.waiter.will_remove_from_wait_queue(&entry.key);
1140 false
1141 } else {
1142 true
1143 }
1144 });
1145 }
1146 for (notifiable_ref, key) in notifiable_refs {
1147 notifiable_ref.notify(&key, events);
1148 }
1149 woken
1150 }
1151
1152 pub fn notify_fd_events(&self, events: FdEvents) {
1153 self.notify_events_count(WaitEvents::Fd(events), usize::MAX);
1154 }
1155
1156 pub fn notify_fd_events_count(&self, events: FdEvents, limit: usize) {
1157 self.notify_events_count(WaitEvents::Fd(events), limit);
1158 }
1159
1160 pub fn notify_signal(&self, signal: &Signal) {
1161 let event = WaitEvents::SignalMask(SigSet::from(*signal));
1162 self.notify_events_count(event, usize::MAX);
1163 }
1164
1165 pub fn notify_value(&self, value: u64) {
1166 self.notify_events_count(WaitEvents::Value(value), usize::MAX);
1167 }
1168
1169 pub fn notify_unordered_count(&self, limit: usize) {
1170 self.notify_events_count(WaitEvents::All, limit);
1171 }
1172
1173 pub fn notify_all(&self) {
1174 self.notify_unordered_count(usize::MAX);
1175 }
1176
1177 pub fn is_empty(&self) -> bool {
1179 self.0.lock().waiters.is_empty()
1180 }
1181}
1182
1183pub struct TypedWaitQueue<T: Into<u64>> {
1185 wait_queue: WaitQueue,
1186 value_type: std::marker::PhantomData<T>,
1187}
1188
1189impl<T: Into<u64>> Default for TypedWaitQueue<T> {
1191 fn default() -> Self {
1192 Self { wait_queue: Default::default(), value_type: Default::default() }
1193 }
1194}
1195
1196impl<T: Into<u64>> TypedWaitQueue<T> {
1197 pub fn wait_async_value(&self, waiter: &Waiter, value: T) -> WaitCanceler {
1198 self.wait_queue.wait_async_value(waiter, value.into())
1199 }
1200
1201 pub fn wait_async_value_with_handler(
1202 &self,
1203 waiter: &Waiter,
1204 value: T,
1205 handler: EventHandler,
1206 ) -> WaitCanceler {
1207 self.wait_queue.wait_async_value_with_handler(waiter, value.into(), handler)
1208 }
1209
1210 pub fn notify_value(&self, value: T) {
1211 self.wait_queue.notify_value(value.into())
1212 }
1213}
1214
1215#[cfg(test)]
1216mod tests {
1217 use super::*;
1218 use crate::fs::fuchsia::create_fuchsia_pipe;
1219 use crate::signals::SignalInfo;
1220 use crate::task::{TaskFlags, TaskStateCode};
1221 use crate::testing::{spawn_kernel_and_run, spawn_kernel_and_run_sync};
1222 use crate::vfs::buffers::{VecInputBuffer, VecOutputBuffer};
1223 use crate::vfs::eventfd::{EventFdType, new_eventfd};
1224 use assert_matches::assert_matches;
1225 use starnix_sync::ObjectWaitError;
1226 use starnix_uapi::open_flags::OpenFlags;
1227 use starnix_uapi::signals::SIGUSR1;
1228
1229 const KEY: ReadyItemKey = ReadyItemKey::Usize(1234);
1230
1231 #[::fuchsia::test]
1232 async fn test_async_wait_exec() {
1233 spawn_kernel_and_run(async |current_task| {
1234 let (local_socket, remote_socket) = zx::Socket::create_stream();
1235 let pipe = create_fuchsia_pipe(¤t_task, remote_socket, OpenFlags::RDWR).unwrap();
1236
1237 const MEM_SIZE: usize = 1024;
1238 let mut output_buffer = VecOutputBuffer::new(MEM_SIZE);
1239
1240 let test_string = "hello startnix".to_string();
1241 let queue: Arc<LockDepMutex<VecDeque<ReadyItem>, EventHandlerReadyQueueLock>> =
1242 Default::default();
1243 let handler = EventHandler::Enqueue {
1244 key: KEY,
1245 queue: queue.clone(),
1246 sought_events: FdEvents::all(),
1247 };
1248 let waiter = Waiter::new();
1249 pipe.wait_async(¤t_task, &waiter, FdEvents::POLLIN, handler).expect("wait_async");
1250 let test_string_clone = test_string.clone();
1251
1252 let write_count = AtomicCounter::<usize>::default();
1253 std::thread::scope(|s| {
1254 let thread = s.spawn(|| {
1255 let test_data = test_string_clone.as_bytes();
1256 let no_written = local_socket.write(test_data).unwrap();
1257 assert_eq!(0, write_count.add(no_written));
1258 assert_eq!(no_written, test_data.len());
1259 });
1260
1261 assert!(queue.lock().is_empty());
1264 waiter.wait(¤t_task).unwrap();
1265 thread.join().expect("join thread")
1266 });
1267 queue.lock().iter().for_each(|item| assert!(item.events.contains(FdEvents::POLLIN)));
1268
1269 let read_size = pipe.read(¤t_task, &mut output_buffer).unwrap();
1270
1271 let no_written = write_count.get();
1272 assert_eq!(no_written, read_size);
1273
1274 assert_eq!(output_buffer.data(), test_string.as_bytes());
1275 })
1276 .await;
1277 }
1278
1279 #[::fuchsia::test]
1280 async fn test_async_wait_cancel() {
1281 for do_cancel in [true, false] {
1282 spawn_kernel_and_run(async move |current_task| {
1283 let event = new_eventfd(¤t_task, 0, EventFdType::Counter, true);
1284 let waiter = Waiter::new();
1285 let queue: Arc<LockDepMutex<VecDeque<ReadyItem>, EventHandlerReadyQueueLock>> =
1286 Default::default();
1287 let handler = EventHandler::Enqueue {
1288 key: KEY,
1289 queue: queue.clone(),
1290 sought_events: FdEvents::all(),
1291 };
1292 let wait_canceler = event
1293 .wait_async(¤t_task, &waiter, FdEvents::POLLIN, handler)
1294 .expect("wait_async");
1295 if do_cancel {
1296 wait_canceler.cancel();
1297 }
1298 let add_val = 1u64;
1299 assert_eq!(
1300 event
1301 .write(¤t_task, &mut VecInputBuffer::new(&add_val.to_ne_bytes()))
1302 .unwrap(),
1303 std::mem::size_of::<u64>()
1304 );
1305
1306 let wait_result = waiter.wait_until(¤t_task, zx::MonotonicInstant::ZERO);
1307 let final_count = queue.lock().len();
1308 if do_cancel {
1309 assert_eq!(wait_result, error!(ETIMEDOUT));
1310 assert_eq!(0, final_count);
1311 } else {
1312 assert_eq!(wait_result, Ok(()));
1313 assert_eq!(1, final_count);
1314 }
1315 })
1316 .await;
1317 }
1318 }
1319
1320 #[::fuchsia::test]
1321 async fn single_waiter_multiple_waits_cancel_one_waiter_still_notified() {
1322 spawn_kernel_and_run(async |current_task| {
1323 let wait_queue = WaitQueue::default();
1324 let waiter = Waiter::new();
1325 let wk1 = wait_queue.wait_async(&waiter);
1326 let _wk2 = wait_queue.wait_async(&waiter);
1327 wk1.cancel();
1328 wait_queue.notify_all();
1329 assert!(waiter.wait_until(¤t_task, zx::MonotonicInstant::ZERO).is_ok());
1330 })
1331 .await;
1332 }
1333
1334 #[::fuchsia::test]
1335 async fn multiple_waiters_cancel_one_other_still_notified() {
1336 spawn_kernel_and_run(async |current_task| {
1337 let wait_queue = WaitQueue::default();
1338 let waiter1 = Waiter::new();
1339 let waiter2 = Waiter::new();
1340 let wk1 = wait_queue.wait_async(&waiter1);
1341 let _wk2 = wait_queue.wait_async(&waiter2);
1342 wk1.cancel();
1343 wait_queue.notify_all();
1344 assert!(waiter1.wait_until(¤t_task, zx::MonotonicInstant::ZERO).is_err());
1345 assert!(waiter2.wait_until(¤t_task, zx::MonotonicInstant::ZERO).is_ok());
1346 })
1347 .await;
1348 }
1349
1350 #[::fuchsia::test]
1351 async fn test_wait_queue() {
1352 spawn_kernel_and_run(async |current_task| {
1353 let queue = WaitQueue::default();
1354
1355 let waiters = <[Waiter; 3]>::default();
1356 waiters.iter().for_each(|w| {
1357 queue.wait_async(w);
1358 });
1359
1360 let woken = || {
1361 waiters
1362 .iter()
1363 .filter(|w| w.wait_until(¤t_task, zx::MonotonicInstant::ZERO).is_ok())
1364 .count()
1365 };
1366
1367 const INITIAL_NOTIFY_COUNT: usize = 2;
1368 let total_waiters = waiters.len();
1369 queue.notify_unordered_count(INITIAL_NOTIFY_COUNT);
1370 assert_eq!(INITIAL_NOTIFY_COUNT, woken());
1371
1372 queue.notify_all();
1374 assert_eq!(total_waiters - INITIAL_NOTIFY_COUNT, woken());
1375 })
1376 .await;
1377 }
1378
1379 #[::fuchsia::test]
1380 async fn waiter_kind_abort_handle() {
1381 spawn_kernel_and_run_sync(|current_task| {
1382 let mut executor = fuchsia_async::TestExecutor::new();
1383 let (abort_handle, abort_registration) = futures::stream::AbortHandle::new_pair();
1384 let abort_handle = Arc::new(abort_handle);
1385 let waiter_ref = WaiterRef::from_abort_handle(&abort_handle);
1386
1387 let mut fut = futures::stream::Abortable::new(
1388 futures::future::pending::<()>(),
1389 abort_registration,
1390 );
1391
1392 assert_matches!(executor.run_until_stalled(&mut fut), std::task::Poll::Pending);
1393
1394 waiter_ref.interrupt();
1395 let output = current_task.run_in_state(RunState::Waiter(waiter_ref), move || {
1396 match executor.run_singlethreaded(&mut fut) {
1397 Ok(()) => unreachable!("future never terminates normally"),
1398 Err(futures::stream::Aborted) => Ok(()),
1399 }
1400 });
1401
1402 assert_eq!(output, Ok(()));
1403 })
1404 .await;
1405 }
1406
1407 #[::fuchsia::test]
1408 async fn waiter_kind_object_waiter() {
1409 spawn_kernel_and_run_sync(|current_task| {
1410 let waiter = ObjectWaiter::new();
1411 let event = zx::Event::create();
1412 let wait = |guard: ObjectWaitGuard<'_>| {
1414 let waiter_ref = WaiterRef::from_object_waiter(&guard);
1415 current_task.run_in_state(RunState::Waiter(waiter_ref), || {
1416 Ok(guard.wait_many(
1417 [event.wait_item(zx::Signals::USER_0)],
1418 zx::MonotonicInstant::INFINITE,
1419 ))
1420 })
1421 };
1422
1423 let task = current_task.task.clone();
1426 let thread = fuchsia_runtime::with_thread_self(|thread| {
1427 thread.duplicate_handle(zx::Rights::SAME_RIGHTS).expect("duplicate_handle")
1428 });
1429 let interrupter = std::thread::spawn(move || {
1430 while thread.info().expect("info").state
1431 != zx::ThreadState::Blocked(zx::ThreadBlockType::WaitMany)
1432 {
1433 std::thread::sleep(std::time::Duration::from_millis(1));
1434 }
1435 task.interrupt();
1436 });
1437 assert_eq!(wait(waiter.begin_wait()), Ok(Err(ObjectWaitError::Interrupted)));
1438 interrupter.join().expect("join");
1439
1440 let guard = waiter.begin_wait();
1443 let waiter_ref = WaiterRef::from_object_waiter(&guard);
1444 waiter_ref.interrupt();
1445 assert_eq!(wait(guard), Ok(Err(ObjectWaitError::Interrupted)));
1446
1447 event.signal(zx::Signals::NONE, zx::Signals::USER_0).expect("signal");
1450 assert_eq!(wait(waiter.begin_wait()), Ok(Ok([zx::Signals::USER_0])));
1451
1452 std::mem::drop(waiter);
1454 assert!(!waiter_ref.is_valid());
1455 })
1456 .await;
1457 }
1458
1459 #[::fuchsia::test]
1460 async fn freeze_with_pending_sigusr1() {
1461 spawn_kernel_and_run(async |current_task| {
1462 {
1463 let mut task_state = current_task.task.write();
1464 let siginfo = SignalInfo::kernel(SIGUSR1);
1465 task_state.enqueue_signal(siginfo);
1466 task_state.set_flags(TaskFlags::SIGNALS_AVAILABLE, true);
1467 }
1468
1469 let event = InterruptibleEvent::default();
1470 let output =
1471 current_task.block_until(event.begin_wait(), zx::MonotonicInstant::INFINITE);
1472 assert_eq!(output, error!(EINTR));
1473
1474 let output = current_task.run_in_state(RunState::Frozen(Waiter::new()), move || Ok(()));
1475 assert_eq!(output, Ok(()));
1476 })
1477 .await;
1478 }
1479
1480 #[::fuchsia::test]
1481 async fn block_until_stack_event_interrupted_by_other_thread() {
1482 spawn_kernel_and_run(async |current_task| {
1483 let task = Arc::clone(¤t_task.task);
1484 let interrupter = std::thread::spawn(move || {
1485 while !matches!(task.read().run_state(), RunState::Event(_)) {
1486 std::thread::yield_now();
1487 }
1488 task.interrupt();
1489 });
1490
1491 let event = InterruptibleEvent::default();
1492 let output =
1493 current_task.block_until(event.begin_wait(), zx::MonotonicInstant::INFINITE);
1494 assert_eq!(output, error!(EINTR));
1495 assert_eq!(current_task.read().run_state(), RunState::Running);
1496
1497 interrupter.join().expect("join interrupter");
1498 })
1499 .await;
1500 }
1501
1502 #[::fuchsia::test]
1503 async fn freeze_with_pending_sigkill() {
1504 spawn_kernel_and_run(async |current_task| {
1505 {
1506 let mut task_state = current_task.task.write();
1507 let siginfo = SignalInfo::kernel(SIGKILL);
1508 task_state.enqueue_signal(siginfo);
1509 task_state.set_flags(TaskFlags::SIGNALS_AVAILABLE, true);
1510 }
1511
1512 let output: Result<(), _> = current_task
1513 .run_in_state(RunState::Frozen(Waiter::new()), move || {
1514 unreachable!("callback should not be called")
1515 });
1516 assert_eq!(output, error!(EINTR));
1517 })
1518 .await;
1519 }
1520
1521 #[::fuchsia::test]
1522 async fn tracing_stopped_with_pending_sigusr1() {
1523 spawn_kernel_and_run(async |current_task| {
1524 {
1525 let mut task_state = current_task.task.write();
1526 let siginfo = SignalInfo::kernel(SIGUSR1);
1527 task_state.enqueue_signal(siginfo);
1528 }
1529
1530 let task = Arc::clone(¤t_task.task);
1531 let output = current_task.run_in_state(RunState::TracingStopped, move || {
1532 assert_eq!(task.state_code(), TaskStateCode::TracingStop);
1533 Ok(())
1534 });
1535 assert_eq!(output, Ok(()));
1536 assert_eq!(current_task.task.state_code(), TaskStateCode::Running);
1537
1538 let waiter = Waiter::new();
1539 waiter.notify();
1540 waiter.stop(¤t_task);
1541 })
1542 .await;
1543 }
1544
1545 #[::fuchsia::test]
1546 async fn tracing_stopped_with_pending_sigkill() {
1547 spawn_kernel_and_run(async |current_task| {
1548 {
1549 let mut task_state = current_task.task.write();
1550 let siginfo = SignalInfo::kernel(SIGKILL);
1551 task_state.enqueue_signal(siginfo);
1552 }
1553
1554 let output: Result<(), _> = current_task
1555 .run_in_state(RunState::TracingStopped, move || {
1556 unreachable!("callback should not be called")
1557 });
1558 assert_eq!(output, error!(EINTR));
1559
1560 let waiter = Waiter::new();
1561 waiter.stop(¤t_task);
1562 })
1563 .await;
1564 }
1565
1566 #[::fuchsia::test]
1567 async fn wait_while_stopping_returns_eintr() {
1568 spawn_kernel_and_run(async |current_task| {
1569 current_task.write().set_stopped(
1570 crate::ptrace::StopState::GroupStopping,
1571 None,
1572 Some(current_task),
1573 None,
1574 );
1575
1576 let event = InterruptibleEvent::default();
1577 let output =
1578 current_task.block_until(event.begin_wait(), zx::MonotonicInstant::INFINITE);
1579 assert_eq!(output, error!(EINTR));
1580 })
1581 .await;
1582 }
1583
1584 #[::fuchsia::test]
1585 async fn test_async_typed_wait_value_with_handler() {
1586 spawn_kernel_and_run(async |current_task| {
1587 let queue: Arc<LockDepMutex<VecDeque<ReadyItem>, EventHandlerReadyQueueLock>> =
1588 Default::default();
1589 let handler = EventHandler::Enqueue {
1590 key: KEY,
1591 queue: queue.clone(),
1592 sought_events: FdEvents::all(),
1593 };
1594 let waiter = Waiter::new();
1595 let wait_queue = TypedWaitQueue::<u64>::default();
1596
1597 let test_value = 100u64;
1598 let _wait_canceler =
1599 wait_queue.wait_async_value_with_handler(&waiter, test_value, handler);
1600
1601 assert!(queue.lock().is_empty());
1602
1603 wait_queue.notify_value(test_value + 1);
1605 assert!(queue.lock().is_empty());
1606
1607 wait_queue.notify_value(test_value);
1609
1610 waiter.wait(¤t_task).expect("wait failed");
1611
1612 let ready_items = queue.lock();
1614 assert_eq!(ready_items.len(), 1);
1615 assert!(ready_items[0].events.contains(FdEvents::POLLIN));
1616 })
1617 .await;
1618 }
1619}