Repository: tokio-rs/tokio
File: tokio/src/runtime/task/join.rs (Rust)

Code before:
    /// to finish quickly, without blocking for any significant amount of time.
    ///
    /// ```rust
    /// use tokio::time;
    ///
    /// #[tokio::main]
    /// async fn main() {
    ///    let handle1 = tokio::spawn(async {
    ///        // do some stuff here
    ///    });
    ///    let handle2 = tokio::spawn(async {
    ///        // do some other stuff here
    ///        time::sleep(time::Duration::from_secs(10)).await;
    ///    });
    ///    // Wait for the task to finish
    ///    time::sleep(time::Duration::from_secs(1)).await;
    ///    assert!(handle1.is_finished());
    ///    handle2.abort();
    ///    assert!(handle2.is_finished());
    /// }
    /// ```
    pub fn is_finished(&self) -> bool {
        if let Some(raw) = self.raw {
            let state = raw.header().state.load();
            state.is_complete() || state.is_cancelled()
        } else {
            true
        }
    }

    /// Set the waker that is notified when the task completes.
    pub(crate) fn set_join_waker(&mut self, waker: &Waker) {
        if let Some(raw) = self.raw {
            if raw.try_set_join_waker(waker) {
                // In this case the task has already completed. We wake the waker immediately.
                waker.wake_by_ref();
            }
        }
    }

    /// Returns a new `AbortHandle` that can be used to remotely abort this task.
    #[cfg(any(tokio_unstable, test))]
    pub(crate) fn abort_handle(&self) -> super::AbortHandle {
        let raw = self.raw.map(|raw| {
            raw.ref_inc();
            raw
        });
        super::AbortHandle::new(raw, self.id.clone())
    }

    /// Returns a [task ID] that uniquely identifies this task relative to other

Review comment (suggestion):
Hmm, I'm not so sure we want to use the `is_cancelled()` bit. The only situation where `is_cancelled()` is true but `is_complete()` is false is if `abort` has been called, but the task has not yet actually been cancelled.

Code after:
    /// Please note that this method can return `false` even if [`abort`] has been
    /// called on the task. This is because the cancellation process may take
    /// some time, and this method does not return `true` until it has
    /// completed.
    ///
    /// ```rust
    /// use tokio::time;
    ///
    /// # #[tokio::main(flavor = "current_thread")]
    /// # async fn main() {
    /// # time::pause();
    /// let handle1 = tokio::spawn(async {
    ///     // do some stuff here
    /// });
    /// let handle2 = tokio::spawn(async {
    ///     // do some other stuff here
    ///     time::sleep(time::Duration::from_secs(10)).await;
    /// });
    /// // Wait for the task to finish
    /// handle2.abort();
    /// time::sleep(time::Duration::from_secs(1)).await;
    /// assert!(handle1.is_finished());
    /// assert!(handle2.is_finished());
    /// # }
    /// ```
    /// [`abort`]: method@JoinHandle::abort
    pub fn is_finished(&self) -> bool {
        if let Some(raw) = self.raw {
            let state = raw.header().state.load();
            state.is_complete()
        } else {
            true
        }
    }

    /// Set the waker that is notified when the task completes.
    pub(crate) fn set_join_waker(&mut self, waker: &Waker) {
        if let Some(raw) = self.raw {
            if raw.try_set_join_waker(waker) {
                // In this case the task has already completed. We wake the waker immediately.
                waker.wake_by_ref();
            }
        }
    }

    /// Returns a new `AbortHandle` that can be used to remotely abort this task.
    #[cfg(any(tokio_unstable, test))]
    pub(crate) fn abort_handle(&self) -> super::AbortHandle {
        let raw = self.raw.map(|raw| {
            raw.ref_inc();
            raw