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

Code before:
            // task structure until the task is deallocated, it may be dropped
            // by a Waker on any arbitrary thread.
            //
            // Panics are delivered to the user via the `JoinHandle`. Given that
            // they are dropping the `JoinHandle`, we assume they are not
            // interested in the panic and swallow it.
            let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| {
                self.core().drop_future_or_output();
            }));
        }

        if transition.drop_waker {
            // If the JOIN_WAKER flag is unset at this point, the task is either
            // already terminal or not complete so the `JoinHandle` is responsible
            // for dropping the waker.
            // Safety:
            // If the JOIN_WAKER bit is not set the join handle has exclusive
            // access to the waker as per rule 2 in task/mod.rs.
            // This can only be the case at this point in two scenarios:
            // 1. The task completed and the runtime unset `JOIN_WAKER` flag
            //    after accessing the waker during task completion. So the
            //    `JoinHandle` is the only one to access the  join waker here.
            // 2. The task is not completed so the `JoinHandle` was able to unset
            //    `JOIN_WAKER` bit itself to get mutable access to the waker.
            //    The runtime will not access the waker when this flag is unset.
            unsafe { self.trailer().set_waker(None) }
        }

        // Drop the `JoinHandle` reference, possibly deallocating the task
        self.drop_reference();
    }

    // ====== internal ======

    /// Completes the task. This method assumes that the state is RUNNING.
    fn complete(self) {
        // The future has completed and its output has been written to the task
        // stage. We transition from running to complete.
        let snapshot = self.state().transition_to_complete();

        // We catch panics here in case dropping the future or waking the
        // JoinHandle panics.
        let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| {
            if !snapshot.is_join_interested() {
                // The `JoinHandle` is not interested in the output of
                // this task. It is our responsibility to drop the
                // output. The join waker was already dropped by the
                // `JoinHandle` before.
                self.core().drop_future_or_output();
            } else if snapshot.is_join_waker_set() {
                // Notify the waker. Reading the waker field is safe per rule 4

Review comment (suggestion):
```suggestion
            unsafe { self.trailer().set_waker(None) };
```

Code after:
            // task structure until the task is deallocated, it may be dropped
            // by a Waker on any arbitrary thread.
            //
            // Panics are delivered to the user via the `JoinHandle`. Given that
            // they are dropping the `JoinHandle`, we assume they are not
            // interested in the panic and swallow it.
            let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| {
                self.core().drop_future_or_output();
            }));
        }

        if transition.drop_waker {
            // If the JOIN_WAKER flag is unset at this point, the task is either
            // already terminal or not complete so the `JoinHandle` is responsible
            // for dropping the waker.
            // Safety:
            // If the JOIN_WAKER bit is not set the join handle has exclusive
            // access to the waker as per rule 2 in task/mod.rs.
            // This can only be the case at this point in two scenarios:
            // 1. The task completed and the runtime unset `JOIN_WAKER` flag
            //    after accessing the waker during task completion. So the
            //    `JoinHandle` is the only one to access the  join waker here.
            // 2. The task is not completed so the `JoinHandle` was able to unset
            //    `JOIN_WAKER` bit itself to get mutable access to the waker.
            //    The runtime will not access the waker when this flag is unset.
            unsafe { self.trailer().set_waker(None) };
        }

        // Drop the `JoinHandle` reference, possibly deallocating the task
        self.drop_reference();
    }

    // ====== internal ======

    /// Completes the task. This method assumes that the state is RUNNING.
    fn complete(self) {
        // The future has completed and its output has been written to the task
        // stage. We transition from running to complete.
        let snapshot = self.state().transition_to_complete();

        // We catch panics here in case dropping the future or waking the
        // JoinHandle panics.
        let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| {
            if !snapshot.is_join_interested() {
                // The `JoinHandle` is not interested in the output of
                // this task. It is our responsibility to drop the
                // output. The join waker was already dropped by the
                // `JoinHandle` before.
                self.core().drop_future_or_output();
            } else if snapshot.is_join_waker_set() {
                // Notify the waker. Reading the waker field is safe per rule 4