Commit c0c7018
fix(overlays): never block on modelsLock from under a model's effectLock
The effect update threads can reach PixelOverlayModelSub::setState() while
holding the model's effectLock (an effect stopping calls setState on its
model), and an unresolved submodel parent then made foundParent() block on
modelsLock via getModel(). Every HTTP and command path takes those locks
the other way - modelsLock for the lookup, then effectLock to inspect or
replace the running effect - so the two directions deadlock. Same shape as
37c8f92, one lock over, and worse: the effectLock side can run on the
channel output thread via updateRunningEffects(), wedging output as well as
the API. An unresolved parent is reachable at runtime because deleting a
model resets every child's cached parent to null.
Add PixelOverlayManager::tryGetModel(), a try_lock lookup, and use it for
parent resolution. Paths that already hold modelsLock (all the manager and
command paths) still resolve exactly as before - the recursive try_lock
always succeeds. A contended effect-side resolve now returns unresolved and
retries on the next setState instead of blocking, which leaves
modelsLock -> effectLock as the only ordering in the subsystem, so the
cycle can no longer close.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>1 parent 8f5696d commit c0c7018
3 files changed
Lines changed: 37 additions & 9 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
388 | 388 | | |
389 | 389 | | |
390 | 390 | | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
391 | 399 | | |
392 | 400 | | |
393 | 401 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
43 | 52 | | |
44 | 53 | | |
45 | 54 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
145 | 145 | | |
146 | 146 | | |
147 | 147 | | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
156 | 161 | | |
157 | 162 | | |
158 | 163 | | |
159 | 164 | | |
160 | | - | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
161 | 172 | | |
162 | 173 | | |
163 | 174 | | |
| |||
0 commit comments