1use crate::sync::Mutex;
4use futures::task::{ArcWake, waker_ref};
5use std::{
6 future::Future,
7 mem,
8 pin::Pin,
9 sync::{
10 Arc, Weak,
11 atomic::{AtomicUsize, Ordering},
12 },
13 task::{Context, Poll, Waker},
14};
15
16const INLINE_WAKES: usize = 4;
18
19#[must_use = "futures do nothing unless you `.await` or poll them"]
56pub struct Shared<F: Future> {
57 inner: Arc<Inner<F>>,
58 key: Option<usize>,
60}
61
62pub struct WeakShared<F: Future>(Weak<Inner<F>>);
64
65struct Inner<F: Future> {
71 clones: AtomicUsize,
73 state: Mutex<State<F>>,
74}
75
76struct State<F: Future> {
77 stage: Stage<F>,
78 woken: bool,
81 contended: bool,
83 wakers: Vec<Option<Waker>>,
86 free: Vec<usize>,
88}
89
90enum Stage<F: Future> {
91 Idle(F),
93 Polling,
95 Ready(Arc<F::Output>),
98 Poisoned,
100 Released,
102}
103
104struct Wakes {
107 inline: [Option<Waker>; INLINE_WAKES],
108 spilled: Vec<Waker>,
109}
110
111impl Wakes {
112 fn wake(self) {
113 for waker in self.inline.into_iter().flatten().chain(self.spilled) {
114 waker.wake();
115 }
116 }
117}
118
119impl<F: Future> State<F> {
120 #[must_use]
125 fn register(&mut self, key: &mut Option<usize>, waker: &Waker) -> Option<Waker> {
126 let key = *key.get_or_insert_with(|| {
127 self.free.pop().unwrap_or_else(|| {
128 self.wakers.push(None);
129 self.wakers.len() - 1
130 })
131 });
132 let slot = &mut self.wakers[key];
133 if slot
134 .as_ref()
135 .is_some_and(|registered| registered.will_wake(waker))
136 {
137 return None;
138 }
139 slot.replace(waker.clone())
140 }
141
142 #[must_use]
145 fn deregister(&mut self, key: usize) -> Option<Waker> {
146 let waker = self.wakers.get_mut(key)?.take();
148 self.free.push(key);
149 waker
150 }
151
152 fn wakes(&self, except: Option<usize>) -> Wakes {
154 let mut wakes = Wakes {
155 inline: Default::default(),
156 spilled: Vec::new(),
157 };
158 let mut inline = wakes.inline.iter_mut();
159 let registered = self.wakers.iter().enumerate();
160 let others = registered.filter(|&(key, _)| except != Some(key));
161 for waker in others.filter_map(|(_, waker)| waker.as_ref()) {
162 match inline.next() {
163 Some(slot) => *slot = Some(waker.clone()),
164 None => wakes.spilled.push(waker.clone()),
165 }
166 }
167 wakes
168 }
169
170 fn finish(&mut self, stage: Stage<F>) -> Vec<Option<Waker>> {
173 self.stage = stage;
174 mem::take(&mut self.wakers)
175 }
176}
177
178impl<F: Future> Shared<F> {
179 pub fn new(future: F) -> Self {
181 Self {
182 inner: Arc::new(Inner {
183 clones: AtomicUsize::new(1),
184 state: Mutex::new(State {
185 stage: Stage::Idle(future),
186 woken: true,
187 contended: false,
188 wakers: Vec::new(),
189 free: Vec::new(),
190 }),
191 }),
192 key: None,
193 }
194 }
195
196 pub fn downgrade(&self) -> WeakShared<F> {
198 WeakShared(Arc::downgrade(&self.inner))
199 }
200
201 pub fn ptr_eq(&self, other: &Self) -> bool {
203 Arc::ptr_eq(&self.inner, &other.inner)
204 }
205}
206
207impl<F: Future> Clone for Shared<F> {
208 fn clone(&self) -> Self {
209 self.inner.clones.fetch_add(1, Ordering::Relaxed);
210 Self {
211 inner: self.inner.clone(),
212 key: None,
213 }
214 }
215}
216
217impl<F: Future> Drop for Shared<F> {
218 fn drop(&mut self) {
219 let waker = self
223 .key
224 .and_then(|key| self.inner.state.lock().deregister(key));
225 let released = (self.inner.clones.fetch_sub(1, Ordering::AcqRel) == 1)
226 .then(|| mem::replace(&mut self.inner.state.lock().stage, Stage::Released));
227 drop(waker);
228 drop(released);
229 }
230}
231
232impl<F> Future for Shared<F>
233where
234 F: Future + Send + Unpin + 'static,
235 F::Output: Clone + Send + Sync,
236{
237 type Output = F::Output;
238
239 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<F::Output> {
240 let this = self.get_mut();
241
242 let (mut future, replaced) = {
245 let mut guard = this.inner.state.lock();
246 let state = &mut *guard;
247 match &state.stage {
248 Stage::Idle(_) if state.woken => {}
249 Stage::Idle(_) | Stage::Polling => {
250 state.contended |= matches!(state.stage, Stage::Polling);
251 let replaced = state.register(&mut this.key, cx.waker());
252 drop(guard);
253 drop(replaced);
254 return Poll::Pending;
255 }
256 Stage::Ready(output) => {
257 this.key = None;
259 let output = Arc::clone(output);
260 drop(guard);
261 return Poll::Ready((*output).clone());
262 }
263 Stage::Poisoned => panic!("Shared future polled after its inner future panicked"),
264 Stage::Released => unreachable!("a live clone keeps the future"),
265 }
266 let replaced = state.register(&mut this.key, cx.waker());
267 state.woken = false;
268 state.contended = false;
269 let Stage::Idle(future) = mem::replace(&mut state.stage, Stage::Polling) else {
270 unreachable!("stage checked above");
271 };
272 (future, replaced)
273 };
274
275 let poison = Poison(&this.inner);
279 drop(replaced);
280 let waker = waker_ref(&this.inner);
281 let poll = Pin::new(&mut future)
282 .poll(&mut Context::from_waker(&waker))
283 .map(|output| {
284 let shared = Arc::new(output);
285 ((*shared).clone(), shared)
286 });
287 mem::forget(poison);
288
289 let mut state = this.inner.state.lock();
290 match poll {
291 Poll::Pending => {
292 state.stage = Stage::Idle(future);
293 if !state.woken && !state.contended {
294 return Poll::Pending;
295 }
296
297 let wakes = state.wakes(this.key);
301 drop(state);
302 wakes.wake();
303 Poll::Pending
304 }
305 Poll::Ready((output, shared)) => {
306 let own = this.key.take().and_then(|key| state.wakers[key].take());
307 let wakers = state.finish(Stage::Ready(shared));
308 drop(state);
309 drop(own);
310 for waker in wakers.into_iter().flatten() {
311 waker.wake();
312 }
313 Poll::Ready(output)
314 }
315 }
316 }
317}
318
319impl<F: Future> WeakShared<F> {
320 pub fn upgrade(&self) -> Option<Shared<F>> {
322 let inner = self.0.upgrade()?;
323 inner
324 .clones
325 .try_update(Ordering::Relaxed, Ordering::Relaxed, |clones| {
326 (clones != 0).then_some(clones + 1)
327 })
328 .ok()?;
329 Some(Shared { inner, key: None })
330 }
331}
332
333impl<F: Future> Clone for WeakShared<F> {
334 fn clone(&self) -> Self {
335 Self(self.0.clone())
336 }
337}
338
339impl<F> ArcWake for Inner<F>
340where
341 F: Future + Send,
342 F::Output: Send + Sync,
343{
344 fn wake_by_ref(arc_self: &Arc<Self>) {
345 let wakes = {
346 let mut state = arc_self.state.lock();
347 state.woken = true;
348 state.wakes(None)
349 };
350 wakes.wake();
351 }
352}
353
354struct Poison<'a, F: Future>(&'a Inner<F>);
356
357impl<F: Future> Drop for Poison<'_, F> {
358 fn drop(&mut self) {
359 let wakers = self.0.state.lock().finish(Stage::Poisoned);
361 for waker in wakers.into_iter().flatten() {
362 waker.wake();
363 }
364 }
365}
366
367#[cfg(test)]
368mod tests {
369 use super::*;
370 use futures::{
371 FutureExt as _,
372 executor::block_on,
373 future::{self, BoxFuture},
374 task,
375 };
376 use std::{
377 panic::{self, AssertUnwindSafe},
378 sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst},
379 thread,
380 time::Duration,
381 };
382
383 struct Counter(AtomicUsize);
385
386 impl Counter {
387 fn count(&self) -> usize {
388 self.0.load(SeqCst)
389 }
390 }
391
392 impl ArcWake for Counter {
393 fn wake_by_ref(arc_self: &Arc<Self>) {
394 arc_self.0.fetch_add(1, SeqCst);
395 }
396 }
397
398 fn counter() -> (Arc<Counter>, Waker) {
400 let counter = Arc::new(Counter(AtomicUsize::new(0)));
401 (counter.clone(), task::waker(counter))
402 }
403
404 fn poll<F>(shared: &mut Shared<F>, waker: &Waker) -> Poll<F::Output>
405 where
406 F: Future + Send + Unpin + 'static,
407 F::Output: Clone + Send + Sync,
408 {
409 Pin::new(shared).poll(&mut Context::from_waker(waker))
410 }
411
412 #[derive(Default)]
414 struct Control {
415 waker: Mutex<Option<Waker>>,
417 hook: Mutex<Option<Box<dyn FnOnce() + Send>>>,
419 ready: AtomicBool,
421 polls: AtomicUsize,
423 }
424
425 impl Control {
426 fn future(self: &Arc<Self>) -> BoxFuture<'static, u32> {
428 let control = self.clone();
429 future::poll_fn(move |cx| {
430 control.polls.fetch_add(1, SeqCst);
431 *control.waker.lock() = Some(cx.waker().clone());
432 let ready = control.ready.load(SeqCst);
433 let hook = control.hook.lock().take();
434 if let Some(hook) = hook {
435 hook();
436 }
437 if ready { Poll::Ready(7) } else { Poll::Pending }
438 })
439 .boxed()
440 }
441
442 fn wake(&self) {
444 self.waker
445 .lock()
446 .as_ref()
447 .expect("inner future never polled")
448 .wake_by_ref();
449 }
450 }
451
452 #[test]
453 fn test_clones_share_output_and_poll_one_at_a_time() {
454 const CLONES: usize = 8;
455 const POLLS: usize = 1_000;
456
457 let polls = Arc::new(AtomicUsize::new(0));
460 let shared = {
461 let active = AtomicBool::new(false);
462 let polls = polls.clone();
463 Shared::new(future::poll_fn(move |cx| {
464 assert!(
465 !active.swap(true, SeqCst),
466 "inner future polled concurrently"
467 );
468 thread::yield_now();
469 let polled = polls.fetch_add(1, SeqCst) + 1;
470 active.store(false, SeqCst);
471 if polled == POLLS {
472 return Poll::Ready(Arc::new(polled));
473 }
474 cx.waker().wake_by_ref();
475 Poll::Pending
476 }))
477 };
478 let outputs: Vec<_> = (0..CLONES)
479 .map(|_| {
480 let shared = shared.clone();
481 thread::spawn(move || block_on(shared))
482 })
483 .collect::<Vec<_>>()
484 .into_iter()
485 .map(|handle| handle.join().unwrap())
486 .collect();
487
488 for output in &outputs {
490 assert!(Arc::ptr_eq(output, &outputs[0]));
491 }
492 assert_eq!(*outputs[0], POLLS);
493 assert_eq!(polls.load(SeqCst), POLLS);
494 }
495
496 #[test]
497 fn test_clone_after_completion_resolves() {
498 let shared = Shared::new(future::ready(5u32));
499 assert_eq!(block_on(shared.clone()), 5);
500 let (wakes, waker) = counter();
501 let mut late = shared.clone();
502 assert_eq!(poll(&mut late, &waker), Poll::Ready(5));
503 assert_eq!(poll(&mut late, &waker), Poll::Ready(5));
504 let mut upgraded = shared.downgrade().upgrade().expect("strong clone alive");
505 assert_eq!(poll(&mut upgraded, &waker), Poll::Ready(5));
506 assert_eq!(wakes.count(), 0);
507
508 assert!(late.ptr_eq(&shared));
510 assert!(!late.ptr_eq(&Shared::new(future::ready(5))));
511 }
512
513 #[test]
514 fn test_wake_during_poll_rewakes_clone_polled_meanwhile() {
515 let control = Arc::new(Control::default());
516 let a = Arc::new(Mutex::new(Shared::new(control.future())));
517 let mut b = a.lock().clone();
518 let (a_wakes, a_waker) = counter();
519 let (b_wakes, b_waker) = counter();
520
521 assert!(poll(&mut a.lock(), &a_waker).is_pending());
523 control.wake();
524 assert_eq!(a_wakes.count(), 1);
525
526 let parked = Arc::new(AtomicUsize::new(0));
530 *control.hook.lock() = Some(Box::new({
531 let (control, a, a_waker, a_wakes, parked) = (
532 control.clone(),
533 a.clone(),
534 a_waker.clone(),
535 a_wakes.clone(),
536 parked.clone(),
537 );
538 move || {
539 control.ready.store(true, SeqCst);
540 control.wake();
541 assert!(poll(&mut a.lock(), &a_waker).is_pending());
542 parked.store(a_wakes.count(), SeqCst);
543 }
544 }));
545 assert!(poll(&mut b, &b_waker).is_pending());
546 assert_eq!(control.polls.load(SeqCst), 2);
547
548 assert!(a_wakes.count() > parked.load(SeqCst));
551 assert_eq!(b_wakes.count(), 1);
552 drop(b);
553 assert_eq!(poll(&mut a.lock(), &a_waker), Poll::Ready(7));
554 assert_eq!(control.polls.load(SeqCst), 3);
555 }
556
557 #[test]
558 fn test_clone_finding_future_busy_is_woken_after_poll() {
559 let control = Arc::new(Control::default());
560 let a = Arc::new(Mutex::new(Shared::new(control.future())));
561 let mut b = a.lock().clone();
562 let (a_wakes, a_waker) = counter();
563 let (b_wakes, b_waker) = counter();
564
565 *control.hook.lock() = Some(Box::new({
567 let a = a.clone();
568 move || assert!(poll(&mut a.lock(), &a_waker).is_pending())
569 }));
570 assert!(poll(&mut b, &b_waker).is_pending());
571
572 assert_eq!((a_wakes.count(), b_wakes.count()), (1, 0));
574 }
575
576 #[test]
577 fn test_dropped_woken_clone_leaves_others_woken() {
578 let control = Arc::new(Control::default());
579 let mut a = Shared::new(control.future());
580 let mut b = a.clone();
581 let (a_wakes, a_waker) = counter();
582 let (b_wakes, b_waker) = counter();
583 assert!(poll(&mut a, &a_waker).is_pending());
584 assert!(poll(&mut b, &b_waker).is_pending());
585
586 control.ready.store(true, SeqCst);
589 control.wake();
590 assert_eq!((a_wakes.count(), b_wakes.count()), (1, 1));
591 drop(a);
592
593 control.wake();
595 assert_eq!((a_wakes.count(), b_wakes.count()), (1, 2));
596 assert_eq!(poll(&mut b, &b_waker), Poll::Ready(7));
597 }
598
599 #[test]
600 fn test_last_clone_drops_future_despite_retained_waker() {
601 struct DropFlag(Arc<AtomicBool>);
602
603 impl Drop for DropFlag {
604 fn drop(&mut self) {
605 self.0.store(true, SeqCst);
606 }
607 }
608
609 let dropped = Arc::new(AtomicBool::new(false));
612 let registration: Arc<Mutex<Option<Waker>>> = Arc::default();
613 let mut shared = {
614 let flag = DropFlag(dropped.clone());
615 let registration = registration.clone();
616 Shared::new(
617 async move {
618 let _flag = flag;
619 future::poll_fn(|cx| {
620 *registration.lock() = Some(cx.waker().clone());
621 Poll::<u32>::Pending
622 })
623 .await
624 }
625 .boxed(),
626 )
627 };
628 let (_, waker) = counter();
629 assert!(poll(&mut shared, &waker).is_pending());
630 let weak = shared.downgrade();
631 let upgraded = weak.upgrade().expect("strong clone alive");
632 assert!(upgraded.ptr_eq(&shared));
633
634 drop(shared);
637 assert!(!dropped.load(SeqCst));
638 drop(upgraded);
639 assert!(dropped.load(SeqCst));
640 assert!(weak.clone().upgrade().is_none());
641 registration.lock().take().unwrap().wake();
642 assert!(weak.upgrade().is_none());
643 }
644
645 #[test]
646 #[should_panic(expected = "Shared future polled after its inner future panicked")]
647 fn test_panic_poisons_every_clone() {
648 let mut polled = false;
650 let mut a = Shared::new(future::poll_fn(move |cx| -> Poll<u32> {
651 assert!(!polled, "inner future failed");
652 polled = true;
653 cx.waker().wake_by_ref();
654 Poll::Pending
655 }));
656 let mut b = a.clone();
657 let (_, a_waker) = counter();
658 let (b_wakes, b_waker) = counter();
659 assert!(poll(&mut b, &b_waker).is_pending());
660 let woken = b_wakes.count();
661
662 let panicked = panic::catch_unwind(AssertUnwindSafe(|| poll(&mut a, &a_waker)));
664 assert!(panicked.is_err());
665 assert_eq!(b_wakes.count(), woken + 1);
666 let _ = poll(&mut b, &b_waker);
667 }
668
669 #[test]
670 fn test_clones_poll_inner_future_once_per_wake() {
671 const CLONES: usize = 8;
672
673 let control = Arc::new(Control::default());
674 let shared = Shared::new(control.future());
675 let mut clones: Vec<_> = (0..CLONES).map(|_| shared.clone()).collect();
676 drop(shared);
677 let (wakes, waker) = counter();
678
679 for clone in &mut clones {
681 assert!(poll(clone, &waker).is_pending());
682 }
683 assert_eq!(control.polls.load(SeqCst), 1);
684
685 control.wake();
688 assert_eq!(wakes.count(), CLONES);
689 for clone in &mut clones {
690 assert!(poll(clone, &waker).is_pending());
691 }
692 assert_eq!(control.polls.load(SeqCst), 2);
693
694 control.ready.store(true, SeqCst);
696 control.wake();
697 for clone in &mut clones {
698 assert_eq!(poll(clone, &waker), Poll::Ready(7));
699 }
700 assert_eq!(control.polls.load(SeqCst), 3);
701 }
702
703 struct PanicsOnDrop;
705
706 impl ArcWake for PanicsOnDrop {
707 fn wake_by_ref(_: &Arc<Self>) {}
708 }
709
710 impl Drop for PanicsOnDrop {
711 fn drop(&mut self) {
712 panic!("waker destructor failed");
713 }
714 }
715
716 #[test]
717 #[should_panic(expected = "Shared future polled after its inner future panicked")]
718 fn test_panicking_replaced_waker_poisons_every_clone() {
719 let mut a = Shared::new(future::poll_fn(|cx| -> Poll<u32> {
721 cx.waker().wake_by_ref();
722 Poll::Pending
723 }));
724 let mut b = a.clone();
725 let (_, plain) = counter();
726 assert!(poll(&mut a, &task::waker(Arc::new(PanicsOnDrop))).is_pending());
727 assert!(poll(&mut b, &plain).is_pending());
728
729 let panicked = panic::catch_unwind(AssertUnwindSafe(|| poll(&mut a, &plain)));
732 assert!(panicked.is_err());
733 let _ = poll(&mut b, &plain);
734 }
735
736 fn completes(f: impl FnOnce() + Send + 'static) {
739 let (done, finished) = std::sync::mpsc::channel();
740 thread::spawn(move || {
741 f();
742 let _ = done.send(());
743 });
744 finished
745 .recv_timeout(Duration::from_secs(10))
746 .expect("call re-entered the shared state and deadlocked");
747 }
748
749 struct WakingOutput(Arc<Mutex<Option<Waker>>>);
751
752 impl Clone for WakingOutput {
753 fn clone(&self) -> Self {
754 if let Some(waker) = self.0.lock().as_ref() {
755 waker.wake_by_ref();
756 }
757 Self(self.0.clone())
758 }
759 }
760
761 #[test]
762 fn test_output_clone_may_wake_inner_future() {
763 completes(|| {
764 let registered = Arc::new(Mutex::new(None));
765 let mut a = Shared::new(future::poll_fn(move |cx| {
766 *registered.lock() = Some(cx.waker().clone());
767 Poll::Ready(WakingOutput(registered.clone()))
768 }));
769 let mut b = a.clone();
770 let (_, waker) = counter();
771
772 assert!(poll(&mut a, &waker).is_ready());
775 assert!(poll(&mut b, &waker).is_ready());
776 });
777 }
778
779 struct DropsClone(Mutex<Option<Shared<BoxFuture<'static, ()>>>>);
781
782 impl ArcWake for DropsClone {
783 fn wake_by_ref(_: &Arc<Self>) {}
784 }
785
786 impl Drop for DropsClone {
787 fn drop(&mut self) {
788 drop(self.0.lock().take());
789 }
790 }
791
792 fn dropping_waker(sibling: Shared<BoxFuture<'static, ()>>) -> Waker {
794 task::waker(Arc::new(DropsClone(Mutex::new(Some(sibling)))))
795 }
796
797 #[rstest::rstest]
798 #[case::replaced(true)]
799 #[case::dropped(false)]
800 fn test_destroyed_waker_may_drop_a_registered_clone(#[case] replaced: bool) {
801 completes(move || {
802 let mut a = Shared::new(future::pending::<()>().boxed());
803 let mut b = a.clone();
804 let (_, plain) = counter();
805 assert!(poll(&mut b, &plain).is_pending());
806 let waker = dropping_waker(b);
807 assert!(poll(&mut a, &waker).is_pending());
808 drop(waker);
809
810 if replaced {
813 assert!(poll(&mut a, &plain).is_pending());
814 } else {
815 drop(a);
816 }
817 });
818 }
819
820 #[test]
821 fn test_last_drop_with_panicking_waker_releases_future() {
822 struct DropFlag(Arc<AtomicBool>);
823
824 impl Drop for DropFlag {
825 fn drop(&mut self) {
826 self.0.store(true, SeqCst);
827 }
828 }
829
830 let dropped = Arc::new(AtomicBool::new(false));
833 let registration: Arc<Mutex<Option<Waker>>> = Arc::default();
834 let mut shared = {
835 let flag = DropFlag(dropped.clone());
836 let registration = registration.clone();
837 Shared::new(
838 async move {
839 let _flag = flag;
840 future::poll_fn(|cx| {
841 *registration.lock() = Some(cx.waker().clone());
842 Poll::<u32>::Pending
843 })
844 .await
845 }
846 .boxed(),
847 )
848 };
849 let weak = shared.downgrade();
850 let waker = task::waker(Arc::new(PanicsOnDrop));
851 assert!(poll(&mut shared, &waker).is_pending());
852 drop(waker);
853
854 let unwound = panic::catch_unwind(AssertUnwindSafe(|| drop(shared)));
858 assert!(unwound.is_err());
859 assert!(dropped.load(SeqCst));
860 assert!(weak.upgrade().is_none());
861 assert!(registration.lock().is_some());
862 }
863}