fix(worker_threads): gate compiled $MessagePort.Start() Ref by cross-thread status#1256
Merged
Conversation
…thread status (#1254) The emitted $MessagePort.Start() unconditionally Ref'd the event loop, so a started, unclosed in-process MessageChannel port hung a compiled program forever. SharpTSMessagePort only Refs for a cross-thread (worker-transferred) port, so this was a compiled-vs-interpreter divergence. Mirrors the interpreter's _crossThread/MarkTransferredAcrossThreads split: $MessagePort gains a _crossThread field and a MarkTransferredAcrossThreads() method (recurses to the partner), and Start() only Refs when set. CompiledMessagePortBridge.Adopt now calls it when a compiled port is transferred to a worker, so both ends still Ref while listening (#406).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #1254 — the compiled
$MessagePort.Start()unconditionally took a keep-aliveRefon the$EventLoop, so a started, unclosed main-threadMessageChannelport kept a compiled program alive forever. The interpreter'sSharpTSMessagePort.Start()only Refs the loop for a cross-thread (worker-transferred) port, so this was a compiled-vs-interpreter divergence.Fix
Mirrors the interpreter's
_crossThread/MarkTransferredAcrossThreadssplit in the emitted$MessagePort(RuntimeEmitter.MessageChannel.cs):_crossThreadfield on$MessagePort, defaulting tofalse.MarkTransferredAcrossThreads()method: sets_crossThread = true, Refs immediately if already started/unclosed, and recurses onto the partner port — same algorithm asSharpTSMessagePort.MarkTransferredAcrossThreads(Compiled Worker: transferList / cross-boundary MessagePort transfer is ignored #406).Start()now only callsthis.Ref()when_crossThreadis set, instead of unconditionally.CompiledMessagePortBridge.Adopt(the worker-side adapter for a transferred compiled port, Compiled Worker: transferList / cross-boundary MessagePort transfer is ignored #406/Follow-ups for compiled→worker MessagePort transfer (CompiledMessagePortBridge) #465) now reflectively invokesMarkTransferredAcrossThreads()on adoption, so both ends of a channel where one port was handed to a worker still Ref while listening — only a plain, never-transferred in-process channel is affected by this fix.Testing
MessageChannel_UnclosedPort_DoesNotHangProcess(both modes) — a plainMessageChannelwith a'message'listener and noclose()call; previously hung forever in compiled mode.Worker_TransferredMessagePort_RoundTripsBetweenParentAndWorker(Compiled Worker: transferList / cross-boundary MessagePort transfer is ignored #406) andWorker_ReceiveMessageOnPort_OnTransferredPort(Follow-ups for compiled→worker MessagePort transfer (CompiledMessagePortBridge) #465) tests, confirming cross-thread keep-alive still works.--verifyand--standalone --verify, and now exits with code 0 instead of hanging.Test plan
dotnet test— 15430/15430 passeddotnet test --filter "FullyQualifiedName~WorkerThreadsTests"— 128/128 passed--compile ... --verifyand--compile ... --standalone --verifyon the issue's repro — IL verification passedgot:hiand exits with code 0 (previously hung)