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

Asyncio.Event.wait doesn't resume execution when the event is set if no other tasks are active. #122938

Open
fevsea opened this issue Aug 12, 2024 · 4 comments
Labels
topic-asyncio type-feature A feature request or enhancement

Comments

@fevsea
Copy link

fevsea commented Aug 12, 2024

Bug report

Bug description:

This is a toy program that sets an asyncio.Event when a signal is received, and runs an asynchronous function (passive_wait) that waits for that signal to be set.

When the following code is executed and a signal is sent externally, it is detected by the program, but the function waiting function does not resume execution.

It does finish correctly if another async function is executed alongside, like when uncommenting the line active_wait(),.

import asyncio
import signal

event = asyncio.Event()

def _signal_handler(*_) -> None:
    event.set()
    print("Event triggered")

signal.signal(signal.SIGINT, _signal_handler)
signal.signal(signal.SIGTERM, _signal_handler)

async def passive_wait():
    print("Pre event")
    await event.wait()
    print("Post event")

async def active_wait():
    while not event.is_set():
        await asyncio.sleep(1)

async def main():
    await asyncio.gather(
        passive_wait(),
        # Uncommenting the following line makes it stop correctly
        #active_wait(),
    )

asyncio.run(main())
# Send the signal externally

If that's the intended behavior I would love some pointers.

CPython versions tested on:

3.12

Operating systems tested on:

Linux

@fevsea fevsea added the type-bug An unexpected behavior, bug, or error label Aug 12, 2024
@github-project-automation github-project-automation bot moved this to Todo in asyncio Aug 12, 2024
@gvanrossum
Copy link
Member

Try wrapping the event.set() call in call_threadsafe()

@fevsea
Copy link
Author

fevsea commented Aug 12, 2024

Using loop.call_soon_threadsafe to set the event does indeed make it work.

Checking the current thread within the coro and the handler shows both on _MainThread. I'm a bit confuse on why was that the problem.

@graingert
Copy link
Contributor

graingert commented Oct 21, 2024

Yes this is intentional behavior. I wonder if python could set a flag when executing from a reentrant context like a signal handler or finalizer so that Event.set could crash in this case

@willingc
Copy link
Contributor

Removing the bug label based on @graingert's explanation.

@willingc willingc added type-feature A feature request or enhancement and removed type-bug An unexpected behavior, bug, or error labels Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic-asyncio type-feature A feature request or enhancement
Projects
Status: Todo
Development

No branches or pull requests

5 participants