Index: third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp |
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp b/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..fea102409b79cd9dc1ca7d87ab338d1abeef67bf |
--- /dev/null |
+++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp |
@@ -0,0 +1,183 @@ |
+// 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/ThreadedWorkletMessagingProxy.h" |
+ |
+#include "bindings/core/v8/ScriptSourceCode.h" |
+#include "bindings/core/v8/SourceLocation.h" |
+#include "bindings/core/v8/WorkerOrWorkletScriptController.h" |
+#include "core/dom/Document.h" |
+#include "core/dom/ExecutionContextTask.h" |
+#include "core/frame/LocalFrame.h" |
+#include "core/origin_trials/OriginTrialContext.h" |
+#include "core/workers/ThreadedWorkletObjectProxy.h" |
+#include "core/workers/WorkerInspectorProxy.h" |
+#include "core/workers/WorkerLoaderProxy.h" |
+#include "core/workers/WorkerThreadStartupData.h" |
+#include "core/workers/WorkletGlobalScope.h" |
+ |
+namespace blink { |
+ |
+namespace { |
+ |
+ void processEvaluateScript(const String& source, const KURL& scriptURL, ExecutionContext* executionContext) |
+ { |
+ WorkletGlobalScope* globalScope = toWorkletGlobalScope(executionContext); |
+ globalScope->scriptController()->evaluate(ScriptSourceCode(source, scriptURL)); |
+ } |
+ |
+} // namespace |
+ |
+ThreadedWorkletMessagingProxy::ThreadedWorkletMessagingProxy(LocalFrame* frame) |
+ : m_executionContext(frame->document()) |
+ , m_workletObjectProxy(ThreadedWorkletObjectProxy::create(this)) |
+ , m_workerInspectorProxy(WorkerInspectorProxy::create()) |
+ , m_workerThreadHadPendingActivity(false) |
+ , m_askedToTerminate(false) |
+ , m_mayBeDestroyed(false) |
+{ |
+ DCHECK(isMainThread()); |
+} |
+ |
+ThreadedWorkletMessagingProxy::~ThreadedWorkletMessagingProxy() |
+{ |
+ DCHECK(isMainThread()); |
+ if (m_loaderProxy) |
+ m_loaderProxy->detachProvider(this); |
+} |
+ |
+void ThreadedWorkletMessagingProxy::initialize() |
+{ |
+ DCHECK(isMainThread()); |
+ DCHECK(!m_askedToTerminate); |
+ |
+ Document* document = toDocument(m_executionContext); |
+ SecurityOrigin* starterOrigin = document->getSecurityOrigin(); |
+ |
+ KURL scriptURL = m_executionContext->url(); |
+ std::unique_ptr<WorkerSettings> workerSettings = wrapUnique(new WorkerSettings(document->settings())); |
+ std::unique_ptr<WorkerThreadStartupData> startupData = WorkerThreadStartupData::create( |
+ scriptURL, |
+ m_executionContext->userAgent(), |
+ String() /* sourceCode */, |
+ nullptr, |
+ m_workerInspectorProxy->workerStartMode(document), |
+ nullptr, |
+ String() /* referrerPolicy */, |
+ starterOrigin, |
+ nullptr, |
+ document->addressSpace(), |
+ OriginTrialContext::getTokens(document).get(), |
+ std::move(workerSettings)); |
+ |
+ m_loaderProxy = WorkerLoaderProxy::create(this); |
+ m_workerThread = createWorkerThread(); |
+ m_workerThread->start(std::move(startupData)); |
+ m_workerInspectorProxy->workerThreadCreated(document, m_workerThread.get(), scriptURL); |
+} |
+ |
+void ThreadedWorkletMessagingProxy::evaluateScript(const ScriptSourceCode& scriptSourceCode) |
+{ |
+ DCHECK(isMainThread()); |
+ m_workerThread->postTask(BLINK_FROM_HERE, createCrossThreadTask(&processEvaluateScript, scriptSourceCode.source(), scriptSourceCode.url())); |
+} |
+ |
+void ThreadedWorkletMessagingProxy::reportConsoleMessage(MessageSource source, MessageLevel level, const String& message, std::unique_ptr<SourceLocation> location) |
+{ |
+ DCHECK(isMainThread()); |
+ if (m_askedToTerminate) |
+ return; |
+ if (m_workerInspectorProxy) |
+ m_workerInspectorProxy->addConsoleMessageFromWorker(level, message, std::move(location)); |
+} |
+ |
+void ThreadedWorkletMessagingProxy::postMessageToPageInspector(const String& message) |
+{ |
+ DCHECK(isMainThread()); |
+ if (m_workerInspectorProxy) |
+ m_workerInspectorProxy->dispatchMessageFromWorker(message); |
+} |
+ |
+void ThreadedWorkletMessagingProxy::reportPendingActivity(bool hasPendingActivity) |
+{ |
+ DCHECK(isMainThread()); |
+ m_workerThreadHadPendingActivity = hasPendingActivity; |
+} |
+ |
+void ThreadedWorkletMessagingProxy::workletObjectDestroyed() |
+{ |
+ DCHECK(isMainThread()); |
+ getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadedWorkletMessagingProxy::workerObjectDestroyedInternal, crossThreadUnretained(this))); |
+} |
+ |
+void ThreadedWorkletMessagingProxy::workerObjectDestroyedInternal() |
+{ |
+ DCHECK(isMainThread()); |
+ m_mayBeDestroyed = true; |
+ if (m_workerThread) |
+ terminateWorkletGlobalScope(); |
+ else |
+ workerThreadTerminated(); |
+} |
+ |
+void ThreadedWorkletMessagingProxy::workerThreadTerminated() |
+{ |
+ DCHECK(isMainThread()); |
+ |
+ // This method is always the last to be performed, so the proxy is not |
+ // needed for communication in either side any more. However, the Worker |
+ // object may still exist, and it assumes that the proxy exists, too. |
+ m_askedToTerminate = true; |
+ m_workerThread = nullptr; |
+ m_workerInspectorProxy->workerThreadTerminated(); |
+ if (m_mayBeDestroyed) |
+ delete this; |
+} |
+ |
+void ThreadedWorkletMessagingProxy::terminateWorkletGlobalScope() |
+{ |
+ DCHECK(isMainThread()); |
+ if (m_askedToTerminate) |
+ return; |
+ m_askedToTerminate = true; |
+ |
+ if (m_workerThread) |
+ m_workerThread->terminate(); |
+ |
+ m_workerInspectorProxy->workerThreadTerminated(); |
+} |
+ |
+void ThreadedWorkletMessagingProxy::workerThreadCreated() |
+{ |
+ DCHECK(isMainThread()); |
+ DCHECK(!m_askedToTerminate); |
+ DCHECK(m_workerThread); |
+ |
+ // Worker initialization means a pending activity. |
+ m_workerThreadHadPendingActivity = true; |
+} |
+ |
+void ThreadedWorkletMessagingProxy::postTaskToLoader(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task) |
+{ |
+ DCHECK(m_executionContext->isDocument()); |
+ m_executionContext->postTask(location, std::move(task)); |
+} |
+ |
+void ThreadedWorkletMessagingProxy::postTaskToWorkerGlobalScope(const WebTraceLocation& location, std::unique_ptr<ExecutionContextTask> task) |
+{ |
+ if (m_askedToTerminate) |
+ return; |
+ |
+ /* |
+ DCHECK(m_workerThread); |
+ m_workerThread->postTask(location, std::move(task)); |
+ */ // TODO need a thread. |
+} |
+ |
+ThreadedWorkletObjectProxy& ThreadedWorkletMessagingProxy::workerObjectProxy() |
+{ |
+ return *m_workletObjectProxy.get(); |
+} |
+ |
+} // namespace blink |