fix: shared Roslyn worker ReadLine no longer blocks Editor shutdown
Merged
HA
3mo ago+589+589+012345678901234567890123456789-82-82-01234567890123456789
Summary
- Domain reload / Editor quit can interrupt a stuck shared Roslyn worker read without waiting up to 30s on the sync lock
- Dynamic-code compile conversations stay single-flight (write→read), while timeout paths kill the worker and observe abandoned reads
User Impact
- Before: A blocked worker
ReadLineheld the session lock, so shutdown (reload/quit) could stall the Editor for the full response timeout - After: Shutdown kills the worker under a short state lock and does not wait on the compile gate; in-flight readers fail fast when pipes close
Lock boundary (before / after)
BEFORE
┌─────────────────────────────────────────────────────────┐
│ ExecuteLocked(_syncRoot) │
│ write request │
│ ReadLine() ← blocks up to 30s WHILE HOLDING LOCK │
│ read diagnostics │
└─────────────────────────────────────────────────────────┘
ShutdownProcessLocked ALSO requires _syncRoot
→ shutdown waits behind the stuck ReadLine
AFTER
┌─ SemaphoreSlim compile gate (async, serializes conversations)
│ short _syncRoot: write + take StreamReader
│ await ReadLineAsync ← OUTSIDE _syncRoot
│ short _syncRoot only if kill/retry needed
└─────────────────────────────────────────────────────────
Shutdown: lock(_syncRoot) only → kill/close pipes
does NOT WaitAsync on the compile gate
→ stuck read unblocks via pipe close; abandoned Task observed
Changes
- Extract Unity-free
SharedRoslynCompilerWorkerLineReader(timeout/cancel + observe abandonedReadLine) - Extract
SharedRoslynCompilerWorkerSessionCoordination(async compile gate + short state lock + shutdown bypass) TryCompile→TryCompileAsync; host kills worker on empty/invalid/timeout responses- Pure unit tests for line reader + “shutdown while compile gate held”
- Wire tests into EditMode / compile-check CI workflows
Out of scope (umbrella note)
SharedRoslynCompilerWorkerAssemblyBuilderstill uses syncWaitForExitfor worker DLL builds; call sites can run on the Unity main thread during compile/prewarm
Verification
-
dotnet test tests/SharedRoslynCompilerWorker.UnitTests/...(8 passed) - Unity Bee compiled
ExecuteDynamicCode.Editorwith no CS errors for these files - Local
uloop compilehung after domain reload in this environment (IPC warmup hit disposedDynamicCodeExecutionScheduler); CI compile check is the authoritative follow-up
Test plan
- CI: SharedRoslynCompilerWorker unit tests green
- CI / local: EditMode
SharedRoslynCompilerWorkerHostTestsstill pass - Manual: trigger domain reload during a slow dynamic-code compile; Editor should not stick on worker ReadLine