-
Notifications
You must be signed in to change notification settings - Fork 44
Don't suspend/resume the thread while holding an exclusive inout reference #198
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
Conversation
This is a more targeted alternative to #194 |
9cf060a
to
27e73ed
Compare
…rence We pass WorkQueue.queue 'by reference' through inout parameters and across thread suspension points. We noticed a stale value issue in release builds when passing Array with inout, likely due to the copy-on-write mechanism. To avoid stale values after a thread resumes from suspension, sleep the worker thread only after releasing the exclusive inout reference, and re-obtain it after resuming. Resolves swiftlang#182
27e73ed
to
c535f36
Compare
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.
Thanks for the fix!!
#if canImport(WinSDK) | ||
SleepConditionVariableCS(self.waitCondition, mutex, INFINITE) | ||
#else | ||
pthread_cond_wait(self.waitCondition, mutex) |
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 doesn't look right. pthread_cont_wait
and pretty much all other low-level condition variable implementations I have used can wake up spuriously. So usually they need to be in a loop. I.e. while condition(&queue) {
instead of if condition(&queue)
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.
I don't think that alone would be correct in this particular case. If I change this to while
, it'll hang during shutdown(), because shutdown() clears the queue (making it empty) and then wakes the condition variable. It must proceed in that case rather than go back to sleep.
That said, I think you may be right that something is generally amiss because where dequeue() is called it looks like it could end up terminating the work queue early if the condition variable was woken spuriously, since returning nil can't distinguish "no work items right now" versus "entered shutdown mode".
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.
Yeah, that doesn't seem good. Condition variables without a while
are almost never right.
And yes, you'll need to add some sentinel to distinguish shutdown vs. empty
Thank you for fix! Could we expect patch release included this fix? |
We pass WorkQueue.queue 'by reference' through inout parameters and across thread suspension points. We noticed a stale value issue in release builds when passing Array with inout, likely due to the copy-on-write mechanism. To avoid stale values after a thread resumes from suspension, sleep the worker thread only after releasing the exclusive inout reference, and re-obtain it after resuming.
Resolves #182