Skip to content

Conversation

jakepetroules
Copy link
Contributor

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

@jakepetroules
Copy link
Contributor Author

This is a more targeted alternative to #194

@jakepetroules jakepetroules force-pushed the eng/PR-workqueue-fix branch 6 times, most recently from 9cf060a to 27e73ed Compare October 16, 2025 02:43
…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
Copy link
Contributor

@iCharlesHu iCharlesHu left a 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!!

@iCharlesHu iCharlesHu merged commit d781b8f into swiftlang:main Oct 16, 2025
35 checks passed
#if canImport(WinSDK)
SleepConditionVariableCS(self.waitCondition, mutex, INFINITE)
#else
pthread_cond_wait(self.waitCondition, mutex)
Copy link

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)

Copy link
Contributor Author

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".

@kattouf
Copy link

kattouf commented Oct 16, 2025

Thank you for fix! Could we expect patch release included this fix?

@jakepetroules jakepetroules deleted the eng/PR-workqueue-fix branch October 16, 2025 06:00
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

Successfully merging this pull request may close these issues.

Swift Subprocess hangs in release builds but works in debug builds

4 participants