GeezerVison is showing github.com — fix(worker): leave the inspector pause loop when the worker is terminating by adrian-niculescu · Pull Request #2071 · NativeScript/android
Conversation
adrian-niculescu
commented
Oct 6, 2026
•
edited by coderabbitai
Bot
Loading
Uh oh!
There was an error while loading. Please reload this page.
In a debug build, a worker paused at a breakpoint inside console.log (for example a debugger statement in a getter that the message text conversion runs) makes the parent's worker.terminate() block until the debugger resumes, freezing the parent's thread.
WorkerWrapper::ConsoleLog holds inspectorMutex_ across WorkerInspectorClient::consoleLog, so the pause loop runs with that mutex held. Terminate() ends a pause through NotifyTerminating(), which it reaches by taking the same mutex, so it waits for the pause, and the pause only waits for the debugger. The pause loop now also leaves on the worker's own isTerminating_ flag, which Terminate() sets before it takes the mutex and which the loop checks on each pass while it waits. The paused worker then returns from consoleLog, the mutex is released, and Terminate() continues.
This builds on #2067, whose commits are the first three here. Leaving the pause on the flag lets the worker run on to its own teardown while the parent may still be interrupting its isolate, and #2067 is what keeps the isolate alive until the parent is done with it.
With the pause entered by hand at that point, the parent's terminate() on main blocks in mutex::lock() while the worker sits in runMessageLoopOnPause, and with this change it returns and the worker ends. Reproducing it for real needs a DevTools session paused inside the getter, so there is no spec for it. The full device suite passes.
Summary by CodeRabbit
- Bug Fixes
- Workers can now be terminated reliably after calling
close(), including while paused in debugging.
- Tests
- Added coverage to verify that a closed worker stops running after termination.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Terminate() read the worker isolate and then interrupted it with no lock, while the worker thread could clear the pointer and dispose that isolate in the same window: a worker that ends through its own close() while its parent calls terminate(), or a parent that terminates its children during its own shutdown. Terminate() now holds a mutex across the read and the use, and the worker thread takes it when it withdraws the isolate, before disposing it.
close() only ends the worker once its running callback returns, and terminate() returned early for a closing worker, so a worker that kept running after close() could not be stopped. terminate() now interrupts it like any other running worker.
…spec in its timeout
A run where terminate() failed left the worker spinning past the spec. The loop now also checks a stop flag the spec raises in afterEach, the spec gets its own Jasmine timeout with a shorter start deadline, and the start-deadline branch fails through an expectation rather than the fail() global this Jasmine does not provide.
coderabbitai
Bot
commented
Oct 6, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
|

No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
da43a519-319c-4acd-99f4-d6f799baafab
📥 Commits
Reviewing files that changed from the base of the PR and between 9b12329 and e8d3dab.
📒 Files selected for processing (7)
test-app/app/src/main/assets/app/mainpage.js
test-app/app/src/main/assets/app/tests/testWorkerTerminateAfterClose.js
test-app/app/src/main/assets/app/tests/workerCloseThenSpinWorker.js
test-app/runtime/src/main/cpp/WorkerInspectorClient.cpp
test-app/runtime/src/main/cpp/WorkerInspectorClient.h
test-app/runtime/src/main/cpp/WorkerWrapper.cpp
test-app/runtime/src/main/cpp/WorkerWrapper.h
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 1 remain after this review.
📝 Walkthrough
Walkthrough
The worker runtime now permits termination after a worker begins closing and coordinates isolate access during termination and shutdown. A new test checks that the worker’s shared counter stops advancing after termination.
Changes
Worker termination
| Layer / File(s) |
Summary |
Coordinate termination and inspector shutdown test-app/runtime/src/main/cpp/WorkerWrapper.h, test-app/runtime/src/main/cpp/WorkerWrapper.cpp, test-app/runtime/src/main/cpp/WorkerInspectorClient.h, test-app/runtime/src/main/cpp/WorkerInspectorClient.cpp |
WorkerWrapper synchronizes isolate access during termination and shutdown. WorkerInspectorClient receives the worker termination flag and checks it in its pause loop. |
Test termination after close test-app/app/src/main/assets/app/tests/workerCloseThenSpinWorker.js, test-app/app/src/main/assets/app/tests/testWorkerTerminateAfterClose.js, test-app/app/src/main/assets/app/mainpage.js |
The worker calls close() and increments a shared counter. The test terminates it and checks that the counter remains unchanged. The app loads the test module. |
Priority: ⬇️ Low
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix
Sequence Diagram(s)
sequenceDiagram
participant WorkerTest
participant workerCloseThenSpinWorker
participant WorkerWrapper
participant WorkerInspectorClient
WorkerTest->>workerCloseThenSpinWorker: Send shared counter buffer
workerCloseThenSpinWorker->>workerCloseThenSpinWorker: Call close and increment counter
WorkerTest->>WorkerWrapper: Terminate worker
WorkerWrapper->>WorkerWrapper: Interrupt isolate and notify event loop
WorkerInspectorClient->>WorkerInspectorClient: Check termination flag and exit pause loop
WorkerTest->>WorkerTest: Check that the counter remains unchanged
Loading
Suggested reviewers: edusperoni
Merge Risk: ⚪ Minimal · up to e8d3d
This change fixes a worker termination deadlock and allows a worker that has called close() to be terminated. No merge-blocking risk is evident from the supplied context.
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
| Check name |
Status |
Explanation |
Resolution |
| Docstring Coverage |
⚠️ Warning |
Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 7 files. |
Write docstrings for the functions missing them to satisfy the coverage threshold. |
✅ Passed checks (4 passed)
| Check name |
Status |
Explanation |
| Description Check |
✅ Passed |
Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check |
✅ Passed |
The title clearly describes the main change: the inspector pause loop exits when the worker is terminating. |
| Linked Issues check |
✅ Passed |
Check skipped because no linked issues were found for this pull request. |
| Out of Scope Changes check |
✅ Passed |
Check skipped because no linked issues were found for this pull request. |
- Fix all pre-merge checks with AI
- Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
❤️ Share
A rabbit watched the worker spin, Then sent the stop signal in. The counter paused, the loop grew still, The test confirmed the change with skill. One hop, one check, and all was done.
Comment @coderabbitai help to get the list of available commands.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
…ating
A breakpoint hit while console.log converts its arguments pauses the worker inside ConsoleLog, which holds the worker's inspector mutex. terminate() could only end that pause through NotifyTerminating, which takes the same mutex, so the parent's terminate() blocked until the debugger resumed. The pause loop now also leaves on the worker's own termination flag, which terminate() sets before it takes the mutex.
This branch has not been deployed
No deployments
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
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.
|