-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Add timeout parameter to wait(::Condition)
#56974
base: master
Are you sure you want to change the base?
Conversation
# Confirm that the waiting task is still in the wait queue and remove it. If | ||
# the task is not in the wait queue, it must have been notified already so we | ||
# don't do anything here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This appears to introduce a data race though, so we cannot merge this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How's that? We're locking the condition variable here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This Timer runs concurrently with the return from wait
, so by the time this code runs, you might have just corrupted some arbitrary subsequent wait on the same condition or by the time you schedule the TimeoutError, it could blow up some completely unrelated wait
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, okay. There's an ABA problem. Let me see if I can find a solution for that.
But the waiting task is only scheduled with a TimeoutError
if it was in this condition's wait queue, so I'm not sure I understand your "or" case here -- the only subsequent wait
that could get blown up is a wait
on the same condition, which is the same ABA problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could been in the waitq, then removed before you got around to scheduling it, or vice versa with some other thread scheduling before it got around to removing it from the queue. Those codes are running on other threads, so it could be concurrent. There is potentially no guarantee that you can safely mutate this data-structure concurrently on two threads (#55542)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed a fix for the ABA problem that relies on happens-before -- if the waiter was scheduled, it sets waiter_left
before returning. It can only re-enter the condition's wait queue by another call to wait
, for which it must acquire the lock.
We acquire the condition's lock before checking waiter_left
and for the task's presence in the wait queue. If the task is present, it can only be because it has not been scheduled, because if it was scheduled, it would have set waiter_left
before re-entering the wait queue.
I think the combination of the lock and the atomic assure there is no ABA problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could been in the waitq, then removed before you got around to scheduling it
We acquire the lock, confirm that the waiter did not leave and remove it from the wait queue before scheduling it. If it was not in the wait queue, we do not schedule it and this decision is made while holding the lock.
some other thread scheduling before it got around to removing it from the queue
If the task is scheduled by notify
, then it is removed from the condition's wait queue before it is scheduled, which is done while holding the condition's lock. If it is not in the wait queue, then we do not schedule it.
We have a need for this capability. I believe this closes #36217.
The implementation is straightforward and there are a couple of tests.