1#![feature(local_waker)]
190#![feature(context_ext)]
191
192use std::fmt;
193use std::mem::{self, transmute, ManuallyDrop};
194use std::ptr;
195use std::sync::Arc;
196use std::task::Context;
197
198pub struct RawCancelerVTable {
199 clone: unsafe fn(*const ()) -> RawCanceler,
200 cancel: unsafe fn(*const ()),
201 drop: unsafe fn(*const ()),
202}
203
204impl RawCancelerVTable {
205 pub const fn new(
206 clone: unsafe fn(_: *const ()) -> RawCanceler,
207 cancel: unsafe fn(_: *const ()),
208 drop: unsafe fn(_: *const ()),
209 ) -> Self {
210 Self {
211 clone,
212 cancel,
213 drop,
214 }
215 }
216}
217
218pub struct RawCanceler {
219 data: *const (),
220 vtable: &'static RawCancelerVTable,
221}
222
223impl RawCanceler {
224 #[inline]
225 pub const fn new(data: *const (), vtable: &'static RawCancelerVTable) -> Self {
226 Self { data, vtable }
227 }
228}
229
230pub struct WakerWaiterCanceler {
231 inner: RawCanceler,
232}
233
234impl WakerWaiterCanceler {
235 pub fn cancel(&self) {
236 unsafe { (self.inner.vtable.cancel)(self.inner.data) }
237 }
238
239 fn into_raw(mut self) -> RawCanceler {
240 const NOOP_VTABLE: &'static RawCancelerVTable =
241 &RawCancelerVTable::new(|c| RawCanceler::new(c, NOOP_VTABLE), |_| {}, |_| {});
242
243 mem::replace(&mut self.inner, RawCanceler::new(ptr::null(), NOOP_VTABLE))
244 }
245}
246
247impl Clone for WakerWaiterCanceler {
248 fn clone(&self) -> Self {
249 Self {
250 inner: unsafe { (self.inner.vtable.clone)(self.inner.data) },
251 }
252 }
253}
254
255impl Drop for WakerWaiterCanceler {
256 fn drop(&mut self) {
257 unsafe { (self.inner.vtable.drop)(self.inner.data) }
258 }
259}
260
261unsafe impl Send for WakerWaiterCanceler {}
262unsafe impl Sync for WakerWaiterCanceler {}
263
264#[derive(PartialEq)]
265pub struct RawWaiterVTable {
266 clone: unsafe fn(*const ()) -> RawWaiter,
267 wait: unsafe fn(*const ()),
268 canceler: unsafe fn(*const ()) -> Option<RawCanceler>,
269 drop: unsafe fn(*const ()),
270}
271
272impl RawWaiterVTable {
273 pub const fn new(
274 clone: unsafe fn(_: *const ()) -> RawWaiter,
275 wait: unsafe fn(_: *const ()),
276 canceler: unsafe fn(_: *const ()) -> Option<RawCanceler>,
277 drop: unsafe fn(_: *const ()),
278 ) -> Self {
279 Self {
280 clone,
281 wait,
282 canceler,
283 drop,
284 }
285 }
286}
287
288#[derive(PartialEq)]
289pub struct RawWaiter {
290 data: *const (),
291 vtable: &'static RawWaiterVTable,
292}
293
294impl RawWaiter {
295 #[inline]
296 pub const fn new(data: *const (), vtable: &'static RawWaiterVTable) -> Self {
297 Self { data, vtable }
298 }
299}
300
301#[derive(PartialEq)]
302pub struct WakerWaiter {
303 inner: RawWaiter,
304}
305
306impl WakerWaiter {
307 pub fn wait(&self) {
308 unsafe { (self.inner.vtable.wait)(self.inner.data) }
309 }
310
311 pub fn canceler(&self) -> WakerWaiterCanceler {
312 let raw = unsafe { (self.inner.vtable.canceler)(self.inner.data).unwrap() };
313
314 WakerWaiterCanceler { inner: raw }
315 }
316
317 pub fn to_local(self) -> LocalWakerWaiter {
318 let data = self.inner.data;
319 let vtable = self.inner.vtable;
320
321 mem::forget(self);
322
323 LocalWakerWaiter {
324 inner: RawWaiter { data, vtable },
325 }
326 }
327}
328
329impl Clone for WakerWaiter {
330 fn clone(&self) -> Self {
331 Self {
332 inner: unsafe { (self.inner.vtable.clone)(self.inner.data) },
333 }
334 }
335}
336
337impl Drop for WakerWaiter {
338 fn drop(&mut self) {
339 unsafe { (self.inner.vtable.drop)(self.inner.data) }
340 }
341}
342
343unsafe impl Send for WakerWaiter {}
344unsafe impl Sync for WakerWaiter {}
345
346#[derive(PartialEq)]
347pub struct LocalWakerWaiter {
348 inner: RawWaiter,
349}
350
351impl LocalWakerWaiter {
352 pub fn wait(&self) {
353 unsafe { (self.inner.vtable.wait)(self.inner.data) }
354 }
355
356 pub fn canceler(&self) -> Option<WakerWaiterCanceler> {
357 let raw = unsafe { (self.inner.vtable.canceler)(self.inner.data) };
358
359 raw.map(|v| WakerWaiterCanceler { inner: v })
360 }
361}
362
363impl Clone for LocalWakerWaiter {
364 fn clone(&self) -> Self {
365 Self {
366 inner: unsafe { (self.inner.vtable.clone)(self.inner.data) },
367 }
368 }
369}
370
371impl Drop for LocalWakerWaiter {
372 fn drop(&mut self) {
373 unsafe { (self.inner.vtable.drop)(self.inner.data) }
374 }
375}
376
377pub trait WakerWait {
378 fn wait(self: &Arc<Self>);
379 fn canceler(self: &Arc<Self>) -> WakerWaiterCanceler;
380}
381
382impl<W: WakerWait + Send + Sync + 'static> From<Arc<W>> for WakerWaiter {
383 fn from(waiter: Arc<W>) -> Self {
384 Self {
385 inner: raw_waiter(waiter),
386 }
387 }
388}
389
390#[inline(always)]
391fn raw_waiter<W: WakerWait + Send + Sync + 'static>(waiter: Arc<W>) -> RawWaiter {
392 struct VTablePerType<W>(W);
393
394 impl<W: WakerWait + Send + Sync + 'static> VTablePerType<W> {
395 const VTABLE: &'static RawWaiterVTable = &RawWaiterVTable::new(
396 clone_waiter::<W>,
397 wait::<W>,
398 canceler::<W>,
399 drop_waiter::<W>,
400 );
401 }
402
403 unsafe fn clone_waiter<W: WakerWait + Send + Sync + 'static>(waiter: *const ()) -> RawWaiter {
404 unsafe { Arc::increment_strong_count(waiter as *const W) };
405
406 RawWaiter::new(waiter as *const (), VTablePerType::<W>::VTABLE)
407 }
408
409 unsafe fn wait<W: WakerWait + Send + Sync + 'static>(waiter: *const ()) {
410 let waiter = unsafe { ManuallyDrop::new(Arc::from_raw(waiter as *const W)) };
411 <W as WakerWait>::wait(&waiter);
412 }
413
414 unsafe fn canceler<W: WakerWait + Send + Sync + 'static>(
415 waiter: *const (),
416 ) -> Option<RawCanceler> {
417 let waiter = unsafe { ManuallyDrop::new(Arc::from_raw(waiter as *const W)) };
418
419 Some(<W as WakerWait>::canceler(&waiter).into_raw())
420 }
421
422 unsafe fn drop_waiter<W: WakerWait + Send + Sync + 'static>(waiter: *const ()) {
423 unsafe { Arc::decrement_strong_count(waiter as *const W) };
424 }
425
426 RawWaiter::new(
427 Arc::into_raw(waiter) as *const (),
428 VTablePerType::<W>::VTABLE,
429 )
430}
431
432pub trait WakerWaiterCancel {
433 fn cancel(self: &Arc<Self>);
434}
435
436impl<C: WakerWaiterCancel + Send + Sync + 'static> From<Arc<C>> for WakerWaiterCanceler {
437 fn from(canceler: Arc<C>) -> Self {
438 Self {
439 inner: raw_canceler(canceler),
440 }
441 }
442}
443
444#[inline(always)]
445fn raw_canceler<C: WakerWaiterCancel + Send + Sync + 'static>(canceler: Arc<C>) -> RawCanceler {
446 struct VTablePerType<C>(C);
447
448 impl<C: WakerWaiterCancel + Send + Sync + 'static> VTablePerType<C> {
449 const VTABLE: &'static RawCancelerVTable =
450 &RawCancelerVTable::new(clone_canceler::<C>, cancel::<C>, drop_canceler::<C>);
451 }
452
453 unsafe fn clone_canceler<C: WakerWaiterCancel + Send + Sync + 'static>(
454 canceler: *const (),
455 ) -> RawCanceler {
456 unsafe { Arc::increment_strong_count(canceler as *const C) };
457
458 RawCanceler::new(canceler as *const (), VTablePerType::<C>::VTABLE)
459 }
460
461 unsafe fn cancel<C: WakerWaiterCancel + Send + Sync + 'static>(canceler: *const ()) {
462 let canceler = unsafe { ManuallyDrop::new(Arc::from_raw(canceler as *const C)) };
463 <C as WakerWaiterCancel>::cancel(&canceler);
464 }
465
466 unsafe fn drop_canceler<C: WakerWaiterCancel + Send + Sync + 'static>(canceler: *const ()) {
467 unsafe { Arc::decrement_strong_count(canceler as *const C) };
468 }
469
470 RawCanceler::new(
471 Arc::into_raw(canceler) as *const (),
472 VTablePerType::<C>::VTABLE,
473 )
474}
475
476#[derive(Debug)]
477pub struct SetWaiterError;
478
479impl fmt::Display for SetWaiterError {
480 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
481 write!(f, "Failed to set waiter: conflict")
482 }
483}
484
485#[derive(Debug)]
486pub enum SetLocalWaiterError {
487 Conflict,
488 Unsupported,
489}
490
491impl fmt::Display for SetLocalWaiterError {
492 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
493 match self {
494 Self::Conflict => write!(f, "Failed to set local waiter: conflict"),
495 Self::Unsupported => write!(f, "Failed to set local waiter: unsupported"),
496 }
497 }
498}
499
500pub trait TopLevelPoller {
501 fn set_waiter(&mut self, waiter: &WakerWaiter) -> Result<(), SetWaiterError>;
502
503 fn set_local_waiter(&mut self, _waiter: &LocalWakerWaiter) -> Result<(), SetLocalWaiterError> {
504 Err(SetLocalWaiterError::Unsupported)
505 }
506}
507
508pub mod ctx_ref {
509 use std::any::Any;
510 use std::marker::PhantomData;
511 use std::task::Context;
512
513 pub unsafe trait DynWithStaticInterface {
520 type Static: ?Sized + 'static;
521 type Clamped<'a>: ?Sized
522 where
523 Self: 'a;
524
525 fn to_static(&mut self) -> &mut Self::Static;
528
529 fn to_clamped<'a>(&'a mut self) -> &'a mut Self::Clamped<'a>;
532 }
533
534 struct AnyablePrivate<T: ?Sized>(*mut T);
535
536 pub struct Anyable<'a, T: ?Sized, U: ?Sized> {
537 p: AnyablePrivate<T>,
538 _marker: PhantomData<&'a mut U>,
539 }
540
541 impl<'a, T: DynWithStaticInterface + ?Sized> Anyable<'a, T::Static, T> {
542 pub fn new(r: &'a mut T) -> Self {
543 Self {
544 p: AnyablePrivate(r.to_static()),
545 _marker: PhantomData,
546 }
547 }
548 }
549
550 impl<T: ?Sized + 'static, U: ?Sized> Anyable<'_, T, U> {
551 pub fn as_any<'a>(&'a mut self) -> &'a mut (dyn Any + 'static) {
552 &mut self.p
553 }
554 }
555
556 pub fn ctx_downcast<'a, T: DynWithStaticInterface + ?Sized + 'static>(
557 cx: &mut Context<'a>,
558 ) -> Option<&'a mut T::Clamped<'a>> {
559 let a = cx.ext();
560
561 let p = match a.downcast_mut::<AnyablePrivate<T>>() {
562 Some(p) => p,
563 None => return None,
564 };
565
566 let r: &'a mut T = unsafe { p.0.as_mut().unwrap() };
570
571 Some(r.to_clamped())
572 }
573}
574
575use ctx_ref::{ctx_downcast, DynWithStaticInterface};
576
577pub use ctx_ref::Anyable;
578
579unsafe impl DynWithStaticInterface for (dyn TopLevelPoller + '_) {
581 type Static = dyn TopLevelPoller + 'static;
582 type Clamped<'a> = dyn TopLevelPoller + 'a;
583
584 fn to_static(&mut self) -> &mut Self::Static {
585 unsafe { transmute(self) }
586 }
587
588 fn to_clamped<'a>(&'a mut self) -> &'a mut Self::Clamped<'a> {
589 unsafe { transmute(self) }
590 }
591}
592
593pub fn get_poller<'a>(cx: &mut Context<'a>) -> Option<&'a mut (dyn TopLevelPoller + 'a)> {
594 ctx_downcast::<dyn TopLevelPoller>(cx)
595}
596
597mod executor {
598 use super::Anyable;
599 use super::{SetWaiterError, TopLevelPoller, WakerWaiter, WakerWaiterCanceler};
600 use std::future::Future;
601 use std::pin::pin;
602 use std::sync::{Arc, Mutex};
603 use std::task::{ContextBuilder, Poll, Wake};
604 use std::thread::{self, Thread};
605
606 struct ThreadWaker {
607 thread: Thread,
608 waiter_data: Arc<Mutex<Option<(WakerWaiter, WakerWaiterCanceler)>>>,
609 }
610
611 impl Wake for ThreadWaker {
612 fn wake(self: Arc<Self>) {
613 if thread::current().id() == self.thread.id() {
614 return;
618 }
619
620 let waiter_data = self.waiter_data.lock().unwrap().clone();
621
622 if let Some(waiter_data) = waiter_data {
623 waiter_data.1.cancel();
626 } else {
627 self.thread.unpark();
630 }
631 }
632 }
633
634 #[derive(Clone)]
635 pub struct MyTopLevelPoller {
636 waiter_data: Arc<Mutex<Option<(WakerWaiter, WakerWaiterCanceler)>>>,
637 }
638
639 impl TopLevelPoller for MyTopLevelPoller {
640 fn set_waiter(&mut self, waiter: &WakerWaiter) -> Result<(), SetWaiterError> {
641 let waiter_data = &mut *self.waiter_data.lock().unwrap();
642
643 if let Some(cur) = waiter_data {
644 if cur.0 == *waiter {
645 return Ok(()); } else {
647 return Err(SetWaiterError); }
649 }
650
651 *waiter_data = Some((waiter.clone(), waiter.canceler()));
652
653 Ok(())
654 }
655 }
656
657 pub fn block_on<T>(fut: T) -> T::Output
658 where
659 T: Future,
660 {
661 let waiter_data = Arc::new(Mutex::new(None));
662
663 let mut poller = MyTopLevelPoller {
664 waiter_data: Arc::clone(&waiter_data),
665 };
666
667 let waker = Arc::new(ThreadWaker {
668 thread: thread::current(),
669 waiter_data,
670 })
671 .into();
672
673 let mut fut = pin!(fut);
674
675 let res = loop {
676 let result = {
677 let mut a = Anyable::new(&mut poller as &mut dyn TopLevelPoller);
678 let mut cx = ContextBuilder::from_waker(&waker).ext(a.as_any()).build();
679
680 fut.as_mut().poll(&mut cx)
681 };
682
683 match result {
684 Poll::Ready(res) => break res,
685 Poll::Pending => {
686 let waiter_data = poller.waiter_data.lock().unwrap().clone();
687
688 match waiter_data {
691 Some(waiter_data) => waiter_data.0.wait(),
692 None => thread::park(),
693 }
694 }
695 }
696 };
697
698 res
699 }
700}
701
702pub use executor::block_on;
703
704#[cfg(test)]
705mod tests {
706 use super::*;
707 use std::cell::RefCell;
708 use std::future::Future;
709 use std::pin::{pin, Pin};
710 use std::task::{ContextBuilder, Poll, Wake};
711
712 struct NoopWaker;
713
714 impl Wake for NoopWaker {
715 fn wake(self: Arc<Self>) {}
716 }
717
718 struct MyTopLevelPoller {
719 waiter: RefCell<Option<WakerWaiter>>,
720 }
721
722 impl TopLevelPoller for MyTopLevelPoller {
723 fn set_waiter(&mut self, waiter: &WakerWaiter) -> Result<(), SetWaiterError> {
724 let self_waiter = &mut *self.waiter.borrow_mut();
725
726 if let Some(cur) = self_waiter {
727 if cur == waiter {
728 return Ok(()); } else {
730 return Err(SetWaiterError); }
732 }
733
734 *self_waiter = Some(waiter.clone());
735
736 Ok(())
737 }
738 }
739
740 struct NoopWakerWaiterCanceler;
741
742 impl WakerWaiterCancel for NoopWakerWaiterCanceler {
743 fn cancel(self: &Arc<Self>) {}
744 }
745
746 struct NoopWakerWaiter;
747
748 impl WakerWait for NoopWakerWaiter {
749 fn wait(self: &Arc<Self>) {}
750 fn canceler(self: &Arc<Self>) -> WakerWaiterCanceler {
751 Arc::new(NoopWakerWaiterCanceler).into()
752 }
753 }
754
755 struct MyFuture {
756 waiter: WakerWaiter,
757 }
758
759 impl MyFuture {
760 fn new() -> Self {
761 Self {
762 waiter: Arc::new(NoopWakerWaiter).into(),
763 }
764 }
765 }
766
767 impl Future for MyFuture {
768 type Output = ();
769
770 fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
771 let waker = Arc::new(NoopWaker).into();
776 let mut cx1 = ContextBuilder::from(cx).waker(&waker).build();
777
778 let poller = match get_poller(&mut cx1) {
780 Some(p) => p,
781 None => panic!("MyFuture requires context to provide TopLevelPoller"),
782 };
783
784 if poller.set_waiter(&self.waiter).is_err() {
787 panic!("Incompatible WakerWaiter already assigned to context's TopLevelPoller");
788 }
789
790 Poll::Ready(())
791 }
792 }
793
794 struct MyFuture2 {
795 waiter: WakerWaiter,
796 }
797
798 impl MyFuture2 {
799 fn new() -> Self {
800 Self {
801 waiter: Arc::new(NoopWakerWaiter).into(),
802 }
803 }
804 }
805
806 impl Future for MyFuture2 {
807 type Output = ();
808
809 fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
810 let waker = Arc::new(NoopWaker).into();
815 let mut cx1 = ContextBuilder::from(cx).waker(&waker).build();
816
817 let poller = match get_poller(&mut cx1) {
819 Some(p) => p,
820 None => panic!("MyFuture requires context to provide TopLevelPoller"),
821 };
822
823 if poller.set_waiter(&self.waiter).is_err() {
826 panic!("Incompatible WakerWaiter already assigned to context's TopLevelPoller");
827 }
828
829 Poll::Ready(())
830 }
831 }
832
833 #[test]
834 fn test_waiter() {
835 let waker = Arc::new(NoopWaker).into();
836
837 let mut poller = MyTopLevelPoller {
838 waiter: RefCell::new(None),
839 };
840
841 let mut fut = pin!(MyFuture::new());
842
843 loop {
844 let result = {
845 let mut a = Anyable::new(&mut poller as &mut dyn TopLevelPoller);
846 let mut cx = ContextBuilder::from_waker(&waker).ext(a.as_any()).build();
847
848 fut.as_mut().poll(&mut cx)
849 };
850
851 match result {
852 Poll::Ready(res) => break res,
853 Poll::Pending => match &*poller.waiter.borrow() {
854 Some(waiter) => waiter.wait(),
855 None => {}
856 },
857 }
858 }
859 }
860
861 #[test]
862 fn test_block_on() {
863 block_on(MyFuture2::new());
864 }
865}