Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1938)

Side by Side Diff: Source/modules/compositorworker/CompositorWorkerManagerTest.cpp

Issue 1158443008: compositor-worker: Share a thread and an isolate for compositor workers. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: . Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "modules/compositorworker/CompositorWorkerManager.h"
7
8 #include "bindings/core/v8/ScriptSourceCode.h"
9 #include "core/testing/DummyPageHolder.h"
10 #include "core/workers/WorkerLoaderProxy.h"
11 #include "core/workers/WorkerObjectProxy.h"
12 #include "core/workers/WorkerReportingProxy.h"
13 #include "core/workers/WorkerThreadStartupData.h"
14 #include "modules/compositorworker/CompositorWorkerThread.h"
15 #include "platform/NotImplemented.h"
16 #include "platform/ThreadSafeFunctional.h"
17 #include "public/platform/Platform.h"
18 #include "public/platform/WebWaitableEvent.h"
19 #include <gtest/gtest.h>
20
21 namespace blink {
22 namespace {
23
24 class TestCompositorWorkerThread : public CompositorWorkerThread {
25 public:
26 TestCompositorWorkerThread(WorkerLoaderProxyProvider* loaderProxyProvider, W orkerObjectProxy& objectProxy, double timeOrigin, WebWaitableEvent* startEvent)
27 : CompositorWorkerThread(WorkerLoaderProxy::create(loaderProxyProvider), objectProxy, timeOrigin)
28 , m_startEvent(startEvent)
29 {
30 }
31
32 ~TestCompositorWorkerThread() override { }
33
34 void executeCallbackAfterV8Termination(PassOwnPtr<Function<void()>> callback )
35 {
36 m_v8TerminationCallback = callback;
37 }
38
39 private:
40 // WorkerThread:
41 void didStartRunLoop() override
42 {
43 m_startEvent->signal();
44 }
45 void terminateV8Execution() override
46 {
47 CompositorWorkerThread::terminateV8Execution();
48 if (m_v8TerminationCallback)
49 (*m_v8TerminationCallback)();
50 }
51
52 WebWaitableEvent* m_startEvent;
53 OwnPtr<Function<void()>> m_v8TerminationCallback;
54 };
55
56 class CompositorWorkerManagerTest : public testing::Test {
57 public:
58 void SetUp() override
59 {
60 m_page = DummyPageHolder::create();
61 m_objectProxy = WorkerObjectProxy::create(&m_page->document(), nullptr);
62 m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http:// fake.url/"));
63 }
64
65 void TearDown() override
66 {
67 m_page.clear();
68 }
69
70 PassRefPtr<TestCompositorWorkerThread> createCompositorWorker(WebWaitableEve nt* startEvent)
71 {
72 TestCompositorWorkerThread* workerThread = new TestCompositorWorkerThrea d(nullptr, *m_objectProxy, 0, startEvent);
73 workerThread->start(WorkerThreadStartupData::create(
74 KURL(ParsedURLString, "http://fake.url/"),
75 "fake user agent",
76 "//fake source code",
77 nullptr,
78 DontPauseWorkerGlobalScopeOnStart,
79 adoptPtr(new Vector<CSPHeaderAndType>()),
80 m_securityOrigin.get(),
81 WorkerClients::create(),
82 V8CacheOptionsDefault));
83 return adoptRef(workerThread);
84 }
85
86 void createSecondWorker(RefPtr<CompositorWorkerThread>* workerThread, WebWai tableEvent* creationEvent)
87 {
88 *workerThread = createCompositorWorker(creationEvent);
89 }
90
91 // Attempts to run some simple script for |worker|.
92 void checkWorkerCanExecuteScript(WorkerThread* worker)
93 {
94 OwnPtr<WebWaitableEvent> waitEvent = adoptPtr(Platform::current()->creat eWaitableEvent());
95 worker->backingThread().platformThread().postTask(FROM_HERE, threadSafeB ind(&CompositorWorkerManagerTest::executeScriptInWorker, AllowCrossThreadAccess( this),
96 AllowCrossThreadAccess(worker), AllowCrossThreadAccess(waitEvent.get ())));
97 waitEvent->wait();
98 }
99
100 private:
101 void executeScriptInWorker(WorkerThread* worker, WebWaitableEvent* waitEvent )
102 {
103 WorkerScriptController* scriptController = worker->workerGlobalScope()-> script();
104 ASSERT(scriptController->evaluate(ScriptSourceCode("var counter = 0; ++c ounter;")));
105 waitEvent->signal();
106 }
107
108 OwnPtr<DummyPageHolder> m_page;
109 RefPtr<SecurityOrigin> m_securityOrigin;
110 OwnPtr<WorkerObjectProxy> m_objectProxy;
111 };
112
113 TEST_F(CompositorWorkerManagerTest, Basic)
114 {
115 OwnPtr<WebWaitableEvent> creationEvent = adoptPtr(Platform::current()->creat eWaitableEvent());
116 RefPtr<CompositorWorkerThread> compositorWorker = createCompositorWorker(cre ationEvent.get());
117 creationEvent->wait();
118 checkWorkerCanExecuteScript(compositorWorker.get());
119 compositorWorker->terminateAndWait();
120 }
121
122 // Tests that the same WebThread is used for new workers if the WebThread is sti ll alive.
123 TEST_F(CompositorWorkerManagerTest, CreateSecondAndTerminateFirst)
124 {
125 // Create the first worker and wait until it is initialized.
126 OwnPtr<WebWaitableEvent> firstCreationEvent = adoptPtr(Platform::current()-> createWaitableEvent());
127 RefPtr<CompositorWorkerThread> firstWorker = createCompositorWorker(firstCre ationEvent.get());
128 WebThreadSupportingGC* firstThread = &CompositorWorkerManager::instance()->c ompositorWorkerThread();
129 ASSERT(firstThread);
130 firstCreationEvent->wait();
131 v8::Isolate* firstIsolate = firstWorker->isolate();
132 ASSERT(firstIsolate);
133
134 // Create the second worker and immediately destroy the first worker.
135 OwnPtr<WebWaitableEvent> secondCreationEvent = adoptPtr(Platform::current()- >createWaitableEvent());
136 RefPtr<CompositorWorkerThread> secondWorker = createCompositorWorker(secondC reationEvent.get());
137 firstWorker->terminateAndWait();
138
139 // Wait until the second worker is initialized. Verify that the second worke r is using the same
140 // thread and Isolate as the first worker.
141 WebThreadSupportingGC* secondThread = &CompositorWorkerManager::instance()-> compositorWorkerThread();
142 ASSERT(secondThread);
143 secondCreationEvent->wait();
144 EXPECT_EQ(firstThread, secondThread);
145
146 v8::Isolate* secondIsolate = secondWorker->isolate();
147 ASSERT(secondIsolate);
148 EXPECT_EQ(firstIsolate, secondIsolate);
149
150 // Verify that the worker can still successfully execute script.
151 checkWorkerCanExecuteScript(secondWorker.get());
152
153 secondWorker->terminateAndWait();
154 }
155
156 static void checkCurrentIsolate(v8::Isolate* isolate, WebWaitableEvent* event)
157 {
158 EXPECT_EQ(v8::Isolate::GetCurrent(), isolate);
159 event->signal();
160 }
161
162 // Tests that a new WebThread is created if all existing workers are terminated before a new worker is created.
163 TEST_F(CompositorWorkerManagerTest, TerminateFirstAndCreateSecond)
164 {
165 // Create the first worker, wait until it is initialized, and terminate it.
166 OwnPtr<WebWaitableEvent> creationEvent = adoptPtr(Platform::current()->creat eWaitableEvent());
167 RefPtr<CompositorWorkerThread> compositorWorker = createCompositorWorker(cre ationEvent.get());
168 WebThreadSupportingGC* firstThread = &CompositorWorkerManager::instance()->c ompositorWorkerThread();
169 creationEvent->wait();
170 ASSERT(compositorWorker->isolate());
171 compositorWorker->terminateAndWait();
172
173 // Create the second worker. Verify that the second worker lives in a differ ent WebThread since the first
174 // thread will have been destroyed after destroying the first worker.
175 creationEvent = adoptPtr(Platform::current()->createWaitableEvent());
176 compositorWorker = createCompositorWorker(creationEvent.get());
177 WebThreadSupportingGC* secondThread = &CompositorWorkerManager::instance()-> compositorWorkerThread();
178 EXPECT_NE(firstThread, secondThread);
179 creationEvent->wait();
180
181 // Jump over to the worker's thread to verify that the Isolate is set up cor rectly and execute script.
182 OwnPtr<WebWaitableEvent> checkEvent = adoptPtr(Platform::current()->createWa itableEvent());
183 secondThread->platformThread().postTask(FROM_HERE, threadSafeBind(&checkCurr entIsolate, AllowCrossThreadAccess(compositorWorker->isolate()), AllowCrossThrea dAccess(checkEvent.get())));
184 checkEvent->wait();
185 checkWorkerCanExecuteScript(compositorWorker.get());
186
187 compositorWorker->terminateAndWait();
188 }
189
190 // Tests that v8::Isolate and WebThread are correctly set-up if a worker is crea ted while another is terminating.
191 TEST_F(CompositorWorkerManagerTest, CreatingSecondDuringTerminationOfFirst)
192 {
193 OwnPtr<WebWaitableEvent> firstCreationEvent = adoptPtr(Platform::current()-> createWaitableEvent());
194 RefPtr<TestCompositorWorkerThread> firstWorker = createCompositorWorker(firs tCreationEvent.get());
195 firstCreationEvent->wait();
196 v8::Isolate* firstIsolate = firstWorker->isolate();
197 ASSERT(firstIsolate);
198
199 // Request termination of the first worker, and set-up to make sure the seco nd worker is created right as
200 // the first worker terminates its isolate.
201 OwnPtr<WebWaitableEvent> secondCreationEvent = adoptPtr(Platform::current()- >createWaitableEvent());
202 RefPtr<CompositorWorkerThread> secondWorker;
203 firstWorker->executeCallbackAfterV8Termination(bind(&CompositorWorkerManager Test::createSecondWorker, this, &secondWorker, secondCreationEvent.get()));
204 firstWorker->terminateAndWait();
205 ASSERT(secondWorker);
206
207 secondCreationEvent->wait();
208 v8::Isolate* secondIsolate = secondWorker->isolate();
209 ASSERT(secondIsolate);
210 EXPECT_EQ(firstIsolate, secondIsolate);
211
212 // Verify that the isolate can run some scripts correctly in the second work er.
213 checkWorkerCanExecuteScript(secondWorker.get());
214 secondWorker->terminateAndWait();
215 }
216
217 } // namespace
218 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698