Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

time: polling sleep future after complete does not panic in release mode. #3675

Closed
carllerche opened this issue Apr 4, 2021 · 1 comment · Fixed by #5093
Closed

time: polling sleep future after complete does not panic in release mode. #3675

carllerche opened this issue Apr 4, 2021 · 1 comment · Fixed by #5093
Labels
A-tokio Area: The main tokio crate C-bug Category: This is a bug. M-time Module: tokio/time

Comments

@carllerche
Copy link
Member

From: https://fasterthanli.me/articles/pin-and-suffering (search for debug_assert!).

use futures::Future;
use std::{mem::swap, pin::Pin, task::Poll, time::Duration};
use tokio::{macros::support::poll_fn, time::sleep};

#[tokio::main]
async fn main() {
    let mut sleep1 = sleep(Duration::from_secs(1));
    let mut sleep2 = sleep(Duration::from_secs(1));

    {
        // let's use `sleep1` pinned exactly _once_
        let mut sleep1 = unsafe { Pin::new_unchecked(&mut sleep1) };

        // this creates a future whose poll method is the closure argument
        poll_fn(|cx| {
            // we poll `sleep1` once, throwing away the result...
            let _ = sleep1.as_mut().poll(cx);

            // ...and resolve immediately
            Poll::Ready(())
        })
        .await;
    }

    // then, let's use `sleep1` unpinned:
    swap(&mut sleep1, &mut sleep2);
    // by this point, `sleep1` has switched places with `sleep2`

    // finally, let's await both sleep1 and sleep2
    sleep1.await;
    sleep2.await;
}

Results in:

thread 'tokio-runtime-worker' panicked at 'assertion failed: cur_state < STATE_MIN_VALUE', /home/amos/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.4.0/src/time/driver/entry.rs:174:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

But the panic is from a debug assert: debug_assert!(cur_state < STATE_MIN_VALUE);, so in --release mode, nothing happens.

Additionally, the panic message is poor. We should:

a) panic in release mode as well
b) have a better error message describing the problem.

@carllerche carllerche added C-bug Category: This is a bug. E-easy Call for participation: Experience needed to fix: Easy / not much A-tokio Area: The main tokio crate M-time Module: tokio/time labels Apr 4, 2021
@Darksonn Darksonn added the E-help-wanted Call for participation: Help is requested to fix this issue. label Apr 4, 2021
@Darksonn
Copy link
Contributor

Darksonn commented Apr 4, 2021

Note that the code that was posted has undefined behavior. Of course, it's still nice to panic with a nice message if possible.

davidpdrsn added a commit that referenced this issue Apr 6, 2021
While this `debug_assert` could only be [triggered through UB][post]
panicking in release mode and including a more helpful error message is
nice.

Fixes #3675

[post]: https://fasterthanli.me/articles/pin-and-suffering
@Darksonn Darksonn removed E-help-wanted Call for participation: Help is requested to fix this issue. E-easy Call for participation: Experience needed to fix: Easy / not much labels Jan 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-bug Category: This is a bug. M-time Module: tokio/time
Projects
None yet
2 participants