1#![allow(unsafe_code)]
4
5use core::fmt;
6use core::future::Future;
7use core::pin::Pin;
8use core::task::{Context, Poll, Waker};
9use std::sync::Arc;
10
11use super::internal::{AtomicUsize, Ordering, UnsafeCell};
12use super::list::List;
13use super::queue::{Arrivals, FIRST_BIT, Policy, QUEUED, Step, WaitQueue};
14use super::waiter::{Cancel, Wait, WakeList, release_queued};
15
16const PERMIT: usize = 1 << FIRST_BIT;
19
20const BY_FIRST: usize = usize::MAX;
24
25const BY_LAST: usize = usize::MAX - 1;
28
29pub struct Notify {
57 queue: WaitQueue,
58 waiting: UnsafeCell<List>,
59 pending_first: AtomicUsize,
61 pending_last: AtomicUsize,
63 generation: AtomicUsize,
65}
66
67unsafe impl Send for Notify {}
69unsafe impl Sync for Notify {}
71
72impl Notify {
73 loom_const_fn! {
74 pub fn new() -> Self {
76 Self {
77 queue: WaitQueue::new(0),
78 waiting: UnsafeCell::new(List::new()),
79 pending_first: AtomicUsize::new(0),
80 pending_last: AtomicUsize::new(0),
81 generation: AtomicUsize::new(0),
82 }
83 }
84 }
85
86 loom_const_fn! {
87 pub fn const_new() -> Self {
90 Self::new()
91 }
92 }
93
94 pub fn notified(&self) -> Notified<'_> {
101 Notified {
102 notify: self,
103 core: Core::new(self),
104 }
105 }
106
107 pub fn notified_owned(self: Arc<Self>) -> OwnedNotified {
110 OwnedNotified {
111 core: Core::new(&self),
112 notify: self,
113 }
114 }
115
116 pub fn notify_one(&self) {
119 self.notify_with(&self.pending_first);
120 }
121
122 pub fn notify_last(&self) {
126 self.notify_with(&self.pending_last);
127 }
128
129 fn notify_with(&self, owed: &AtomicUsize) {
131 let before = self.transition(|state| {
132 if state & QUEUED != 0 {
133 Step::Keep
134 } else {
135 Step::Set(state | PERMIT)
136 }
137 });
138 if before & QUEUED == 0 {
139 return;
140 }
141 owed.fetch_add(1, Ordering::Release);
142 self.transition(Step::Drain);
143 }
144
145 pub fn notify_waiters(&self) {
148 self.generation.fetch_add(1, Ordering::Release);
149 self.transition(|state| {
153 if state & QUEUED != 0 {
154 Step::Drain(state)
155 } else {
156 Step::Set(state)
157 }
158 });
159 }
160
161 fn take_permit(&self) -> bool {
163 let before = self.transition(|state| {
164 if state & (QUEUED | PERMIT) == PERMIT {
165 Step::Set(state & !PERMIT)
166 } else {
167 Step::Keep
168 }
169 });
170 before & (QUEUED | PERMIT) == PERMIT
171 }
172
173 fn generation(&self) -> usize {
178 self.generation.load(Ordering::Acquire) & (usize::MAX >> 1)
179 }
180}
181
182impl Policy for Notify {
183 fn queue(&self) -> &WaitQueue {
184 &self.queue
185 }
186
187 fn pass(&self, arrivals: Arrivals, woken: &mut WakeList<'_>, _wake_front: bool) -> usize {
188 let pool = &self.queue;
189 let generation = self.generation();
192 self.waiting.with_mut(|waiting| unsafe {
194 let waiting = &mut *waiting;
195 while let Some(node) = waiting.front(pool) {
200 if node.as_ref().payload() == generation {
201 break;
202 }
203 waiting.pop_front();
204 woken.grant(node);
205 }
206 for node in arrivals {
211 if node.as_ref().is_cancelled() {
212 release_queued(node, pool);
213 } else if node.as_ref().payload() != generation {
214 woken.grant(node);
215 } else {
216 waiting.push_back(node);
217 }
218 }
219 waiting.tidy(&self.queue);
220 let mut first = self.pending_first.swap(0, Ordering::AcqRel);
221 let mut last = self.pending_last.swap(0, Ordering::AcqRel);
222 if waiting.front(pool).is_some()
223 && self.queue.state.fetch_and(!PERMIT, Ordering::AcqRel) & PERMIT != 0
224 {
225 first += 1;
226 }
227 while first > 0 {
228 let Some(node) = waiting.front(pool) else {
229 break;
230 };
231 waiting.pop_front();
232 node.as_ref().set_payload(BY_FIRST);
233 if woken.grant(node) {
234 first -= 1;
235 }
236 }
237 while last > 0 {
238 let Some(node) = waiting.back(pool) else {
239 break;
240 };
241 waiting.pop_back();
242 node.as_ref().set_payload(BY_LAST);
243 if woken.grant(node) {
244 last -= 1;
245 }
246 }
247 if first + last > 0 {
248 self.queue.state.fetch_or(PERMIT, Ordering::AcqRel);
249 }
250 if waiting.is_empty() { QUEUED } else { 0 }
251 })
252 }
253}
254
255impl Drop for Notify {
256 fn drop(&mut self) {
257 let pool = &self.queue;
258 self.waiting
260 .with_mut(|waiting| unsafe { (*waiting).clear(pool) });
261 }
262}
263
264impl Default for Notify {
265 fn default() -> Self {
266 Self::new()
267 }
268}
269
270impl fmt::Debug for Notify {
271 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
272 f.debug_struct("Notify").finish_non_exhaustive()
273 }
274}
275
276struct Core {
280 generation: usize,
281 wait: Wait,
282 done: bool,
283}
284
285impl Core {
286 fn new(notify: &Notify) -> Self {
287 Self {
288 generation: notify.generation(),
289 wait: Wait::new(),
290 done: false,
291 }
292 }
293
294 fn drive(&mut self, notify: &Notify, waker: Option<&Waker>) -> bool {
299 if self.done {
300 return true;
301 }
302 let ready = if self.wait.is_queued() {
303 match waker {
304 Some(waker) => self.wait.poll(¬ify.queue, Some(waker)).is_ready(),
305 None => self.wait.granted(¬ify.queue).is_some(),
307 }
308 } else if notify.generation() != self.generation || notify.take_permit() {
309 true
310 } else {
311 notify.enqueue(
312 &mut self.wait,
313 self.generation,
314 waker.unwrap_or(Waker::noop()),
315 );
316 self.wait.poll(¬ify.queue, None).is_ready()
317 };
318 self.done = ready;
319 ready
320 }
321
322 fn cancel(&mut self, notify: &Notify) {
325 match self.wait.cancel(¬ify.queue) {
326 Cancel::Idle => {}
327 Cancel::Withdrawn(_) => notify.withdrawn(false),
328 Cancel::Granted(BY_FIRST) => notify.notify_one(),
329 Cancel::Granted(BY_LAST) => notify.notify_last(),
330 Cancel::Granted(_) => {}
331 }
332 }
333}
334
335#[must_use = "futures do nothing unless polled"]
342pub struct Notified<'a> {
343 notify: &'a Notify,
344 core: Core,
345}
346
347impl Notified<'_> {
348 pub fn enable(self: Pin<&mut Self>) -> bool {
376 let this = self.get_mut();
377 this.core.drive(this.notify, None)
378 }
379}
380
381impl Future for Notified<'_> {
382 type Output = ();
383
384 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
385 let this = self.get_mut();
386 if this.core.drive(this.notify, Some(cx.waker())) {
387 Poll::Ready(())
388 } else {
389 Poll::Pending
390 }
391 }
392}
393
394impl Drop for Notified<'_> {
395 fn drop(&mut self) {
396 self.core.cancel(self.notify);
397 }
398}
399
400impl fmt::Debug for Notified<'_> {
401 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
402 f.debug_struct("Notified")
403 .field("done", &self.core.done)
404 .finish()
405 }
406}
407
408#[must_use = "futures do nothing unless polled"]
411pub struct OwnedNotified {
412 notify: Arc<Notify>,
413 core: Core,
414}
415
416impl OwnedNotified {
417 pub fn enable(self: Pin<&mut Self>) -> bool {
419 let this = self.get_mut();
420 this.core.drive(&this.notify, None)
421 }
422}
423
424impl Future for OwnedNotified {
425 type Output = ();
426
427 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
428 let this = self.get_mut();
429 if this.core.drive(&this.notify, Some(cx.waker())) {
430 Poll::Ready(())
431 } else {
432 Poll::Pending
433 }
434 }
435}
436
437impl Drop for OwnedNotified {
438 fn drop(&mut self) {
439 self.core.cancel(&self.notify);
440 }
441}
442
443impl fmt::Debug for OwnedNotified {
444 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
445 f.debug_struct("OwnedNotified")
446 .field("done", &self.core.done)
447 .finish()
448 }
449}
450
451#[cfg(all(test, not(loom)))]
452mod tests {
453 use super::*;
454 use crate::sync::test_support::{Polled, block_on};
455 use core::task::Waker;
456
457 #[test]
458 fn a_notification_before_the_wait_is_kept_once() {
459 let notify = Notify::new();
460 notify.notify_one();
461 notify.notify_one();
462 notify.notify_last();
463 Polled::new(notify.notified()).ready();
464 Polled::new(notify.notified()).pending();
465 }
466
467 #[test]
468 fn notify_one_wakes_waiters_in_order() {
469 let notify = Notify::new();
470 let mut first = Polled::new(notify.notified());
471 first.pending();
472 let mut second = Polled::new(notify.notified());
473 second.pending();
474 notify.notify_one();
475 assert_eq!((first.wakes(), second.wakes()), (1, 0));
476 first.ready();
477 notify.notify_one();
478 second.ready();
479 Polled::new(notify.notified()).pending();
480 }
481
482 #[test]
483 fn notify_last_wakes_the_newest_waiter() {
484 let notify = Notify::new();
485 let mut waiters: Vec<_> = (0..3).map(|_| Polled::new(notify.notified())).collect();
486 for waiter in &mut waiters {
487 waiter.pending();
488 }
489 notify.notify_last();
490 assert_eq!(
491 waiters.iter().map(Polled::wakes).collect::<Vec<_>>(),
492 [0, 0, 1]
493 );
494 notify.notify_last();
495 notify.notify_one();
496 assert_eq!(
497 waiters.iter().map(Polled::wakes).collect::<Vec<_>>(),
498 [1, 1, 1],
499 "one from the back, one from the front"
500 );
501 for waiter in &mut waiters {
502 waiter.ready();
503 }
504 }
505
506 #[test]
507 fn notify_last_skips_the_waiters_that_withdrew_at_the_back() {
508 let notify = Notify::new();
509 let mut oldest = Polled::new(notify.notified());
510 oldest.pending();
511 let mut middle = Polled::new(notify.notified());
512 middle.pending();
513 let mut newest = Polled::new(notify.notified());
514 newest.pending();
515 drop(newest);
516 notify.notify_last();
517 assert_eq!((oldest.wakes(), middle.wakes()), (0, 1));
518 middle.ready();
519 let mut fresh = Polled::new(notify.notified());
520 fresh.pending();
521 drop(fresh);
522 notify.notify_last();
523 assert_eq!(oldest.wakes(), 1, "only the oldest is left");
524 oldest.ready();
525 }
526
527 #[test]
530 fn both_ends_stay_linked_after_withdrawals_and_sweeps() {
531 let notify = Notify::new();
532 let mut waiters: Vec<(usize, Polled<Notified<'_>>)> = (0..9)
533 .map(|id| (id, Polled::new(notify.notified())))
534 .collect();
535 for (_, waiter) in &mut waiters {
536 waiter.pending();
537 }
538 for gone in [4, 5, 3, 6, 2] {
540 let at = waiters
541 .iter()
542 .position(|(id, _)| *id == gone)
543 .expect("queued");
544 drop(waiters.remove(at));
545 }
546 let mut model: std::collections::VecDeque<usize> = [0, 1, 7, 8].into();
547 let mut woken = Vec::new();
548 for call in 0..4 {
549 let expected = if call % 2 == 0 {
550 notify.notify_last();
551 model.pop_back()
552 } else {
553 notify.notify_one();
554 model.pop_front()
555 }
556 .expect("a waiter is left");
557 let (at, _) = waiters
558 .iter()
559 .enumerate()
560 .find(|(_, (_, w))| w.wakes() == 1)
561 .expect("somebody was woken");
562 let (id, mut waiter) = waiters.remove(at);
563 assert_eq!(id, expected, "call {call} woke the wrong waiter");
564 waiter.ready();
565 woken.push(id);
566 }
567 assert_eq!(woken, [8, 0, 7, 1]);
568 }
569
570 #[test]
571 fn notify_waiters_wakes_everyone_present_and_stores_nothing() {
572 let notify = Notify::new();
573 let mut waiting = Polled::new(notify.notified());
574 waiting.pending();
575 let mut created = Polled::new(notify.notified());
576 notify.notify_waiters();
577 waiting.ready();
578 created.ready();
579 Polled::new(notify.notified()).pending();
580 }
581
582 #[test]
583 fn an_older_waiter_queued_behind_a_newer_one_still_gets_the_broadcast() {
584 let notify = Notify::new();
585 let mut older = notify.notified();
587 notify.notify_waiters();
588 let mut newer = Polled::new(notify.notified());
589 newer.pending();
590 notify.enqueue(&mut older.core.wait, older.core.generation, Waker::noop());
594 assert!(
595 older.core.wait.poll(¬ify.queue, None).is_ready(),
596 "the broadcast after its creation reached it"
597 );
598 newer.pending();
599 assert_eq!(newer.wakes(), 0, "an earlier broadcast is not its");
600 }
601
602 #[test]
603 fn a_dropped_waiter_passes_its_notify_one_on() {
604 let notify = Notify::new();
605 let mut first = Polled::new(notify.notified());
606 first.pending();
607 let mut second = Polled::new(notify.notified());
608 second.pending();
609 notify.notify_one();
610 drop(first);
611 assert_eq!(second.wakes(), 1);
612 second.ready();
613 }
614
615 #[test]
616 fn a_dropped_waiter_passes_its_notify_last_on_to_the_newest() {
617 let notify = Notify::new();
618 let mut oldest = Polled::new(notify.notified());
619 oldest.pending();
620 let mut middle = Polled::new(notify.notified());
621 middle.pending();
622 let mut newest = Polled::new(notify.notified());
623 newest.pending();
624 notify.notify_last();
625 drop(newest);
626 assert_eq!(
627 (oldest.wakes(), middle.wakes()),
628 (0, 1),
629 "the pass-on wakes the newest left"
630 );
631 middle.ready();
632 oldest.pending();
633 }
634
635 #[test]
636 fn enable_queues_the_future_for_notify_one_without_a_poll() {
637 let notify = Notify::new();
638 let mut waiting = core::pin::pin!(notify.notified());
639 assert!(!waiting.as_mut().enable());
640 notify.notify_one();
641 assert!(
642 waiting.as_mut().enable(),
643 "the notification found it queued"
644 );
645 assert!(waiting.as_mut().enable(), "and stays ready");
646 notify.notify_one();
648 Polled::new(notify.notified()).ready();
649 }
650
651 #[test]
652 fn enable_consumes_a_stored_permit_and_sees_a_broadcast() {
653 let notify = Notify::new();
654 notify.notify_one();
655 let mut got = core::pin::pin!(notify.notified());
656 assert!(got.as_mut().enable(), "the stored permit");
657 Polled::new(notify.notified()).pending();
658
659 let mut broadcast = core::pin::pin!(notify.notified());
660 notify.notify_waiters();
661 assert!(
662 broadcast.as_mut().enable(),
663 "a broadcast after its creation"
664 );
665 }
666
667 #[test]
668 fn a_poll_after_enable_registers_the_real_waker() {
669 let notify = Notify::new();
670 let mut waiting = core::pin::pin!(notify.notified());
671 assert!(!waiting.as_mut().enable());
672 let probe = Polled::new(core::future::pending::<()>());
673 let waker = probe.waker();
674 assert!(
675 waiting
676 .as_mut()
677 .poll(&mut Context::from_waker(&waker))
678 .is_pending()
679 );
680 notify.notify_one();
681 assert_eq!(
682 probe.wakes(),
683 1,
684 "the waker of the poll replaced the empty one"
685 );
686 assert!(
687 waiting
688 .as_mut()
689 .poll(&mut Context::from_waker(&waker))
690 .is_ready()
691 );
692 }
693
694 #[test]
695 fn an_enabled_future_is_ahead_of_one_polled_later() {
696 let notify = Notify::new();
697 let mut enabled = core::pin::pin!(notify.notified());
698 assert!(!enabled.as_mut().enable());
699 let mut polled = Polled::new(notify.notified());
700 polled.pending();
701 notify.notify_one();
702 assert!(
703 enabled.as_mut().enable(),
704 "the enabled one is first in line"
705 );
706 assert_eq!(polled.wakes(), 0);
707 notify.notify_one();
708 assert_eq!(polled.wakes(), 1);
709 polled.ready();
710 }
711
712 #[test]
713 fn an_enabled_future_dropped_after_its_notification_passes_it_on() {
714 let notify = Notify::new();
715 let mut enabled = Box::pin(notify.notified());
716 assert!(!enabled.as_mut().enable());
717 let mut next = Polled::new(notify.notified());
718 next.pending();
719 notify.notify_one();
720 drop(enabled);
721 assert_eq!(next.wakes(), 1, "the unseen notification moved on");
722 next.ready();
723 }
724
725 #[test]
726 fn an_owned_notified_outlives_the_borrow() {
727 let notify = Arc::new(Notify::new());
728 let mut waiting = Polled::new(Arc::clone(¬ify).notified_owned());
729 waiting.pending();
730 notify.notify_one();
731 waiting.ready();
732 let owned = Arc::clone(¬ify).notified_owned();
733 drop(notify);
734 let mut owned = core::pin::pin!(owned);
735 assert!(!owned.as_mut().enable());
736 }
737
738 #[test]
739 fn a_const_notify_works_in_a_static() {
740 static NOTIFY: Notify = Notify::const_new();
741 NOTIFY.notify_one();
742 Polled::new(NOTIFY.notified()).ready();
743 }
744
745 #[test]
746 fn one_notification_reaches_a_waiter_on_another_thread_whenever_it_lands() {
747 let rounds = if cfg!(miri) { 5 } else { 200 };
748 for _ in 0..rounds {
749 let notify = Arc::new(Notify::new());
750 let waiter = Arc::clone(¬ify);
751 let thread = std::thread::spawn(move || block_on(waiter.notified()));
752 notify.notify_one();
753 thread.join().expect("waiter");
754 }
755 }
756}