Commit 66b07a32 authored by kinuko's avatar kinuko Committed by Commit bot

Pass per-frame task runners to Workers (when possible)

- For in-process workers (i.e. dedicated/compositor workers): always use
  the associated document's task runners
- For out-of-process workers (i.e. service/shared workers): keep using the
  default task runner of the main thread, but via TaskRunnerHelper so
  we could still start using different task runners for different tasks
  (e.g. loading vs timer) if we want.

BUG=627034

Review-Url: https://codereview.chromium.org/2163983004
Cr-Commit-Position: refs/heads/master@{#408652}
parent b737ad86
......@@ -2264,6 +2264,8 @@
'workers/InProcessWorkerObjectProxy.h',
'workers/MainThreadWorkletGlobalScope.cpp',
'workers/MainThreadWorkletGlobalScope.h',
'workers/ParentFrameTaskRunners.cpp',
'workers/ParentFrameTaskRunners.h',
'workers/SharedWorker.cpp',
'workers/SharedWorker.h',
'workers/SharedWorkerGlobalScope.cpp',
......
......@@ -32,6 +32,7 @@
#include "core/dom/CrossThreadTask.h"
#include "core/dom/Document.h"
#include "core/dom/SecurityContext.h"
#include "core/dom/TaskRunnerHelper.h"
#include "core/events/ErrorEvent.h"
#include "core/events/MessageEvent.h"
#include "core/frame/FrameConsole.h"
......@@ -43,10 +44,12 @@
#include "core/origin_trials/OriginTrialContext.h"
#include "core/workers/InProcessWorkerBase.h"
#include "core/workers/InProcessWorkerObjectProxy.h"
#include "core/workers/ParentFrameTaskRunners.h"
#include "core/workers/WorkerClients.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerInspectorProxy.h"
#include "core/workers/WorkerThreadStartupData.h"
#include "public/platform/WebTaskRunner.h"
#include "wtf/WTF.h"
#include <memory>
......@@ -82,6 +85,7 @@ InProcessWorkerMessagingProxy::InProcessWorkerMessagingProxy(InProcessWorkerBase
, m_askedToTerminate(false)
, m_workerInspectorProxy(WorkerInspectorProxy::create())
, m_workerClients(workerClients)
, m_parentFrameTaskRunners(ParentFrameTaskRunners::create(toDocument(m_executionContext.get())))
{
DCHECK(isParentContextThread());
DCHECK(m_workerObject);
......@@ -168,6 +172,8 @@ bool InProcessWorkerMessagingProxy::postTaskToWorkerGlobalScope(std::unique_ptr<
void InProcessWorkerMessagingProxy::postTaskToLoader(std::unique_ptr<ExecutionContextTask> task)
{
DCHECK(getExecutionContext()->isDocument());
// TODO(hiroshige,yuryu): Make this not use ExecutionContextTask and use
// m_parentFrameTaskRunners->getLoadingTaskRunner() instead.
getExecutionContext()->postTask(BLINK_FROM_HERE, std::move(task));
}
......@@ -223,7 +229,7 @@ void InProcessWorkerMessagingProxy::workerObjectDestroyed()
// cleared before this method gets called.
DCHECK(!m_workerObject);
getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&InProcessWorkerMessagingProxy::workerObjectDestroyedInternal, crossThreadUnretained(this)));
m_parentFrameTaskRunners->getUnthrottledTaskRunner()->postTask(BLINK_FROM_HERE, WTF::bind(&InProcessWorkerMessagingProxy::workerObjectDestroyedInternal, unretained(this)));
}
void InProcessWorkerMessagingProxy::workerObjectDestroyedInternal()
......
......@@ -41,12 +41,13 @@
namespace blink {
class InProcessWorkerObjectProxy;
class WorkerThread;
class ExecutionContext;
class InProcessWorkerBase;
class InProcessWorkerObjectProxy;
class ParentFrameTaskRunners;
class WorkerClients;
class WorkerInspectorProxy;
class WorkerThread;
// TODO(nhiroki): "MessagingProxy" is not well-defined term among worker
// components. Probably we should rename this to something more suitable.
......@@ -77,6 +78,8 @@ public:
ExecutionContext* getExecutionContext() const { return m_executionContext.get(); }
ParentFrameTaskRunners* getParentFrameTaskRunners() { return m_parentFrameTaskRunners.get(); }
// Number of live messaging proxies, used by leak detection.
static int proxyCount();
......@@ -124,6 +127,8 @@ private:
Persistent<WorkerClients> m_workerClients;
std::unique_ptr<ParentFrameTaskRunners> m_parentFrameTaskRunners;
RefPtr<WorkerLoaderProxy> m_loaderProxy;
};
......
......@@ -37,6 +37,9 @@
#include "core/dom/ExecutionContext.h"
#include "core/inspector/ConsoleMessage.h"
#include "core/workers/InProcessWorkerMessagingProxy.h"
#include "core/workers/ParentFrameTaskRunners.h"
#include "platform/CrossThreadFunctional.h"
#include "public/platform/WebTaskRunner.h"
#include "wtf/Functional.h"
#include "wtf/PtrUtil.h"
#include <memory>
......@@ -51,50 +54,55 @@ std::unique_ptr<InProcessWorkerObjectProxy> InProcessWorkerObjectProxy::create(I
void InProcessWorkerObjectProxy::postMessageToWorkerObject(PassRefPtr<SerializedScriptValue> message, std::unique_ptr<MessagePortChannelArray> channels)
{
getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&InProcessWorkerMessagingProxy::postMessageToWorkerObject, crossThreadUnretained(m_messagingProxy), message, passed(std::move(channels))));
getParentFrameTaskRunners()->getUnthrottledTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadBind(&InProcessWorkerMessagingProxy::postMessageToWorkerObject, crossThreadUnretained(m_messagingProxy), message, passed(std::move(channels))));
}
void InProcessWorkerObjectProxy::postTaskToMainExecutionContext(std::unique_ptr<ExecutionContextTask> task)
{
// TODO(hiroshige,yuryu): Make this not use ExecutionContextTask and use
// getParentFrameTaskRunners() instead.
getExecutionContext()->postTask(BLINK_FROM_HERE, std::move(task));
}
void InProcessWorkerObjectProxy::confirmMessageFromWorkerObject(bool hasPendingActivity)
{
getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&InProcessWorkerMessagingProxy::confirmMessageFromWorkerObject, crossThreadUnretained(m_messagingProxy), hasPendingActivity));
getParentFrameTaskRunners()->getUnthrottledTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadBind(&InProcessWorkerMessagingProxy::confirmMessageFromWorkerObject, crossThreadUnretained(m_messagingProxy), hasPendingActivity));
}
void InProcessWorkerObjectProxy::reportPendingActivity(bool hasPendingActivity)
{
getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&InProcessWorkerMessagingProxy::reportPendingActivity, crossThreadUnretained(m_messagingProxy), hasPendingActivity));
getParentFrameTaskRunners()->getUnthrottledTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadBind(&InProcessWorkerMessagingProxy::reportPendingActivity, crossThreadUnretained(m_messagingProxy), hasPendingActivity));
}
void InProcessWorkerObjectProxy::reportException(const String& errorMessage, std::unique_ptr<SourceLocation> location)
{
getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&InProcessWorkerMessagingProxy::reportException, crossThreadUnretained(m_messagingProxy), errorMessage, passed(std::move(location))));
getParentFrameTaskRunners()->getUnthrottledTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadBind(&InProcessWorkerMessagingProxy::reportException, crossThreadUnretained(m_messagingProxy), errorMessage, passed(std::move(location))));
}
void InProcessWorkerObjectProxy::reportConsoleMessage(ConsoleMessage* consoleMessage)
{
getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&InProcessWorkerMessagingProxy::reportConsoleMessage, crossThreadUnretained(m_messagingProxy), consoleMessage->source(), consoleMessage->level(), consoleMessage->message(), passed(consoleMessage->location()->clone())));
getParentFrameTaskRunners()->getUnthrottledTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadBind(&InProcessWorkerMessagingProxy::reportConsoleMessage, crossThreadUnretained(m_messagingProxy), consoleMessage->source(), consoleMessage->level(), consoleMessage->message(), passed(consoleMessage->location()->clone())));
}
void InProcessWorkerObjectProxy::postMessageToPageInspector(const String& message)
{
ExecutionContext* context = getExecutionContext();
if (context->isDocument())
if (context->isDocument()) {
// TODO(hiroshige): consider using getParentFrameTaskRunners() here
// too.
toDocument(context)->postInspectorTask(BLINK_FROM_HERE, createCrossThreadTask(&InProcessWorkerMessagingProxy::postMessageToPageInspector, crossThreadUnretained(m_messagingProxy), message));
}
}
void InProcessWorkerObjectProxy::workerGlobalScopeClosed()
{
getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&InProcessWorkerMessagingProxy::terminateWorkerGlobalScope, crossThreadUnretained(m_messagingProxy)));
getParentFrameTaskRunners()->getUnthrottledTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadBind(&InProcessWorkerMessagingProxy::terminateWorkerGlobalScope, crossThreadUnretained(m_messagingProxy)));
}
void InProcessWorkerObjectProxy::workerThreadTerminated()
{
// This will terminate the MessagingProxy.
getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&InProcessWorkerMessagingProxy::workerThreadTerminated, crossThreadUnretained(m_messagingProxy)));
getParentFrameTaskRunners()->getUnthrottledTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadBind(&InProcessWorkerMessagingProxy::workerThreadTerminated, crossThreadUnretained(m_messagingProxy)));
}
InProcessWorkerObjectProxy::InProcessWorkerObjectProxy(InProcessWorkerMessagingProxy* messagingProxy)
......@@ -102,6 +110,12 @@ InProcessWorkerObjectProxy::InProcessWorkerObjectProxy(InProcessWorkerMessagingP
{
}
ParentFrameTaskRunners* InProcessWorkerObjectProxy::getParentFrameTaskRunners()
{
DCHECK(m_messagingProxy);
return m_messagingProxy->getParentFrameTaskRunners();
}
ExecutionContext* InProcessWorkerObjectProxy::getExecutionContext()
{
DCHECK(m_messagingProxy);
......
......@@ -44,6 +44,7 @@ class ConsoleMessage;
class ExecutionContext;
class ExecutionContextTask;
class InProcessWorkerMessagingProxy;
class ParentFrameTaskRunners;
class WorkerOrWorkletGlobalScope;
// A proxy to talk to the worker object. This object is created on the
......@@ -79,6 +80,9 @@ protected:
virtual ExecutionContext* getExecutionContext();
private:
// Returns the parent frame's task runners.
ParentFrameTaskRunners* getParentFrameTaskRunners();
// This object always outlives this proxy.
InProcessWorkerMessagingProxy* m_messagingProxy;
};
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/workers/ParentFrameTaskRunners.h"
#include "core/dom/Document.h"
#include "core/dom/TaskRunnerHelper.h"
#include "wtf/Assertions.h"
namespace blink {
ParentFrameTaskRunners::~ParentFrameTaskRunners()
{
}
WebTaskRunner* ParentFrameTaskRunners::getUnthrottledTaskRunner()
{
return m_unthrottledTaskRunner.get();
}
WebTaskRunner* ParentFrameTaskRunners::getTimerTaskRunner()
{
return m_timerTaskRunner.get();
}
WebTaskRunner* ParentFrameTaskRunners::getLoadingTaskRunner()
{
return m_loadingTaskRunner.get();
}
ParentFrameTaskRunners::ParentFrameTaskRunners(Document* document)
: m_unthrottledTaskRunner(TaskRunnerHelper::getUnthrottledTaskRunner(document)->clone())
, m_timerTaskRunner(TaskRunnerHelper::getTimerTaskRunner(document)->clone())
, m_loadingTaskRunner(TaskRunnerHelper::getLoadingTaskRunner(document)->clone())
{
DCHECK(document->isContextThread());
}
} // namespace blink
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ParentFrameTaskRunners_h
#define ParentFrameTaskRunners_h
#include "core/CoreExport.h"
#include "wtf/Allocator.h"
#include "wtf/Noncopyable.h"
#include "wtf/PtrUtil.h"
#include <memory>
namespace blink {
class Document;
class WebTaskRunner;
// Represents a set of task runners of the parent (or associated) document's
// frame. This could be accessed from worker thread(s) and must be initialized
// on the parent context thread (i.e. MainThread) on construction time, rather
// than being done lazily.
class CORE_EXPORT ParentFrameTaskRunners final {
WTF_MAKE_NONCOPYABLE(ParentFrameTaskRunners);
USING_FAST_MALLOC(ParentFrameTaskRunners);
public:
static std::unique_ptr<ParentFrameTaskRunners> create(Document* document)
{
return wrapUnique(new ParentFrameTaskRunners(document));
}
~ParentFrameTaskRunners();
WebTaskRunner* getUnthrottledTaskRunner();
WebTaskRunner* getTimerTaskRunner();
WebTaskRunner* getLoadingTaskRunner();
private:
ParentFrameTaskRunners(Document*);
std::unique_ptr<WebTaskRunner> m_unthrottledTaskRunner;
std::unique_ptr<WebTaskRunner> m_timerTaskRunner;
std::unique_ptr<WebTaskRunner> m_loadingTaskRunner;
};
} // namespace blink
#endif // ParentFrameTaskRunners_h
......@@ -39,6 +39,7 @@
#include "core/inspector/ConsoleMessage.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/loader/FrameLoadRequest.h"
#include "core/workers/ParentFrameTaskRunners.h"
#include "core/workers/WorkerClients.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerInspectorProxy.h"
......@@ -255,6 +256,8 @@ void WebEmbeddedWorkerImpl::postMessageToPageInspector(const String& message)
void WebEmbeddedWorkerImpl::postTaskToLoader(std::unique_ptr<ExecutionContextTask> task)
{
// TODO(hiroshige,yuryu): Make this not use ExecutionContextTask and
// consider using m_mainThreadTaskRunners->getLoadingTaskRunner() instead.
m_mainFrame->frame()->document()->postTask(BLINK_FROM_HERE, std::move(task));
}
......@@ -436,6 +439,12 @@ void WebEmbeddedWorkerImpl::startWorkerThread()
m_mainScriptLoader.clear();
// We have a dummy document here for loading but it doesn't really represent
// the document/frame of associated document(s) for this worker. Here we
// populate the task runners with null document not to confuse the frame
// scheduler (which will end up using the thread's default task runner).
m_mainThreadTaskRunners = ParentFrameTaskRunners::create(nullptr);
m_workerGlobalScopeProxy = ServiceWorkerGlobalScopeProxy::create(*this, *document, *m_workerContextClient);
m_loaderProxy = WorkerLoaderProxy::create(this);
m_workerThread = ServiceWorkerThread::create(m_loaderProxy, *m_workerGlobalScopeProxy);
......
......@@ -42,6 +42,7 @@
namespace blink {
class ParentFrameTaskRunners;
class ServiceWorkerGlobalScopeProxy;
class WebLocalFrameImpl;
class WebServiceWorkerNetworkProvider;
......@@ -109,6 +110,8 @@ private:
// Kept around only while main script loading is ongoing.
RefPtr<WorkerScriptLoader> m_mainScriptLoader;
std::unique_ptr<ParentFrameTaskRunners> m_mainThreadTaskRunners;
std::unique_ptr<WorkerThread> m_workerThread;
RefPtr<WorkerLoaderProxy> m_loaderProxy;
Persistent<ServiceWorkerGlobalScopeProxy> m_workerGlobalScopeProxy;
......
......@@ -39,6 +39,7 @@
#include "core/loader/FrameLoadRequest.h"
#include "core/loader/FrameLoader.h"
#include "core/page/Page.h"
#include "core/workers/ParentFrameTaskRunners.h"
#include "core/workers/SharedWorkerGlobalScope.h"
#include "core/workers/SharedWorkerThread.h"
#include "core/workers/WorkerClients.h"
......@@ -271,6 +272,8 @@ void WebSharedWorkerImpl::workerThreadTerminatedOnMainThread()
void WebSharedWorkerImpl::postTaskToLoader(std::unique_ptr<ExecutionContextTask> task)
{
// TODO(hiroshige,yuryu): Make this not use ExecutionContextTask and
// consider using m_mainThreadTaskRunners->getLoadingTaskRunner() instead.
m_mainFrame->frame()->document()->postTask(BLINK_FROM_HERE, std::move(task));
}
......@@ -351,6 +354,13 @@ void WebSharedWorkerImpl::onScriptLoaderFinished()
m_mainScriptLoader->responseAddressSpace(),
m_mainScriptLoader->originTrialTokens(),
std::move(workerSettings));
// We have a dummy document here for loading but it doesn't really represent
// the document/frame of associated document(s) for this worker. Here we
// populate the task runners with null document not to confuse the frame
// scheduler (which will end up using the thread's default task runner).
m_mainThreadTaskRunners = ParentFrameTaskRunners::create(nullptr);
m_loaderProxy = WorkerLoaderProxy::create(this);
m_workerThread = SharedWorkerThread::create(m_name, m_loaderProxy, *this);
InspectorInstrumentation::scriptImported(m_loadingDocument.get(), m_mainScriptLoader->identifier(), m_mainScriptLoader->script());
......
......@@ -48,6 +48,7 @@
namespace blink {
class ConsoleMessage;
class ParentFrameTaskRunners;
class WebApplicationCacheHost;
class WebApplicationCacheHostClient;
class WebLocalFrameImpl;
......@@ -144,6 +145,8 @@ private:
Persistent<WorkerInspectorProxy> m_workerInspectorProxy;
std::unique_ptr<ParentFrameTaskRunners> m_mainThreadTaskRunners;
std::unique_ptr<WorkerThread> m_workerThread;
WebSharedWorkerClient* m_client;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment