Commit fd350e4
authored
This PR fixes the race condition in `Test.cancel()` that could occur if
an unstructured task, created from within a test's task, called
`Test.cancel()` at just the right moment. The order of events for the
race is:
- Unstructured task is created and inherits task-locals including the
reference to the test's unsafe current task;
- Test's task starts tearing down;
- Unstructured task calls `takeUnsafeCurrentTask()` and gets a reference
to the unsafe current task;
- Test's task finishes tearing down;
- Unstructured task calls `UnsafeCurrentTask.cancel()`.
The fix is to use `trylock` semantics when cancelling the unsafe current
task. If the test's task is still alive, the task is cancelled while the
lock is held, which will block the test's task from being torn down as
it has a lock-guarded call to clear the unsafe current task reference.
If the test's task is no longer alive, the reference is already `nil` by
the time the unstructured task acquires the lock and it bails early. If
we recursively call `cancel()` (which can happen via the
concurrency-level cancellation handler), the `trylock` means we won't
acquire the lock a second time, so we won't end up deadlocking or
aborting (which is what prevents calling `cancel()` while holding the
lock in the current implementation).
It is possible for `cancel()` to trigger user code, especially if the
user has set up a cancellation handler, but there is no code path that
can then lead to a deadlock because the only user-accessible calls that
might touch this lock use `trylock`.
I hope some part of that made sense.
### Checklist:
- [x] Code and documentation should follow the style of the [Style
Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md).
- [x] If public symbols are renamed or modified, DocC references should
be updated.
1 parent b0aef48 commit fd350e4
File tree
2 files changed
+120
-38
lines changed- Sources/Testing
- Support
2 files changed
+120
-38
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
29 | 37 | | |
30 | 38 | | |
31 | 39 | | |
| |||
49 | 57 | | |
50 | 58 | | |
51 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
52 | 65 | | |
53 | 66 | | |
54 | 67 | | |
| |||
77 | 90 | | |
78 | 91 | | |
79 | 92 | | |
| 93 | + | |
80 | 94 | | |
81 | | - | |
| 95 | + | |
82 | 96 | | |
83 | 97 | | |
84 | 98 | | |
85 | 99 | | |
86 | 100 | | |
87 | 101 | | |
88 | | - | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
89 | 110 | | |
90 | | - | |
| 111 | + | |
91 | 112 | | |
92 | 113 | | |
93 | 114 | | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
94 | 159 | | |
95 | 160 | | |
96 | 161 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | | - | |
29 | | - | |
30 | | - | |
| 28 | + | |
| 29 | + | |
31 | 30 | | |
32 | 31 | | |
33 | 32 | | |
| |||
45 | 44 | | |
46 | 45 | | |
47 | 46 | | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
56 | 50 | | |
57 | | - | |
58 | 51 | | |
59 | | - | |
60 | 52 | | |
61 | 53 | | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
62 | 82 | | |
63 | 83 | | |
64 | | - | |
| 84 | + | |
65 | 85 | | |
66 | | - | |
| 86 | + | |
67 | 87 | | |
68 | 88 | | |
69 | 89 | | |
| |||
87 | 107 | | |
88 | 108 | | |
89 | 109 | | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
98 | 117 | | |
99 | | - | |
| 118 | + | |
100 | 119 | | |
101 | 120 | | |
102 | 121 | | |
| |||
121 | 140 | | |
122 | 141 | | |
123 | 142 | | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
134 | | - | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
135 | 148 | | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
136 | 153 | | |
137 | 154 | | |
138 | 155 | | |
| |||
0 commit comments