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

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

Issue 1728803002: Rename WorkerThread to WorkerScript Base URL: https://chromium.googlesource.com/chromium/src.git@workerscript-controller
Patch Set: Created 4 years, 10 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/WorkerThread.cpp
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
deleted file mode 100644
index 7531f85f8fd3380bb9d78c4486aa3c0272634be2..0000000000000000000000000000000000000000
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "core/workers/WorkerThread.h"
-
-#include "bindings/core/v8/ScriptSourceCode.h"
-#include "bindings/core/v8/V8GCController.h"
-#include "bindings/core/v8/V8IdleTaskRunner.h"
-#include "bindings/core/v8/V8Initializer.h"
-#include "core/dom/Microtask.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "core/inspector/WorkerInspectorController.h"
-#include "core/workers/DedicatedWorkerGlobalScope.h"
-#include "core/workers/WorkerClients.h"
-#include "core/workers/WorkerReportingProxy.h"
-#include "core/workers/WorkerThreadStartupData.h"
-#include "platform/Task.h"
-#include "platform/ThreadSafeFunctional.h"
-#include "platform/WaitableEvent.h"
-#include "platform/heap/SafePoint.h"
-#include "platform/heap/ThreadState.h"
-#include "platform/weborigin/KURL.h"
-#include "public/platform/Platform.h"
-#include "public/platform/WebScheduler.h"
-#include "public/platform/WebThread.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/WeakPtr.h"
-#include "wtf/text/WTFString.h"
-#include <limits.h>
-
-namespace blink {
-
-class WorkerMicrotaskRunner : public WebThread::TaskObserver {
-public:
- explicit WorkerMicrotaskRunner(WorkerThread* workerThread)
- : m_workerThread(workerThread)
- {
- }
-
- void willProcessTask() override
- {
- // No tasks should get executed after we have closed.
- WorkerGlobalScope* globalScope = m_workerThread->workerGlobalScope();
- ASSERT_UNUSED(globalScope, !globalScope || !globalScope->isClosing());
- }
-
- void didProcessTask() override
- {
- Microtask::performCheckpoint(m_workerThread->isolate());
- if (WorkerGlobalScope* globalScope = m_workerThread->workerGlobalScope()) {
- if (WorkerOrWorkletScriptController* scriptController = globalScope->scriptController())
- scriptController->rejectedPromises()->processQueue();
- if (globalScope->isClosing()) {
- m_workerThread->workerReportingProxy().workerGlobalScopeClosed();
- m_workerThread->shutdown();
- }
- }
- }
-
-private:
- // Thread owns the microtask runner; reference remains
- // valid for the lifetime of this object.
- WorkerThread* m_workerThread;
-};
-
-static Mutex& threadSetMutex()
-{
- DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, mutex, new Mutex);
- return mutex;
-}
-
-static HashSet<WorkerThread*>& workerThreads()
-{
- DEFINE_STATIC_LOCAL(HashSet<WorkerThread*>, threads, ());
- return threads;
-}
-
-unsigned WorkerThread::workerThreadCount()
-{
- MutexLocker lock(threadSetMutex());
- return workerThreads().size();
-}
-
-void WorkerThread::performTask(PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
-{
- ASSERT(isCurrentThread());
- WorkerGlobalScope* globalScope = workerGlobalScope();
- // 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) {
- ASSERT(terminated());
- return;
- }
-
- if (isInstrumented)
- InspectorInstrumentation::willPerformExecutionContextTask(globalScope, task.get());
- task->performTask(globalScope);
- if (isInstrumented)
- InspectorInstrumentation::didPerformExecutionContextTask(globalScope);
-}
-
-WebTaskRunner::Task* WorkerThread::createWorkerThreadTask(PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
-{
- if (isInstrumented)
- isInstrumented = !task->taskNameForInstrumentation().isEmpty();
- if (isInstrumented) {
- // TODO(hiroshige): This doesn't work when called on the main thread.
- // https://crbug.com/588497
- InspectorInstrumentation::didPostExecutionContextTask(workerGlobalScope(), task.get());
- }
- return new Task(threadSafeBind(&WorkerThread::performTask, AllowCrossThreadAccess(this), task, isInstrumented));
-}
-
-class WorkerThread::DebuggerTaskQueue {
- WTF_MAKE_NONCOPYABLE(DebuggerTaskQueue);
-public:
- using Task = WebTaskRunner::Task;
- using Result = WorkerThread::TaskQueueResult;
-
- DebuggerTaskQueue() { }
-
- // Returns true if the queue is still alive, false if the queue has been
- // killed.
- bool append(PassOwnPtr<Task> task)
- {
- MutexLocker lock(m_mutex);
- m_queue.append(task);
- m_condition.signal();
- return !m_killed;
- }
-
- PassOwnPtr<Task> waitWithTimeout(Result& result, double absoluteTime)
- {
- MutexLocker lock(m_mutex);
- bool timedOut = false;
-
- while (!m_killed && !timedOut && m_queue.isEmpty())
- timedOut = !m_condition.timedWait(m_mutex, absoluteTime);
-
- ASSERT(!timedOut || absoluteTime != infiniteTime());
-
- if (m_killed) {
- result = Terminated;
- return nullptr;
- }
-
- if (timedOut) {
- result = Timeout;
- return nullptr;
- }
-
- ASSERT_WITH_SECURITY_IMPLICATION(!m_queue.isEmpty());
- result = TaskReceived;
-
- return m_queue.takeFirst().release();
- }
-
- void kill()
- {
- MutexLocker lock(m_mutex);
- m_killed = true;
- m_condition.broadcast();
- }
-
- static double infiniteTime() { return std::numeric_limits<double>::max(); }
-
-private:
- Mutex m_mutex;
- ThreadCondition m_condition;
- Deque<OwnPtr<Task>> m_queue;
- bool m_killed = false;
-};
-
-WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, WorkerReportingProxy& workerReportingProxy)
- : m_started(false)
- , m_terminated(false)
- , m_shutdown(false)
- , m_debuggerTaskQueue(adoptPtr(new DebuggerTaskQueue))
- , m_workerLoaderProxy(workerLoaderProxy)
- , m_workerReportingProxy(workerReportingProxy)
- , m_webScheduler(nullptr)
- , m_isolate(nullptr)
- , m_shutdownEvent(adoptPtr(new WaitableEvent(
- WaitableEvent::ResetPolicy::Manual,
- WaitableEvent::InitialState::NonSignaled)))
- , m_terminationEvent(adoptPtr(new WaitableEvent(
- WaitableEvent::ResetPolicy::Manual,
- WaitableEvent::InitialState::NonSignaled)))
-{
- MutexLocker lock(threadSetMutex());
- workerThreads().add(this);
-}
-
-WorkerThread::~WorkerThread()
-{
- MutexLocker lock(threadSetMutex());
- ASSERT(workerThreads().contains(this));
- workerThreads().remove(this);
-}
-
-void WorkerThread::start(PassOwnPtr<WorkerThreadStartupData> startupData)
-{
- ASSERT(isMainThread());
-
- if (m_started)
- return;
-
- m_started = true;
- backingThread().postTask(BLINK_FROM_HERE, new Task(threadSafeBind(&WorkerThread::initialize, AllowCrossThreadAccess(this), startupData)));
-}
-
-void WorkerThread::interruptAndDispatchInspectorCommands()
-{
- MutexLocker locker(m_workerInspectorControllerMutex);
- if (m_workerInspectorController)
- m_workerInspectorController->interruptAndDispatchInspectorCommands();
-}
-
-PlatformThreadId WorkerThread::platformThreadId()
-{
- if (!m_started)
- return 0;
- return backingThread().platformThread().threadId();
-}
-
-void WorkerThread::initialize(PassOwnPtr<WorkerThreadStartupData> startupData)
-{
- KURL scriptURL = startupData->m_scriptURL;
- String sourceCode = startupData->m_sourceCode;
- WorkerThreadStartMode startMode = startupData->m_startMode;
- OwnPtr<Vector<char>> cachedMetaData = startupData->m_cachedMetaData.release();
- V8CacheOptions v8CacheOptions = startupData->m_v8CacheOptions;
- m_webScheduler = backingThread().platformThread().scheduler();
-
- {
- MutexLocker lock(m_threadStateMutex);
-
- // The worker was terminated before the thread had a chance to run.
- if (m_terminated) {
- // 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_terminationEvent->signal();
- return;
- }
-
- m_microtaskRunner = adoptPtr(new WorkerMicrotaskRunner(this));
- initializeBackingThread();
- backingThread().addTaskObserver(m_microtaskRunner.get());
-
- m_isolate = initializeIsolate();
- // Optimize for memory usage instead of latency for the worker isolate.
- m_isolate->IsolateInBackgroundNotification();
- m_workerGlobalScope = createWorkerGlobalScope(startupData);
- m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.get() ? cachedMetaData->size() : 0);
-
- didStartWorkerThread();
-
- // 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();
- }
- m_workerGlobalScope->workerInspectorController()->workerContextInitialized(startMode == PauseWorkerGlobalScopeOnStart);
-
- if (m_workerGlobalScope->scriptController()->isContextInitialized()) {
- m_workerReportingProxy.didInitializeWorkerContext();
- }
-
- OwnPtrWillBeRawPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScriptCachedMetadataHandler(scriptURL, cachedMetaData.get()));
- bool success = m_workerGlobalScope->scriptController()->evaluate(ScriptSourceCode(sourceCode, scriptURL), nullptr, handler.get(), v8CacheOptions);
- m_workerGlobalScope->didEvaluateWorkerScript();
- m_workerReportingProxy.didEvaluateWorkerScript(success);
-
- postInitialize();
-}
-
-void WorkerThread::shutdown()
-{
- ASSERT(isCurrentThread());
- {
- MutexLocker lock(m_threadStateMutex);
- if (m_shutdown)
- return;
- m_shutdown = true;
- }
-
- // This should be called before we start the shutdown procedure.
- workerReportingProxy().willDestroyWorkerGlobalScope();
-
- workerGlobalScope()->dispose();
-
- // This should be called after the WorkerGlobalScope's disposed (which may
- // trigger some last-minutes cleanups) and before the thread actually stops.
- willStopWorkerThread();
-
- backingThread().removeTaskObserver(m_microtaskRunner.get());
- postTask(BLINK_FROM_HERE, createSameThreadTask(&WorkerThread::performShutdownTask, this));
-}
-
-void WorkerThread::performShutdownTask()
-{
- // The below assignment will destroy the context, which will in turn notify messaging proxy.
- // We cannot let any objects survive past thread exit, 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.
-#if !ENABLE(OILPAN)
- ASSERT(m_workerGlobalScope->hasOneRef());
-#endif
- m_workerGlobalScope->notifyContextDestroyed();
- m_workerGlobalScope = nullptr;
-
- willDestroyIsolate();
- shutdownBackingThread();
- destroyIsolate();
- m_isolate = nullptr;
-
- m_microtaskRunner = nullptr;
-
- // Notify the proxy that the WorkerGlobalScope has been disposed of.
- // This can free this thread object, hence it must not be touched afterwards.
- workerReportingProxy().workerThreadTerminated();
-
- m_terminationEvent->signal();
-}
-
-void WorkerThread::terminate()
-{
- // Prevent the deadlock between GC and an attempt to terminate a thread.
- SafePointScope safePointScope(BlinkGC::HeapPointersOnStack);
- terminateInternal();
-}
-
-void WorkerThread::terminateAndWait()
-{
- terminate();
- m_terminationEvent->wait();
-}
-
-WorkerGlobalScope* WorkerThread::workerGlobalScope()
-{
- ASSERT(isCurrentThread());
- return m_workerGlobalScope.get();
-}
-
-bool WorkerThread::terminated()
-{
- MutexLocker lock(m_threadStateMutex);
- return m_terminated;
-}
-
-void WorkerThread::terminateInternal()
-{
- ASSERT(isMainThread());
-
- // Protect against this method, initialize() or termination via the global scope racing each other.
- MutexLocker lock(m_threadStateMutex);
-
- // If terminateInternal has already been called, just return.
- if (m_terminated)
- return;
- m_terminated = true;
-
- // Signal the thread to notify that the thread's stopping.
- if (m_shutdownEvent)
- m_shutdownEvent->signal();
-
- // If the thread has already initiated shut down, just return.
- if (m_shutdown)
- return;
-
- // If the worker thread was never initialized, don't start another
- // shutdown, but still wait for the thread to signal when termination has
- // completed.
- if (!m_workerGlobalScope)
- return;
-
- // Ensure that tasks are being handled by thread event loop. If script execution weren't forbidden, a while(1) loop in JS could keep the thread alive forever.
- m_workerGlobalScope->scriptController()->willScheduleExecutionTermination();
- terminateV8Execution();
-
- InspectorInstrumentation::didKillAllExecutionContextTasks(m_workerGlobalScope.get());
- m_debuggerTaskQueue->kill();
- backingThread().postTask(BLINK_FROM_HERE, new Task(threadSafeBind(&WorkerThread::shutdown, AllowCrossThreadAccess(this))));
-}
-
-void WorkerThread::didStartWorkerThread()
-{
- ASSERT(isCurrentThread());
- Platform::current()->didStartWorkerThread();
-}
-
-void WorkerThread::willStopWorkerThread()
-{
- ASSERT(isCurrentThread());
- Platform::current()->willStopWorkerThread();
-}
-
-void WorkerThread::terminateAndWaitForAllWorkers()
-{
- // Keep this lock to prevent WorkerThread instances from being destroyed.
- MutexLocker lock(threadSetMutex());
- HashSet<WorkerThread*> threads = workerThreads();
- for (WorkerThread* thread : threads)
- thread->terminateInternal();
-
- for (WorkerThread* thread : threads)
- thread->m_terminationEvent->wait();
-}
-
-bool WorkerThread::isCurrentThread()
-{
- return m_started && backingThread().isCurrentThread();
-}
-
-void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<ExecutionContextTask> task)
-{
- backingThread().postTask(location, createWorkerThreadTask(task, true));
-}
-
-void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr<ExecutionContextTask> task, long long delayMs)
-{
- backingThread().postDelayedTask(location, createWorkerThreadTask(task, true), delayMs);
-}
-
-void WorkerThread::initializeBackingThread()
-{
- ASSERT(isCurrentThread());
- backingThread().initialize();
-}
-
-void WorkerThread::shutdownBackingThread()
-{
- ASSERT(isCurrentThread());
- backingThread().shutdown();
-}
-
-v8::Isolate* WorkerThread::initializeIsolate()
-{
- ASSERT(isCurrentThread());
- ASSERT(!m_isolate);
- v8::Isolate* isolate = V8PerIsolateData::initialize();
- V8Initializer::initializeWorker(isolate);
-
- OwnPtr<V8IsolateInterruptor> interruptor = adoptPtr(new V8IsolateInterruptor(isolate));
- ThreadState::current()->addInterruptor(interruptor.release());
- ThreadState::current()->registerTraceDOMWrappers(isolate, V8GCController::traceDOMWrappers);
- if (RuntimeEnabledFeatures::v8IdleTasksEnabled())
- V8PerIsolateData::enableIdleTasks(isolate, adoptPtr(new V8IdleTaskRunner(m_webScheduler)));
- return isolate;
-}
-
-void WorkerThread::willDestroyIsolate()
-{
- ASSERT(isCurrentThread());
- ASSERT(m_isolate);
- V8PerIsolateData::willBeDestroyed(m_isolate);
-}
-
-void WorkerThread::destroyIsolate()
-{
- ASSERT(isCurrentThread());
- V8PerIsolateData::destroy(m_isolate);
-}
-
-void WorkerThread::terminateV8Execution()
-{
- ASSERT(isMainThread());
- m_isolate->TerminateExecution();
-}
-
-void WorkerThread::appendDebuggerTask(PassOwnPtr<WebTaskRunner::Task> task)
-{
- {
- MutexLocker lock(m_threadStateMutex);
- if (m_shutdown)
- return;
- }
- m_debuggerTaskQueue->append(task);
-}
-
-WorkerThread::TaskQueueResult WorkerThread::runDebuggerTask(WaitMode waitMode)
-{
- ASSERT(isCurrentThread());
- TaskQueueResult result;
- double absoluteTime = DebuggerTaskQueue::infiniteTime();
- OwnPtr<WebTaskRunner::Task> task;
- {
- if (waitMode == DontWaitForTask)
- absoluteTime = 0.0;
- SafePointScope safePointScope(BlinkGC::HeapPointersOnStack);
- task = m_debuggerTaskQueue->waitWithTimeout(result, absoluteTime);
- }
-
- if (result == TaskReceived) {
- InspectorInstrumentation::willProcessTask(workerGlobalScope());
- task->run();
- InspectorInstrumentation::didProcessTask(workerGlobalScope());
- }
-
- return result;
-}
-
-void WorkerThread::willRunDebuggerTasks()
-{
- InspectorInstrumentation::willEnterNestedRunLoop(m_workerGlobalScope.get());
-}
-
-void WorkerThread::didRunDebuggerTasks()
-{
- InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get());
-}
-
-void WorkerThread::setWorkerInspectorController(WorkerInspectorController* workerInspectorController)
-{
- MutexLocker locker(m_workerInspectorControllerMutex);
- m_workerInspectorController = workerInspectorController;
-}
-
-} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698