#![stable(feature = "wake_trait", since = "1.51.0")]

//! Types and Traits for working with asynchronous tasks.
//!
//! **Note**: Some of the types in this module are only available
//! on platforms that support atomic loads and stores of pointers.
//! This may be detected at compile time using
//! `#[cfg(target_has_atomic = "ptr")]`.

use core::mem::ManuallyDrop;
#[cfg(target_has_atomic = "ptr")]
use core::task::Waker;
use core::task::{LocalWaker, RawWaker, RawWakerVTable};

use crate::rc::Rc;
#[cfg(target_has_atomic = "ptr")]
use crate::sync::Arc;

/// The implementation of waking a task on an executor.
///
/// This trait can be used to create a [`Waker`]. An executor can define an
/// implementation of this trait, and use that to construct a [`Waker`] to pass
/// to the tasks that are executed on that executor.
///
/// This trait is a memory-safe and ergonomic alternative to constructing a
/// [`RawWaker`]. It supports the common executor design in which the data used
/// to wake up a task is stored in an [`Arc`]. Some executors (especially
/// those for embedded systems) cannot use this API, which is why [`RawWaker`]
/// exists as an alternative for those systems.
///
/// To construct a [`Waker`] from some type `W` implementing this trait,
/// wrap it in an [`Arc<W>`](Arc) and call `Waker::from()` on that.
/// It is also possible to convert to [`RawWaker`] in the same way.
///
/// <!-- Ideally we'd link to the `From` impl, but rustdoc doesn't generate any page for it within
///      `alloc` because `alloc` neither defines nor re-exports `From` or `Waker`, and we can't
///      link ../../std/task/struct.Waker.html#impl-From%3CArc%3CW,+Global%3E%3E-for-Waker
///      without getting a link-checking error in CI. -->
///
/// # Examples
///
/// A basic `block_on` function that takes a future and runs it to completion on
/// the current thread.
///
/// **Note:** This example trades correctness for simplicity. In order to prevent
/// deadlocks, production-grade implementations will also need to handle
/// intermediate calls to `thread::unpark` as well as nested invocations.
///
/// ```rust
/// use std::future::Future;
/// use std::sync::Arc;
/// use std::task::{Context, Poll, Wake};
/// use std::thread::{self, Thread};
/// use core::pin::pin;
///
/// /// A waker that wakes up the current thread when called.
/// struct ThreadWaker(Thread);
///
/// impl Wake for ThreadWaker {
///     fn wake(self: Arc<Self>) {
///         self.0.unpark();
///     }
/// }
///
/// /// Run a future to completion on the current thread.
/// fn block_on<T>(fut: impl Future<Output = T>) -> T {
///     // Pin the future so it can be polled.
///     let mut fut = pin!(fut);
///
///     // Create a new context to be passed to the future.
///     let t = thread::current();
///     let waker = Arc::new(ThreadWaker(t)).into();
///     let mut cx = Context::from_waker(&waker);
///
///     // Run the future to completion.
///     loop {
///         match fut.as_mut().poll(&mut cx) {
///             Poll::Ready(res) => return res,
///             Poll::Pending => thread::park(),
///         }
///     }
/// }
///
/// block_on(async {
///     println!("Hi from inside a future!");
/// });
/// ```
#[cfg(target_has_atomic = "ptr")]
#[stable(feature = "wake_trait", since = "1.51.0")]
#[rustc_diagnostic_item = "Wake"]
pub trait Wake {
    /// Wake this task.
    #[stable(feature = "wake_trait", since = "1.51.0")]
    fn wake(self: Arc<Self>);

    /// Wake this task without consuming the waker.
    ///
    /// If an executor supports a cheaper way to wake without consuming the
    /// waker, it should override this method. By default, it clones the
    /// [`Arc`] and calls [`wake`] on the clone.
    ///
    /// [`wake`]: Wake::wake
    #[stable(feature = "wake_trait", since = "1.51.0")]
    fn wake_by_ref(self: &Arc<Self>) {
        self.clone().wake();
    }
}
#[cfg(target_has_atomic = "ptr")]
#[stable(feature = "wake_trait", since = "1.51.0")]
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
    /// Use a [`Wake`]-able type as a `Waker`.
    ///
    /// No heap allocations or atomic operations are used for this conversion.
    fn from(waker: Arc<W>) -> Waker {
        // SAFETY: This is safe because raw_waker safely constructs
        // a RawWaker from Arc<W>.
        unsafe { Waker::from_raw(raw_waker(waker)) }
    }
}
#[cfg(target_has_atomic = "ptr")]
#[stable(feature = "wake_trait", since = "1.51.0")]
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
    /// Use a `Wake`-able type as a `RawWaker`.
    ///
    /// No heap allocations or atomic operations are used for this conversion.
    fn from(waker: Arc<W>) -> RawWaker {
        raw_waker(waker)
    }
}

