-
Notifications
You must be signed in to change notification settings - Fork 149
Deadlock in anyio.Lock #398
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
Comments
? I don't understand that part. Of course the lock's context manager blocks during |
AnyIO has an explicit code path that is executed in case the task is cancelled during |
My bad there. I mean that the implementation of |
On AnyIO, the only |
Yes, that is exactly the place I got when debugging. There is an await there, the task yields, and in my case the lock is not released. What happens when you run my PoC? |
So what seems to happen here is this:
The |
Dealing with two different cancellation systems is a pain, but a pain AnyIO has to live with. We should probably add more tests to check for native cancellation behavior. |
So this opens up the question of how to deal with cancellations arriving in |
I wrote tests against |
… cancel during __aenter__() Fixes #398.
To be safe, I inspected all other AnyIO classes that have an |
@graffic would you mind reviewing or at least testing the fix? I'm pretty confident about it but as policy, I try to get all new AnyIO code reviewed. |
@agronholm So your fix makes the PoC pass. 👍 Checking the pull request, I see that you've added a try in the point where it could deadlock, plus releasing the lock in case of error. So I'd say that's the fix :D |
Related to this issue in httpcore: encode/httpcore#454
TL;DR: With the right timing, the lock acquire step can be cancelled and the lock remain locked for other tasks because when using the lock context manager, if the task is cancelled during the
__aenter__
,__aexit__
is not executed.This snippet reproduces the issue:
The issue goes away when using
asyncio.Lock
because that lock context manager never blocks during the acquire step. Even if the__aenter__
method inasyncio.Lock
is asynchronous, no asynchronous code is executed there.The text was updated successfully, but these errors were encountered: