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

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: tot-merge 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 setCallbackAfterV8Termination(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 } // namespace
57
58 class CompositorWorkerManagerTest : public testing::Test {
59 public:
60 void SetUp() override
61 {
62 m_page = DummyPageHolder::create();
63 m_objectProxy = WorkerObjectProxy::create(&m_page->document(), nullptr);
64 m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http:// fake.url/"));
65 }
66
67 void TearDown() override
68 {
69 ASSERT(!managerHasThread());
70 ASSERT(!managerHasIsolate());
71 m_page.clear();
72 }
73
74 PassRefPtr<TestCompositorWorkerThread> createCompositorWorker(WebWaitableEve nt* startEvent)
75 {
76 TestCompositorWorkerThread* workerThread = new TestCompositorWorkerThrea d(nullptr, *m_objectProxy, 0, startEvent);
77 workerThread->start(WorkerThreadStartupData::create(
78 KURL(ParsedURLString, "http://fake.url/"),
79 "fake user agent",
80 "//fake source code",
81 nullptr,
82 DontPauseWorkerGlobalScopeOnStart,
83 adoptPtr(new Vector<CSPHeaderAndType>()),
84 m_securityOrigin.get(),
85 WorkerClients::create(),
86 V8CacheOptionsDefault));
87 return adoptRef(workerThread);
88 }
89
90 void createWorkerAdapter(RefPtr<CompositorWorkerThread>* workerThread, WebWa itableEvent* creationEvent)
91 {
92 *workerThread = createCompositorWorker(creationEvent);
93 }
94
95 // Attempts to run some simple script for |worker|.
96 void checkWorkerCanExecuteScript(WorkerThread* worker)
97 {
98 OwnPtr<WebWaitableEvent> waitEvent = adoptPtr(Platform::current()->creat eWaitableEvent());
99 worker->backingThread().platformThread().postTask(FROM_HERE, threadSafeB ind(&CompositorWorkerManagerTest::executeScriptInWorker, AllowCrossThreadAccess( this),
100 AllowCrossThreadAccess(worker), AllowCrossThreadAccess(waitEvent.get ())));
101 waitEvent->wait();
102 }
103
104 bool managerHasThread() const
105 {
106 return CompositorWorkerManager::instance()->m_thread;
107 }
108
109 bool managerHasIsolate() const
110 {
111 return CompositorWorkerManager::instance()->m_isolate;
112 }
113
114 private:
115 void executeScriptInWorker(WorkerThread* worker, WebWaitableEvent* waitEvent )
116 {
117 WorkerScriptController* scriptController = worker->workerGlobalScope()-> script();
118 bool evaluateResult = scriptController->evaluate(ScriptSourceCode("var c ounter = 0; ++counter;"));
119 ASSERT_UNUSED(evaluateResult, evaluateResult);
120 waitEvent->signal();
121 }
122
123 OwnPtr<DummyPageHolder> m_page;
124 RefPtr<SecurityOrigin> m_securityOrigin;
125 OwnPtr<WorkerObjectProxy> m_objectProxy;
126 };
127
128 TEST_F(CompositorWorkerManagerTest, Basic)
129 {
130 OwnPtr<WebWaitableEvent> creationEvent = adoptPtr(Platform::current()->creat eWaitableEvent());
131 RefPtr<CompositorWorkerThread> compositorWorker = createCompositorWorker(cre ationEvent.get());
132 creationEvent->wait();
133 checkWorkerCanExecuteScript(compositorWorker.get());
134 compositorWorker->terminateAndWait();
135 }
136
137 // Tests that the same WebThread is used for new workers if the WebThread is sti ll alive.
138 TEST_F(CompositorWorkerManagerTest, CreateSecondAndTerminateFirst)
139 {
140 // Create the first worker and wait until it is initialized.
141 OwnPtr<WebWaitableEvent> firstCreationEvent = adoptPtr(Platform::current()-> createWaitableEvent());
142 RefPtr<CompositorWorkerThread> firstWorker = createCompositorWorker(firstCre ationEvent.get());
143 WebThreadSupportingGC* firstThread = &CompositorWorkerManager::instance()->c ompositorWorkerThread();
144 ASSERT(firstThread);
145 firstCreationEvent->wait();
146 v8::Isolate* firstIsolate = firstWorker->isolate();
147 ASSERT(firstIsolate);
148
149 // Create the second worker and immediately destroy the first worker.
150 OwnPtr<WebWaitableEvent> secondCreationEvent = adoptPtr(Platform::current()- >createWaitableEvent());
151 RefPtr<CompositorWorkerThread> secondWorker = createCompositorWorker(secondC reationEvent.get());
152 firstWorker->terminateAndWait();
153
154 // Wait until the second worker is initialized. Verify that the second worke r is using the same
155 // thread and Isolate as the first worker.
156 WebThreadSupportingGC* secondThread = &CompositorWorkerManager::instance()-> compositorWorkerThread();
157 ASSERT(secondThread);
158 secondCreationEvent->wait();
159 EXPECT_EQ(firstThread, secondThread);
160
161 v8::Isolate* secondIsolate = secondWorker->isolate();
162 ASSERT(secondIsolate);
163 EXPECT_EQ(firstIsolate, secondIsolate);
164
165 // Verify that the worker can still successfully execute script.
166 checkWorkerCanExecuteScript(secondWorker.get());
167
168 secondWorker->terminateAndWait();
169 }
170
171 static void checkCurrentIsolate(v8::Isolate* isolate, WebWaitableEvent* event)
172 {
173 EXPECT_EQ(v8::Isolate::GetCurrent(), isolate);
174 event->signal();
175 }
176
177 // Tests that a new WebThread is created if all existing workers are terminated before a new worker is created.
178 TEST_F(CompositorWorkerManagerTest, TerminateFirstAndCreateSecond)
179 {
180 // Create the first worker, wait until it is initialized, and terminate it.
181 OwnPtr<WebWaitableEvent> creationEvent = adoptPtr(Platform::current()->creat eWaitableEvent());
182 RefPtr<CompositorWorkerThread> compositorWorker = createCompositorWorker(cre ationEvent.get());
183 WebThreadSupportingGC* firstThread = &CompositorWorkerManager::instance()->c ompositorWorkerThread();
184 creationEvent->wait();
185 ASSERT(compositorWorker->isolate());
186 compositorWorker->terminateAndWait();
187
188 // Create the second worker. Verify that the second worker lives in a differ ent WebThread since the first
189 // thread will have been destroyed after destroying the first worker.
190 creationEvent = adoptPtr(Platform::current()->createWaitableEvent());
191 compositorWorker = createCompositorWorker(creationEvent.get());
192 WebThreadSupportingGC* secondThread = &CompositorWorkerManager::instance()-> compositorWorkerThread();
193 EXPECT_NE(firstThread, secondThread);
194 creationEvent->wait();
195
196 // Jump over to the worker's thread to verify that the Isolate is set up cor rectly and execute script.
197 OwnPtr<WebWaitableEvent> checkEvent = adoptPtr(Platform::current()->createWa itableEvent());
198 secondThread->platformThread().postTask(FROM_HERE, threadSafeBind(&checkCurr entIsolate, AllowCrossThreadAccess(compositorWorker->isolate()), AllowCrossThrea dAccess(checkEvent.get())));
199 checkEvent->wait();
200 checkWorkerCanExecuteScript(compositorWorker.get());
201
202 compositorWorker->terminateAndWait();
203 }
204
205 // Tests that v8::Isolate and WebThread are correctly set-up if a worker is crea ted while another is terminating.
206 TEST_F(CompositorWorkerManagerTest, CreatingSecondDuringTerminationOfFirst)
207 {
208 OwnPtr<WebWaitableEvent> firstCreationEvent = adoptPtr(Platform::current()-> createWaitableEvent());
209 RefPtr<TestCompositorWorkerThread> firstWorker = createCompositorWorker(firs tCreationEvent.get());
210 firstCreationEvent->wait();
211 v8::Isolate* firstIsolate = firstWorker->isolate();
212 ASSERT(firstIsolate);
213
214 // Request termination of the first worker, and set-up to make sure the seco nd worker is created right as
215 // the first worker terminates its isolate.
216 OwnPtr<WebWaitableEvent> secondCreationEvent = adoptPtr(Platform::current()- >createWaitableEvent());
217 RefPtr<CompositorWorkerThread> secondWorker;
218 firstWorker->setCallbackAfterV8Termination(bind(&CompositorWorkerManagerTest ::createWorkerAdapter, this, &secondWorker, secondCreationEvent.get()));
219 firstWorker->terminateAndWait();
220 ASSERT(secondWorker);
221
222 secondCreationEvent->wait();
223 v8::Isolate* secondIsolate = secondWorker->isolate();
224 ASSERT(secondIsolate);
225 EXPECT_EQ(firstIsolate, secondIsolate);
226
227 // Verify that the isolate can run some scripts correctly in the second work er.
228 checkWorkerCanExecuteScript(secondWorker.get());
229 secondWorker->terminateAndWait();
230 }
231
232 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/compositorworker/CompositorWorkerManager.cpp ('k') | Source/modules/compositorworker/CompositorWorkerThread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698