/// Converts a closure into a [`Waker`].
///
/// The closure gets called every time the waker is woken.
///
/// # Examples
///
/// ```
/// #![feature(waker_fn)]
/// use std::task::waker_fn;
///
/// let waker = waker_fn(|| println!("woken"));
///
/// waker.wake_by_ref(); // Prints "woken".
/// waker.wake();        // Prints "woken".
/// ```
#[cfg(target_has_atomic = "ptr")]
#[unstable(feature = "waker_fn", issue = "149580")]
pub fn waker_fn<F: Fn() + Send + Sync + 'static>(f: F) -> Waker {
    struct WakeFn<F> {
        f: F,
    }

    impl<F> Wake for WakeFn<F>
    where
        F: Fn(),
    {
        fn wake(self: Arc<Self>) {
            (self.f)()
        }

        fn wake_by_ref(self: &Arc<Self>) {
            (self.f)()
        }
    }

    Waker::from(Arc::new(WakeFn { f }))
}

// NB: This private function for constructing a RawWaker is used, rather than
// inlining this into the `From<Arc<W>> for RawWaker` impl, to ensure that
// the safety of `From<Arc<W>> for Waker` does not depend on the correct
// trait dispatch - instead both impls call this function directly and
// explicitly.
#[cfg(target_has_atomic = "ptr")]
#[inline(always)]
fn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker {
    // Increment the reference count of the arc to clone it.
    //
    // The #[inline(always)] is to ensure that raw_waker and clone_waker are
    // always generated in the same code generation unit as one another, and
    // therefore that the structurally identical const-promoted RawWakerVTable
    // within both functions is deduplicated at LLVM IR code generation time.
    // This allows optimizing Waker::will_wake to a single pointer comparison of
    // the vtable pointers, rather than comparing all four function pointers
    // within the vtables.
    #[inline(always)]
    unsafe fn clone_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) -> RawWaker {
        unsafe { Arc::increment_strong_count(waker as *const W) };
        RawWaker::new(
            waker,
            &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
        )
    }

    // Wake by value, moving the Arc into the Wake::wake function
    unsafe fn wake<W: Wake + Send + Sync + 'static>(waker: *const ()) {
        let waker = unsafe { Arc::from_raw(waker as *const W) };
        <W as Wake>::wake(waker);
    }

    // Wake by reference, wrap the waker in ManuallyDrop to avoid dropping it
    unsafe fn wake_by_ref<W: Wake + Send + Sync + 'static>(waker: *const ()) {
        let waker = unsafe { ManuallyDrop::new(Arc::from_raw(waker as *const W)) };
        <W as Wake>::wake_by_ref(&waker);
    }

    // Decrement the reference count of the Arc on drop
    unsafe fn drop_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) {
        unsafe { Arc::decrement_strong_count(waker as *const W) };
    }

    RawWaker::new(
        Arc::into_raw(waker) as *const (),
        &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
    )
}

/// An analogous trait to `Wake` but used to construct a `LocalWaker`.
///
/// This API works in exactly the same way as `Wake`,
/// except that it uses an `Rc` instead of an `Arc`,
/// and the result is a `LocalWaker` instead of a `Waker`.
///
/// The benefits of using `LocalWaker` over `Waker` are that it allows the local waker
/// to hold data that does not implement `Send` and `Sync`. Additionally, it saves calls
/// to `Arc::clone`, which requires atomic synchronization.
///
///
/// # Examples
///
/// This is a simplified example of a `spawn` and a `block_on` function. The `spawn` function
/// is used to push new tasks onto the run queue, while the block on function will remove them
/// and poll them. When a task is woken, it will put itself back on the run queue to be polled
/// by the executor.
///
/// **Note:** This example trades correctness for simplicity. A real world example would interleave
/// poll calls with calls to an io reactor to wait for events instead of spinning on a loop.
///
/// ```rust
/// #![feature(local_waker)]
/// use std::task::{LocalWake, ContextBuilder, LocalWaker, Waker};
/// use std::future::Future;
/// use std::pin::Pin;
/// use std::rc::Rc;
/// use std::cell::RefCell;
/// use std::collections::VecDeque;
///
///
/// thread_local! {
///     // A queue containing all tasks ready to do progress
///     static RUN_QUEUE: RefCell<VecDeque<Rc<Task>>> = RefCell::default();
/// }
///
/// type BoxedFuture = Pin<Box<dyn Future<Output = ()>>>;
///
/// struct Task(RefCell<BoxedFuture>);
///
/// impl LocalWake for Task {
///     fn wake(self: Rc<Self>) {
///         RUN_QUEUE.with_borrow_mut(|queue| {
///             queue.push_back(self)
///         })
///     }
/// }
///
/// fn spawn<F>(future: F)
/// where
///     F: Future<Output=()> + 'static + Send + Sync
/// {
///     let task = RefCell::new(Box::pin(future));
///     RUN_QUEUE.with_borrow_mut(|queue| {
///         queue.push_back(Rc::new(Task(task)));
///     });
/// }
///
/// fn block_on<F>(future: F)
/// where
///     F: Future<Output=()> + 'static + Sync + Send
/// {
///     spawn(future);
///     loop {
///         let Some(task) = RUN_QUEUE.with_borrow_mut(|queue| queue.pop_front()) else {
///             // we exit, since there are no more tasks remaining on the queue
///             return;
///         };
///
///         // cast the Rc<Task> into a `LocalWaker`
///         let local_waker: LocalWaker = task.clone().into();
///         // Build the context using `ContextBuilder`
///         let mut cx = ContextBuilder::from_waker(Waker::noop())
///             .local_waker(&local_waker)
///             .build();
///
///         // Poll the task
///         let _ = task.0
///             .borrow_mut()
///             .as_mut()
///             .poll(&mut cx);
///     }
/// }
///
/// block_on(async {
///     println!("hello world");
/// });
/// ```
///
#[unstable(feature = "local_waker", issue = "118959")]
pub trait LocalWake {
    /// Wake this task.
    #[unstable(feature = "local_waker", issue = "118959")]
    fn wake(self: Rc<Self>);

