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 |
index 6829460f8c69a49d9f9e34ee3f356597a6c09771..b7480fa33f2d5ea5f7db2cc645a1dee952a4b6bf 100644 |
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp |
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp |
@@ -31,6 +31,7 @@ |
#include "bindings/core/v8/Microtask.h" |
#include "bindings/core/v8/ScriptSourceCode.h" |
#include "bindings/core/v8/WorkerOrWorkletScriptController.h" |
+#include "core/dom/TaskRunnerHelper.h" |
#include "core/inspector/ConsoleMessageStorage.h" |
#include "core/inspector/InspectorTaskRunner.h" |
#include "core/inspector/WorkerInspectorController.h" |
@@ -50,6 +51,7 @@ |
#include "platform/heap/SafePoint.h" |
#include "platform/heap/ThreadState.h" |
#include "platform/weborigin/KURL.h" |
+#include "public/platform/scheduler/child/webthread_impl_for_worker_scheduler.h" |
#include "wtf/Functional.h" |
#include "wtf/Noncopyable.h" |
#include "wtf/PtrUtil.h" |
@@ -107,13 +109,25 @@ WorkerThread::~WorkerThread() { |
void WorkerThread::start(std::unique_ptr<WorkerThreadStartupData> startupData, |
ParentFrameTaskRunners* parentFrameTaskRunners) { |
DCHECK(isMainThread()); |
- |
if (m_requestedToStart) |
return; |
m_requestedToStart = true; |
m_parentFrameTaskRunners = parentFrameTaskRunners; |
- workerBackingThread().backingThread().postTask( |
+ m_threadControlTaskRunner = |
+ workerBackingThread().backingThread().platformThread().getWebTaskRunner(); |
+ |
+ // Synchronously initialize the per-global-scope scheduler to prevent someone |
+ // from posting a task to the thread before the scheduler is ready. |
+ WaitableEvent waitableEvent; |
+ m_threadControlTaskRunner->postTask( |
+ BLINK_FROM_HERE, |
+ crossThreadBind(&WorkerThread::initializeSchedulerOnWorkerThread, |
+ crossThreadUnretained(this), |
+ crossThreadUnretained(&waitableEvent))); |
kinuko
2017/04/10 06:30:06
Is it the requirement of NewTaskQueue implementati
Sami
2017/04/10 16:58:10
Yes, that's the case.
|
+ waitableEvent.wait(); |
+ |
+ m_threadControlTaskRunner->postTask( |
BLINK_FROM_HERE, crossThreadBind(&WorkerThread::initializeOnWorkerThread, |
crossThreadUnretained(this), |
WTF::passed(std::move(startupData)))); |
@@ -190,33 +204,10 @@ bool WorkerThread::isCurrentThread() { |
return workerBackingThread().backingThread().isCurrentThread(); |
} |
-void WorkerThread::postTask(const WebTraceLocation& location, |
- std::unique_ptr<WTF::Closure> task) { |
- DCHECK(isCurrentThread()); |
- if (isInShutdown()) |
- return; |
- workerBackingThread().backingThread().postTask( |
- location, |
- WTF::bind( |
- &WorkerThread::performTaskOnWorkerThread<WTF::SameThreadAffinity>, |
- WTF::unretained(this), WTF::passed(std::move(task)))); |
-} |
- |
-void WorkerThread::postTask(const WebTraceLocation& location, |
- std::unique_ptr<WTF::CrossThreadClosure> task) { |
- if (isInShutdown()) |
- return; |
- workerBackingThread().backingThread().postTask( |
- location, |
- crossThreadBind( |
- &WorkerThread::performTaskOnWorkerThread<WTF::CrossThreadAffinity>, |
- crossThreadUnretained(this), WTF::passed(std::move(task)))); |
-} |
- |
void WorkerThread::appendDebuggerTask( |
std::unique_ptr<CrossThreadClosure> task) { |
DCHECK(isMainThread()); |
- if (isInShutdown()) |
+ if (m_requestedToTerminate) |
return; |
m_inspectorTaskRunner->appendTask(crossThreadBind( |
&WorkerThread::performDebuggerTaskOnWorkerThread, |
@@ -226,10 +217,11 @@ void WorkerThread::appendDebuggerTask( |
if (isolate() && m_threadState != ThreadState::ReadyToShutdown) |
m_inspectorTaskRunner->interruptAndRunAllTasksDontWait(isolate()); |
} |
- workerBackingThread().backingThread().postTask( |
- BLINK_FROM_HERE, |
- crossThreadBind(&WorkerThread::performDebuggerTaskDontWaitOnWorkerThread, |
- crossThreadUnretained(this))); |
+ TaskRunnerHelper::get(TaskType::Unthrottled, this) |
+ ->postTask(BLINK_FROM_HERE, |
+ crossThreadBind( |
+ &WorkerThread::performDebuggerTaskDontWaitOnWorkerThread, |
+ crossThreadUnretained(this))); |
} |
void WorkerThread::startRunningDebuggerTasksOnPauseOnWorkerThread() { |
@@ -368,11 +360,11 @@ void WorkerThread::terminateInternal(TerminationMode mode) { |
m_workerThreadLifecycleContext->notifyContextDestroyed(); |
m_inspectorTaskRunner->kill(); |
- workerBackingThread().backingThread().postTask( |
+ m_threadControlTaskRunner->postTask( |
BLINK_FROM_HERE, |
crossThreadBind(&WorkerThread::prepareForShutdownOnWorkerThread, |
crossThreadUnretained(this))); |
- workerBackingThread().backingThread().postTask( |
+ m_threadControlTaskRunner->postTask( |
BLINK_FROM_HERE, |
crossThreadBind(&WorkerThread::performShutdownOnWorkerThread, |
crossThreadUnretained(this))); |
@@ -430,16 +422,15 @@ void WorkerThread::forciblyTerminateExecution(const MutexLocker& lock, |
m_forcibleTerminationTaskHandle.cancel(); |
} |
-bool WorkerThread::isInShutdown() { |
- // Check if we've started termination or shutdown sequence. Avoid acquiring |
- // a lock here to avoid introducing a risk of deadlock. Note that accessing |
- // |m_requestedToTerminate| on the main thread or |m_threadState| on the |
- // worker thread is safe as the flag is set only on the thread. |
- if (isMainThread() && m_requestedToTerminate) |
- return true; |
- if (isCurrentThread() && m_threadState == ThreadState::ReadyToShutdown) |
- return true; |
- return false; |
+void WorkerThread::initializeSchedulerOnWorkerThread( |
+ WaitableEvent* waitableEvent) { |
+ DCHECK(isCurrentThread()); |
+ scheduler::WebThreadImplForWorkerScheduler& workerScheduler = |
+ static_cast<scheduler::WebThreadImplForWorkerScheduler&>( |
+ workerBackingThread().backingThread().platformThread()); |
+ m_globalScopeScheduler = WTF::makeUnique<scheduler::GlobalScopeScheduler>( |
+ workerScheduler.getWorkerScheduler()); |
+ waitableEvent->signal(); |
} |
void WorkerThread::initializeOnWorkerThread( |
@@ -537,6 +528,9 @@ void WorkerThread::prepareForShutdownOnWorkerThread() { |
globalScope()->dispose(); |
m_consoleMessageStorage.clear(); |
workerBackingThread().backingThread().removeTaskObserver(this); |
+ |
+ // Cancel all queued tasks. |
+ m_globalScopeScheduler->dispose(); |
} |
void WorkerThread::performShutdownOnWorkerThread() { |
@@ -563,22 +557,6 @@ void WorkerThread::performShutdownOnWorkerThread() { |
m_shutdownEvent->signal(); |
} |
-template <WTF::FunctionThreadAffinity threadAffinity> |
-void WorkerThread::performTaskOnWorkerThread( |
- std::unique_ptr<Function<void(), threadAffinity>> task) { |
- DCHECK(isCurrentThread()); |
- if (m_threadState != ThreadState::Running) |
- return; |
- |
- { |
- DEFINE_THREAD_SAFE_STATIC_LOCAL( |
- CustomCountHistogram, scopedUsCounter, |
- new CustomCountHistogram("WorkerThread.Task.Time", 0, 10000000, 50)); |
- ScopedUsHistogramTimer timer(scopedUsCounter); |
- (*task)(); |
- } |
-} |
- |
void WorkerThread::performDebuggerTaskOnWorkerThread( |
std::unique_ptr<CrossThreadClosure> task) { |
DCHECK(isCurrentThread()); |