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

Unified Diff: third_party/WebKit/Source/core/workers/WorkerOrWorkletThread.cpp

Issue 1992933002: Introduce WorkletGlobalScopeProxy interface. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix tests. Created 4 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/workers/WorkerOrWorkletThread.cpp
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerOrWorkletThread.cpp
similarity index 72%
copy from third_party/WebKit/Source/core/workers/WorkerThread.cpp
copy to third_party/WebKit/Source/core/workers/WorkerOrWorkletThread.cpp
index 62c4fd888ac86f03869271c109be5607ccb159c8..1a9980856e9b4882ad35cc0f4adb80f34a0e4381 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerOrWorkletThread.cpp
@@ -24,7 +24,7 @@
*
*/
-#include "core/workers/WorkerThread.h"
+#include "core/workers/WorkerOrWorkletThread.h"
#include "bindings/core/v8/Microtask.h"
#include "bindings/core/v8/ScriptSourceCode.h"
@@ -61,9 +61,9 @@ const long long kForceTerminationDelayInMs = 2000; // 2 secs
// shutdown sequence does not start in a certain time period because of an
// inifite loop in the JS execution context etc. When the shutdown sequence is
// started before this task runs, the task is simply cancelled.
-class WorkerThread::ForceTerminationTask final {
+class WorkerOrWorkletThread::ForceTerminationTask final {
public:
- static PassOwnPtr<ForceTerminationTask> create(WorkerThread* workerThread)
+ static PassOwnPtr<ForceTerminationTask> create(WorkerOrWorkletThread* workerThread)
{
return adoptPtr(new ForceTerminationTask(workerThread));
}
@@ -75,7 +75,7 @@ public:
}
private:
- explicit ForceTerminationTask(WorkerThread* workerThread)
+ explicit ForceTerminationTask(WorkerOrWorkletThread* workerThread)
: m_workerThread(workerThread)
{
DCHECK(isMainThread());
@@ -92,17 +92,17 @@ private:
}
m_workerThread->forciblyTerminateExecution();
- DCHECK_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->m_exitCode);
- m_workerThread->m_exitCode = WorkerThread::ExitCode::AsyncForciblyTerminated;
+ DCHECK_EQ(WorkerOrWorkletThread::ExitCode::NotTerminated, m_workerThread->m_exitCode);
+ m_workerThread->m_exitCode = WorkerOrWorkletThread::ExitCode::AsyncForciblyTerminated;
}
- WorkerThread* m_workerThread;
+ WorkerOrWorkletThread* m_workerThread;
OwnPtr<CancellableTaskFactory> m_cancellableTaskFactory;
};
-class WorkerThread::WorkerMicrotaskRunner final : public WebThread::TaskObserver {
+class WorkerOrWorkletThread::WorkerMicrotaskRunner final : public WebThread::TaskObserver {
public:
- explicit WorkerMicrotaskRunner(WorkerThread* workerThread)
+ explicit WorkerMicrotaskRunner(WorkerOrWorkletThread* workerThread)
: m_workerThread(workerThread)
{
}
@@ -110,16 +110,16 @@ public:
void willProcessTask() override
{
// No tasks should get executed after we have closed.
- DCHECK(!m_workerThread->workerGlobalScope() || !m_workerThread->workerGlobalScope()->isClosing());
+ DCHECK(!m_workerThread->globalScope() || !m_workerThread->globalScope()->isClosing());
}
void didProcessTask() override
{
Microtask::performCheckpoint(m_workerThread->isolate());
- if (WorkerGlobalScope* globalScope = m_workerThread->workerGlobalScope()) {
- if (WorkerOrWorkletScriptController* scriptController = globalScope->scriptController())
+ if (WorkerOrWorkletGlobalScope* global = m_workerThread->globalScope()) {
+ if (WorkerOrWorkletScriptController* scriptController = global->scriptController())
scriptController->getRejectedPromises()->processQueue();
- if (globalScope->isClosing()) {
+ if (global->isClosing()) {
// |m_workerThread| will eventually be requested to terminate.
m_workerThread->workerReportingProxy().workerGlobalScopeClosed();
@@ -132,7 +132,7 @@ public:
private:
// Thread owns the microtask runner; reference remains
// valid for the lifetime of this object.
- WorkerThread* m_workerThread;
+ WorkerOrWorkletThread* m_workerThread;
};
static Mutex& threadSetMutex()
@@ -141,13 +141,13 @@ static Mutex& threadSetMutex()
return mutex;
}
-static HashSet<WorkerThread*>& workerThreads()
+static HashSet<WorkerOrWorkletThread*>& workerThreads()
{
- DEFINE_STATIC_LOCAL(HashSet<WorkerThread*>, threads, ());
+ DEFINE_STATIC_LOCAL(HashSet<WorkerOrWorkletThread*>, threads, ());
return threads;
}
-WorkerThread::~WorkerThread()
+WorkerOrWorkletThread::~WorkerOrWorkletThread()
{
DCHECK(isMainThread());
MutexLocker lock(threadSetMutex());
@@ -159,24 +159,70 @@ WorkerThread::~WorkerThread()
DCHECK_NE(ExitCode::NotTerminated, m_exitCode);
}
-void WorkerThread::start(PassOwnPtr<WorkerThreadStartupData> startupData)
+void WorkerOrWorkletThread::initializeGlobalScope(GlobalScopeFactory& factory)
{
- DCHECK(isMainThread());
- if (m_started)
- return;
+ {
+ MutexLocker lock(m_threadStateMutex);
+
+ // The worker was terminated before the thread had a chance to run.
+ if (m_terminated) {
+ DCHECK_EQ(ExitCode::GracefullyTerminated, m_exitCode);
+
+ // Notify the proxy that the WorkerGlobalScope has been disposed of.
+ // This can free this thread object, hence it must not be touched
+ // afterwards.
+ m_workerReportingProxy.workerThreadTerminated();
+
+ // Notify the main thread that it is safe to deallocate our
+ // resources.
+ m_shutdownEvent->signal();
+ return;
+ }
+
+ workerBackingThread().attach();
+
+ if (shouldAttachThreadDebugger())
+ V8PerIsolateData::from(isolate())->setThreadDebugger(adoptPtr(new WorkerThreadDebugger(this, isolate())));
+ m_microtaskRunner = adoptPtr(new WorkerMicrotaskRunner(this));
+ workerBackingThread().backingThread().addTaskObserver(m_microtaskRunner.get());
+
+ // Optimize for memory usage instead of latency for the worker isolate.
+ isolate()->IsolateInBackgroundNotification();
+ m_globalScope = factory.create();
- m_started = true;
- workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::initializeOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(startupData))));
+ // Notify proxy that a new WorkerGlobalScope has been created and started.
+ m_workerReportingProxy.workerGlobalScopeStarted(m_globalScope.get());
+
+ WorkerOrWorkletScriptController* scriptController = m_globalScope->scriptController();
+ if (!scriptController->isExecutionForbidden()) {
+ scriptController->initializeContextIfNeeded();
+
+ // If Origin Trials have been registered before the V8 context was ready,
+ // then inject them into the context now
+ ExecutionContext* executionContext = m_globalScope;
+ if (executionContext) {
+ OriginTrialContext* originTrialContext = OriginTrialContext::from(executionContext);
+ if (originTrialContext)
+ originTrialContext->initializePendingFeatures();
+ }
+ }
+ }
+
+ if (m_globalScope->scriptController()->isContextInitialized()) {
+ m_workerReportingProxy.didInitializeWorkerContext();
+ v8::HandleScope handleScope(isolate());
+ Platform::current()->workerContextCreated(m_globalScope->scriptController()->context());
+ }
}
-void WorkerThread::terminate()
+void WorkerOrWorkletThread::terminate()
{
DCHECK(isMainThread());
terminateInternal(TerminationMode::Graceful);
}
-void WorkerThread::terminateAndWait()
+void WorkerOrWorkletThread::terminateAndWait()
{
DCHECK(isMainThread());
@@ -186,55 +232,55 @@ void WorkerThread::terminateAndWait()
m_shutdownEvent->wait();
}
-void WorkerThread::terminateAndWaitForAllWorkers()
+void WorkerOrWorkletThread::terminateAndWaitForAllWorkers()
{
DCHECK(isMainThread());
- // Keep this lock to prevent WorkerThread instances from being destroyed.
+ // Keep this lock to prevent WorkerOrWorkletThread instances from being destroyed.
MutexLocker lock(threadSetMutex());
- HashSet<WorkerThread*> threads = workerThreads();
+ HashSet<WorkerOrWorkletThread*> threads = workerThreads();
// The main thread will be blocked, so asynchronous graceful shutdown does
// not work.
- for (WorkerThread* thread : threads)
+ for (WorkerOrWorkletThread* thread : threads)
thread->terminateInternal(TerminationMode::Forcible);
- for (WorkerThread* thread : threads)
+ for (WorkerOrWorkletThread* thread : threads)
thread->m_shutdownEvent->wait();
}
-v8::Isolate* WorkerThread::isolate()
+v8::Isolate* WorkerOrWorkletThread::isolate()
{
return workerBackingThread().isolate();
}
-bool WorkerThread::isCurrentThread()
+bool WorkerOrWorkletThread::isCurrentThread()
{
return m_started && workerBackingThread().backingThread().isCurrentThread();
}
-void WorkerThread::postTask(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task)
+void WorkerOrWorkletThread::postTask(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task)
{
workerBackingThread().backingThread().postTask(location, createWorkerThreadTask(std::move(task), true));
}
-void WorkerThread::appendDebuggerTask(std::unique_ptr<CrossThreadClosure> task)
+void WorkerOrWorkletThread::appendDebuggerTask(std::unique_ptr<CrossThreadClosure> task)
{
{
MutexLocker lock(m_threadStateMutex);
if (m_readyToShutdown)
return;
}
- m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerThread::runDebuggerTaskOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(task))));
+ m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerOrWorkletThread::runDebuggerTaskOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(task))));
{
MutexLocker lock(m_threadStateMutex);
if (isolate())
m_inspectorTaskRunner->interruptAndRunAllTasksDontWait(isolate());
}
- workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::runDebuggerTaskDontWaitOnWorkerThread, AllowCrossThreadAccess(this)));
+ workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerOrWorkletThread::runDebuggerTaskDontWaitOnWorkerThread, AllowCrossThreadAccess(this)));
}
-void WorkerThread::startRunningDebuggerTasksOnPause()
+void WorkerOrWorkletThread::startRunningDebuggerTasksOnPause()
{
m_pausedInDebugger = true;
ThreadDebugger::idleStarted(isolate());
@@ -251,40 +297,39 @@ void WorkerThread::startRunningDebuggerTasksOnPause()
ThreadDebugger::idleFinished(isolate());
}
-void WorkerThread::stopRunningDebuggerTasksOnPause()
+void WorkerOrWorkletThread::stopRunningDebuggerTasksOnPause()
{
m_pausedInDebugger = false;
}
-WorkerGlobalScope* WorkerThread::workerGlobalScope()
+WorkerOrWorkletGlobalScope* WorkerOrWorkletThread::globalScope()
{
DCHECK(isCurrentThread());
- return m_workerGlobalScope.get();
+ return m_globalScope.get();
}
-bool WorkerThread::terminated()
+bool WorkerOrWorkletThread::terminated()
{
MutexLocker lock(m_threadStateMutex);
return m_terminated;
}
-unsigned WorkerThread::workerThreadCount()
+unsigned WorkerOrWorkletThread::workerThreadCount()
{
MutexLocker lock(threadSetMutex());
return workerThreads().size();
}
-PlatformThreadId WorkerThread::platformThreadId()
+PlatformThreadId WorkerOrWorkletThread::platformThreadId()
{
if (!m_started)
return 0;
return workerBackingThread().backingThread().platformThread().threadId();
}
-WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, WorkerReportingProxy& workerReportingProxy)
+WorkerOrWorkletThread::WorkerOrWorkletThread(WorkerReportingProxy& workerReportingProxy)
: m_forceTerminationDelayInMs(kForceTerminationDelayInMs)
, m_inspectorTaskRunner(adoptPtr(new InspectorTaskRunner()))
- , m_workerLoaderProxy(workerLoaderProxy)
, m_workerReportingProxy(workerReportingProxy)
, m_terminationEvent(adoptPtr(new WaitableEvent(
WaitableEvent::ResetPolicy::Manual,
@@ -297,18 +342,18 @@ WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work
workerThreads().add(this);
}
-std::unique_ptr<CrossThreadClosure> WorkerThread::createWorkerThreadTask(std::unique_ptr<ExecutionContextTask> task, bool isInstrumented)
+std::unique_ptr<CrossThreadClosure> WorkerOrWorkletThread::createWorkerThreadTask(std::unique_ptr<ExecutionContextTask> task, bool isInstrumented)
{
if (isInstrumented)
isInstrumented = !task->taskNameForInstrumentation().isEmpty();
if (isInstrumented) {
DCHECK(isCurrentThread());
- InspectorInstrumentation::asyncTaskScheduled(workerGlobalScope(), "Worker task", task.get());
+ InspectorInstrumentation::asyncTaskScheduled(globalScope(), "Worker task", task.get());
}
- return threadSafeBind(&WorkerThread::performTaskOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(task)), isInstrumented);
+ return threadSafeBind(&WorkerOrWorkletThread::performTaskOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(task)), isInstrumented);
}
-void WorkerThread::terminateInternal(TerminationMode mode)
+void WorkerOrWorkletThread::terminateInternal(TerminationMode mode)
{
DCHECK(m_started);
@@ -342,7 +387,7 @@ void WorkerThread::terminateInternal(TerminationMode mode)
// If the worker thread was never initialized, don't start another
// shutdown, but still wait for the thread to signal when shutdown has
// completed on initializeOnWorkerThread().
- if (!m_workerGlobalScope) {
+ if (!m_globalScope) {
DCHECK_EQ(ExitCode::NotTerminated, m_exitCode);
m_exitCode = ExitCode::GracefullyTerminated;
return;
@@ -358,7 +403,7 @@ void WorkerThread::terminateInternal(TerminationMode mode)
// scope is already disposed, so we don't have to explicitly terminate the
// worker execution.
//
- // (2) |workerScriptCount() == 1|: If other WorkerGlobalScopes are running
+ // (2) |workerScriptCount() == 1|: If other WorkerOrWorkletGlobalScopes are running
// on the worker thread, we should not terminate the worker execution. This
// condition is not entirely correct because other scripts can be being
// initialized or terminated simuletaneously. Though this function itself is
@@ -384,91 +429,18 @@ void WorkerThread::terminateInternal(TerminationMode mode)
}
m_inspectorTaskRunner->kill();
- workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::prepareForShutdownOnWorkerThread, AllowCrossThreadAccess(this)));
- workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::performShutdownOnWorkerThread, AllowCrossThreadAccess(this)));
+ workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerOrWorkletThread::prepareForShutdownOnWorkerThread, AllowCrossThreadAccess(this)));
+ workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerOrWorkletThread::performShutdownOnWorkerThread, AllowCrossThreadAccess(this)));
}
-void WorkerThread::forciblyTerminateExecution()
+void WorkerOrWorkletThread::forciblyTerminateExecution()
{
- DCHECK(m_workerGlobalScope);
- m_workerGlobalScope->scriptController()->willScheduleExecutionTermination();
+ DCHECK(m_globalScope);
+ m_globalScope->scriptController()->willScheduleExecutionTermination();
isolate()->TerminateExecution();
}
-void WorkerThread::initializeOnWorkerThread(PassOwnPtr<WorkerThreadStartupData> startupData)
-{
- KURL scriptURL = startupData->m_scriptURL;
- String sourceCode = startupData->m_sourceCode;
- WorkerThreadStartMode startMode = startupData->m_startMode;
- OwnPtr<Vector<char>> cachedMetaData = std::move(startupData->m_cachedMetaData);
- V8CacheOptions v8CacheOptions = startupData->m_v8CacheOptions;
-
- {
- MutexLocker lock(m_threadStateMutex);
-
- // The worker was terminated before the thread had a chance to run.
- if (m_terminated) {
- DCHECK_EQ(ExitCode::GracefullyTerminated, m_exitCode);
-
- // Notify the proxy that the WorkerGlobalScope has been disposed of.
- // This can free this thread object, hence it must not be touched
- // afterwards.
- m_workerReportingProxy.workerThreadTerminated();
-
- // Notify the main thread that it is safe to deallocate our
- // resources.
- m_shutdownEvent->signal();
- return;
- }
-
- workerBackingThread().attach();
-
- if (shouldAttachThreadDebugger())
- V8PerIsolateData::from(isolate())->setThreadDebugger(adoptPtr(new WorkerThreadDebugger(this, isolate())));
- m_microtaskRunner = adoptPtr(new WorkerMicrotaskRunner(this));
- workerBackingThread().backingThread().addTaskObserver(m_microtaskRunner.get());
-
- // Optimize for memory usage instead of latency for the worker isolate.
- isolate()->IsolateInBackgroundNotification();
- m_workerGlobalScope = createWorkerGlobalScope(std::move(startupData));
- m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.get() ? cachedMetaData->size() : 0);
-
- // Notify proxy that a new WorkerGlobalScope has been created and started.
- m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get());
-
- WorkerOrWorkletScriptController* scriptController = m_workerGlobalScope->scriptController();
- if (!scriptController->isExecutionForbidden()) {
- scriptController->initializeContextIfNeeded();
-
- // If Origin Trials have been registered before the V8 context was ready,
- // then inject them into the context now
- ExecutionContext* executionContext = m_workerGlobalScope->getExecutionContext();
- if (executionContext) {
- OriginTrialContext* originTrialContext = OriginTrialContext::from(executionContext);
- if (originTrialContext)
- originTrialContext->initializePendingFeatures();
- }
- }
- }
-
- if (startMode == PauseWorkerGlobalScopeOnStart)
- startRunningDebuggerTasksOnPause();
-
- if (m_workerGlobalScope->scriptController()->isContextInitialized()) {
- m_workerReportingProxy.didInitializeWorkerContext();
- v8::HandleScope handleScope(isolate());
- Platform::current()->workerContextCreated(m_workerGlobalScope->scriptController()->context());
- }
-
- CachedMetadataHandler* handler = workerGlobalScope()->createWorkerScriptCachedMetadataHandler(scriptURL, cachedMetaData.get());
- bool success = m_workerGlobalScope->scriptController()->evaluate(ScriptSourceCode(sourceCode, scriptURL), nullptr, handler, v8CacheOptions);
- m_workerGlobalScope->didEvaluateWorkerScript();
- m_workerReportingProxy.didEvaluateWorkerScript(success);
-
- postInitialize();
-}
-
-void WorkerThread::prepareForShutdownOnWorkerThread()
+void WorkerOrWorkletThread::prepareForShutdownOnWorkerThread()
{
DCHECK(isCurrentThread());
{
@@ -481,12 +453,12 @@ void WorkerThread::prepareForShutdownOnWorkerThread()
}
workerReportingProxy().willDestroyWorkerGlobalScope();
- InspectorInstrumentation::allAsyncTasksCanceled(workerGlobalScope());
- workerGlobalScope()->dispose();
+ InspectorInstrumentation::allAsyncTasksCanceled(globalScope());
+ globalScope()->dispose();
workerBackingThread().backingThread().removeTaskObserver(m_microtaskRunner.get());
}
-void WorkerThread::performShutdownOnWorkerThread()
+void WorkerOrWorkletThread::performShutdownOnWorkerThread()
{
DCHECK(isCurrentThread());
#if DCHECK_IS_ON
@@ -502,8 +474,8 @@ void WorkerThread::performShutdownOnWorkerThread()
// because no other thread will run GC or otherwise destroy them. If Oilpan
// is enabled, we detach of the context/global scope, with the final heap
// cleanup below sweeping it out.
- m_workerGlobalScope->notifyContextDestroyed();
- m_workerGlobalScope = nullptr;
+ m_globalScope->notifyContextDestroyed();
+ m_globalScope = nullptr;
workerBackingThread().detach();
// We must not touch workerBackingThread() from now on.
@@ -518,7 +490,7 @@ void WorkerThread::performShutdownOnWorkerThread()
m_shutdownEvent->signal();
}
-void WorkerThread::performTaskOnWorkerThread(std::unique_ptr<ExecutionContextTask> task, bool isInstrumented)
+void WorkerOrWorkletThread::performTaskOnWorkerThread(std::unique_ptr<ExecutionContextTask> task, bool isInstrumented)
{
DCHECK(isCurrentThread());
{
@@ -527,19 +499,19 @@ void WorkerThread::performTaskOnWorkerThread(std::unique_ptr<ExecutionContextTas
return;
}
- WorkerGlobalScope* globalScope = workerGlobalScope();
+ WorkerOrWorkletGlobalScope* global = globalScope();
// If the thread is terminated before it had a chance initialize (see
- // WorkerThread::Initialize()), we mustn't run any of the posted tasks.
- if (!globalScope) {
+ // WorkerOrWorkletThread::Initialize()), we mustn't run any of the posted tasks.
+ if (!global) {
DCHECK(terminated());
return;
}
- InspectorInstrumentation::AsyncTask asyncTask(globalScope, task.get(), isInstrumented);
- task->performTask(globalScope);
+ InspectorInstrumentation::AsyncTask asyncTask(global, task.get(), isInstrumented);
+ task->performTask(global);
}
-void WorkerThread::runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClosure> task)
+void WorkerOrWorkletThread::runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClosure> task)
{
DCHECK(isCurrentThread());
InspectorTaskRunner::IgnoreInterruptsScope scope(m_inspectorTaskRunner.get());
@@ -562,7 +534,7 @@ void WorkerThread::runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClos
prepareForShutdownOnWorkerThread();
}
-void WorkerThread::runDebuggerTaskDontWaitOnWorkerThread()
+void WorkerOrWorkletThread::runDebuggerTaskDontWaitOnWorkerThread()
{
DCHECK(isCurrentThread());
std::unique_ptr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::DontWaitForTask);
@@ -570,7 +542,7 @@ void WorkerThread::runDebuggerTaskDontWaitOnWorkerThread()
(*task)();
}
-WorkerThread::ExitCode WorkerThread::getExitCode()
+WorkerOrWorkletThread::ExitCode WorkerOrWorkletThread::getExitCode()
{
MutexLocker lock(m_threadStateMutex);
return m_exitCode;

Powered by Google App Engine
This is Rietveld 408576698