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

release GIL for detached smol::Executor #30

Open
ertosns opened this issue Dec 6, 2024 · 3 comments
Open

release GIL for detached smol::Executor #30

ertosns opened this issue Dec 6, 2024 · 3 comments

Comments

@ertosns
Copy link

ertosns commented Dec 6, 2024

Discussed in PyO3/pyo3#4775

Originally posted by ertosns December 6, 2024
allow_threads doesn't release gil for detached smol::Executor in background, for example the following code block only run in the main thread, and the gil doesn't seem to be released.

async fn executor_run() {
    let ex = Arc::new(smol::Executor::new());
    let fut = ex.spawn(async {
        println!("executor run\n");
    });
    Python::with_gil(|gil| {
            gil.allow_threads(|| {
                fut.detach();
            })
    })
}
@davidhewitt
Copy link
Member

Sorry for the slow reply. Can you demonstrate a more complete repro along with how you conclude that the GIL is not released? I see nothing obvious in this snippet.

@ertosns
Copy link
Author

ertosns commented Feb 4, 2025

i need to following to work without having to sleep in the background until background function is called, if i uncomment the line where it sleeps for 1 sec, it will work. while it should if the gil is released since there is a loop in the background function, and it shouldn't exit.

async fn background(ex: Arc<smol::Executor<'_>>) {
    let fut = ex.clone().spawn(async {
        loop {
            println!("some interesting work!\n");
            async_std::task::sleep(std::time::Duration::from_secs(1)).await;
        }
    });
    Python::with_gil(|gil| {
        gil.allow_threads(|| {
            fut.detach();
        })
    });
    //async_std::task::sleep(std::time::Duration::from_secs(1)).await;
}

#[pyfunction]
fn background_caller(py: Python<'_>) ->  PyResult<Bound<PyAny>> {
    let ex = Arc::new(smol::Executor::new());
    pyo3_async_runtimes::async_std::future_into_py(py, async move {
        let fut = background(ex.clone());
        smol::future::block_on(ex.run(fut));
        Ok(())
    })
}

@davidhewitt
Copy link
Member

The call to smol::future::block_on seems suspicious, that will block the calling thread. You probably need to find a different way to await the calling future.

I will move this issue to pyo3-async-runtimes, it does not look like a PyO3 problem.

@davidhewitt davidhewitt transferred this issue from PyO3/pyo3 Feb 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants