diff options
author | Simon Marlow <marlowsd@gmail.com> | 2015-06-19 15:12:24 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2015-06-26 09:32:23 +0100 |
commit | 111ba4beda4ffc48381723da12e5b237d7f9ac59 (patch) | |
tree | 84ec683a20ea340bd60877daa8ab962e5eebaa2e /testsuite/tests/ghci/prog009/B.hs | |
parent | be0ce8718ea40b091e69dd48fe6bc62b6b551154 (diff) | |
download | haskell-111ba4beda4ffc48381723da12e5b237d7f9ac59.tar.gz |
Fix deadlock (#10545)
yieldCapability() was not prepared to be called by a Task that is not
either a worker or a bound Task. This could happen if we ended up in
yieldCapability via this call stack:
performGC()
scheduleDoGC()
requestSync()
yieldCapability()
and there were a few other ways this could happen via requestSync.
The fix is to handle this case in yieldCapability(): when the Task is
not a worker or a bound Task, we put it on the returning_workers
queue, where it will be woken up again.
Summary of changes:
* `yieldCapability`: factored out subroutine waitForWorkerCapability`
* `waitForReturnCapability` renamed to `waitForCapability`, and
factored out subroutine `waitForReturnCapability`
* `releaseCapabilityAndQueue` worker renamed to `enqueueWorker`, does
not take a lock and no longer tests if `!isBoundTask()`
* `yieldCapability` adjusted for refactorings, only change in behavior
is when it is not a worker or bound task.
Test Plan:
* new test concurrent/should_run/performGC
* validate
Reviewers: niteria, austin, ezyang, bgamari
Subscribers: thomie, bgamari
Differential Revision: https://phabricator.haskell.org/D997
GHC Trac Issues: #10545
Diffstat (limited to 'testsuite/tests/ghci/prog009/B.hs')
0 files changed, 0 insertions, 0 deletions