Commit fe1dede
committed
SwiftSyntax: avoid a possible deadlock situtation
Access the consumers list in the DiagnosticsEngine directly to the
storage rather than the accessor. This prevents a possible issue with
invalid usage of `dispatch_sync`. It has been observed on Windows (and
Linux) that there are times where dispatch would trigger an assertion
that `dispatch_sync` was called on a queue owned by the current thread.
It is possible that a thread of execution would invoke the `consumers`
setter, which enqueues a block with barrier semantics. Because the task
is async, the `DiagnosticsEngine` instance has the reference count
incremented. The caller then continues execution immediately (due to
the async nature) and then proceeds to terminate. The
`DiagnosticEngine`'s instance is now effectively owned by the queue.
When the enqueued block executes, the `deinit` invocation will execute
on the thread owning the `consumersQueue`. The `deinit` then proceeds
to access the `consumers` through a `dispatch_sync`, resulting in a
deadlock.
This issue was uncovered by running the swift-format testsuite on
Windows.
Special thanks to @allevato for his invaluable discussion and insight
into what may be occurring here.1 parent 593d01f commit fe1dede
1 file changed
+1
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
95 | 95 | | |
96 | 96 | | |
97 | 97 | | |
98 | | - | |
| 98 | + | |
99 | 99 | | |
100 | 100 | | |
101 | 101 | | |
| |||
0 commit comments