    /// Wake this task without consuming the local waker.
    ///
    /// If an executor supports a cheaper way to wake without consuming the
    /// waker, it should override this method. By default, it clones the
    /// [`Rc`] and calls [`wake`] on the clone.
    ///
    /// [`wake`]: LocalWaker::wake
    #[unstable(feature = "local_waker", issue = "118959")]
    fn wake_by_ref(self: &Rc<Self>) {
        self.clone().wake();
    }
}

#[unstable(feature = "local_waker", issue = "118959")]
impl<W: LocalWake + 'static> From<Rc<W>> for LocalWaker {
    /// Use a `Wake`-able type as a `LocalWaker`.
    ///
    /// No heap allocations or atomic operations are used for this conversion.
    fn from(waker: Rc<W>) -> LocalWaker {
        // SAFETY: This is safe because raw_waker safely constructs
        // a RawWaker from Rc<W>.
        unsafe { LocalWaker::from_raw(local_raw_waker(waker)) }
    }
}
#[allow(ineffective_unstable_trait_impl)]
#[unstable(feature = "local_waker", issue = "118959")]
impl<W: LocalWake + 'static> From<Rc<W>> for RawWaker {
    /// Use a `Wake`-able type as a `RawWaker`.
    ///
    /// No heap allocations or atomic operations are used for this conversion.
    fn from(waker: Rc<W>) -> RawWaker {
        local_raw_waker(waker)
    }
}

/// Converts a closure into a [`LocalWaker`].
///
/// The closure gets called every time the local waker is woken.
///
/// # Examples
///
/// ```
/// #![feature(local_waker)]
/// #![feature(waker_fn)]
/// use std::task::local_waker_fn;
///
/// let waker = local_waker_fn(|| println!("woken"));
///
/// waker.wake_by_ref(); // Prints "woken".
/// waker.wake();        // Prints "woken".
/// ```
// #[unstable(feature = "local_waker", issue = "118959")]
#[unstable(feature = "waker_fn", issue = "149580")]
pub fn local_waker_fn<F: Fn() + Send + Sync + 'static>(f: F) -> LocalWaker {
    struct LocalWakeFn<F> {
        f: F,
    }

    impl<F> LocalWake for LocalWakeFn<F>
    where
        F: Fn(),
    {
        fn wake(self: Rc<Self>) {
            (self.f)()
        }

        fn wake_by_ref(self: &Rc<Self>) {
            (self.f)()
        }
    }

    LocalWaker::from(Rc::new(LocalWakeFn { f }))
}

// NB: This private function for constructing a RawWaker is used, rather than
// inlining this into the `From<Rc<W>> for RawWaker` impl, to ensure that
// the safety of `From<Rc<W>> for Waker` does not depend on the correct
// trait dispatch - instead both impls call this function directly and
// explicitly.
#[inline(always)]
fn local_raw_waker<W: LocalWake + 'static>(waker: Rc<W>) -> RawWaker {
    // Increment the reference count of the Rc to clone it.
    //
    // Refer to the comment on raw_waker's clone_waker regarding why this is
    // always inline.
    #[inline(always)]
    unsafe fn clone_waker<W: LocalWake + 'static>(waker: *const ()) -> RawWaker {
        unsafe { Rc::increment_strong_count(waker as *const W) };
        RawWaker::new(
            waker,
            &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
        )
    }

    // Wake by value, moving the Rc into the LocalWake::wake function
    unsafe fn wake<W: LocalWake + 'static>(waker: *const ()) {
        let waker = unsafe { Rc::from_raw(waker as *const W) };
        <W as LocalWake>::wake(waker);
    }

    // Wake by reference, wrap the waker in ManuallyDrop to avoid dropping it
    unsafe fn wake_by_ref<W: LocalWake + 'static>(waker: *const ()) {
        let waker = unsafe { ManuallyDrop::new(Rc::from_raw(waker as *const W)) };
        <W as LocalWake>::wake_by_ref(&waker);
    }

    // Decrement the reference count of the Rc on drop
    unsafe fn drop_waker<W: LocalWake + 'static>(waker: *const ()) {
        unsafe { Rc::decrement_strong_count(waker as *const W) };
    }

    RawWaker::new(
        Rc::into_raw(waker) as *const (),
        &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
    )
}
