diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc b/chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc index c54d0a91447..dbe40e69a27 100644 --- a/chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc +++ b/chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc @@ -234,6 +234,7 @@ class ThreadedWorkletMessagingProxyForTest private: friend class ThreadedWorkletTest; + FRIEND_TEST_ALL_PREFIXES(ThreadedWorkletTest, NestedRunLoopTermination); std::unique_ptr<WorkerThread> CreateWorkerThread() final { return std::make_unique<ThreadedWorkletThreadForTest>(WorkletObjectProxy()); @@ -280,6 +281,16 @@ class ThreadedWorkletTest : public testing::Test { } Document& GetDocument() { return page_->GetDocument(); } + void WaitForReady(WorkerThread* worker_thread) { + base::WaitableEvent child_waitable; + PostCrossThreadTask( + *worker_thread->GetTaskRunner(TaskType::kInternalTest), FROM_HERE, + CrossThreadBindOnce(&base::WaitableEvent::Signal, + CrossThreadUnretained(&child_waitable))); + + child_waitable.Wait(); + } + private: std::unique_ptr<DummyPageHolder> page_; Persistent<ThreadedWorkletMessagingProxyForTest> messaging_proxy_; @@ -403,4 +414,40 @@ TEST_F(ThreadedWorkletTest, TaskRunner) { test::EnterRunLoop(); } +TEST_F(ThreadedWorkletTest, NestedRunLoopTermination) { + MessagingProxy()->Start(); + + ThreadedWorkletMessagingProxyForTest* second_messaging_proxy = + MakeGarbageCollected<ThreadedWorkletMessagingProxyForTest>( + GetExecutionContext()); + + // Get a nested event loop where the first one is on the stack + // and the second is still alive. + second_messaging_proxy->Start(); + + // Wait until the workers are setup and ready to accept work before we + // pause them. + WaitForReady(GetWorkerThread()); + WaitForReady(second_messaging_proxy->GetWorkerThread()); + + // Pause the second worker, then the first. + second_messaging_proxy->GetWorkerThread()->Pause(); + GetWorkerThread()->Pause(); + + // Resume then terminate the second worker. + second_messaging_proxy->GetWorkerThread()->Resume(); + second_messaging_proxy->GetWorkerThread()->Terminate(); + second_messaging_proxy = nullptr; + + // Now resume the first worker. + GetWorkerThread()->Resume(); + + // Make sure execution still works without crashing. + PostCrossThreadTask( + *GetWorkerThread()->GetTaskRunner(TaskType::kInternalTest), FROM_HERE, + CrossThreadBindOnce(&ThreadedWorkletThreadForTest::TestTaskRunner, + CrossThreadUnretained(GetWorkerThread()))); + test::EnterRunLoop(); +} + } // namespace blink |