hjiayz / async_once

async once tool for lazy_static
Other
35 stars 3 forks source link

Future does not setup waker #1

Open robo-corg opened 2 years ago

robo-corg commented 2 years ago

I am not certain if this is a legitimate problem since I haven't written any breaking tests but looking at the code it seems like it is possible to return a Poll::Pending without registering a waker to fire when the lock was not ready but becomes ready later.

bddap commented 2 years ago

I believe causes a deadlock when multiple futures await an AsyncOnce simultaneously. One of the futures will complete, but the others will not. In the example below, only one test case finishes. The other never finishes.

use std::time::Duration;

use async_once::AsyncOnce;
use lazy_static::lazy_static;

lazy_static! {
    static ref FOO: AsyncOnce<u32> = AsyncOnce::new(async {
        tokio::time::sleep(Duration::from_millis(10)).await;
        1
    });
}

#[tokio::test]
async fn test_one() {
    assert_eq!(FOO.get().await, &1);
}

#[tokio::test]
async fn test_two() {
    assert_eq!(FOO.get().await, &1);
}
> cargo test
running 2 tests
test test_two ... ok
test test_one has been running for over 60 seconds
[dependencies]
async_once = "0.2.1"
lazy_static = "1.4.0"
tokio = { version = "1.14.0", features = ["full"] }
hjiayz commented 2 years ago

fixed.