diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/workers/WorkerRunLoop.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/workers/WorkerRunLoop.cpp')
-rw-r--r-- | Source/WebCore/workers/WorkerRunLoop.cpp | 104 |
1 files changed, 63 insertions, 41 deletions
diff --git a/Source/WebCore/workers/WorkerRunLoop.cpp b/Source/WebCore/workers/WorkerRunLoop.cpp index 9a9f556f7..b32b2598c 100644 --- a/Source/WebCore/workers/WorkerRunLoop.cpp +++ b/Source/WebCore/workers/WorkerRunLoop.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2016 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 @@ -39,28 +40,26 @@ #include "WorkerThread.h" #include <wtf/CurrentTime.h> +#if PLATFORM(GTK) +#include <glib.h> +#endif + namespace WebCore { -class WorkerSharedTimer : public SharedTimer { +class WorkerSharedTimer final : public SharedTimer { public: - WorkerSharedTimer() - : m_sharedTimerFunction(0) - , m_nextFireTime(0) - { - } - // SharedTimer interface. - virtual void setFiredFunction(void (*function)()) { m_sharedTimerFunction = function; } - virtual void setFireInterval(double interval) { m_nextFireTime = interval + currentTime(); } - virtual void stop() { m_nextFireTime = 0; } + void setFiredFunction(std::function<void()>&& function) override { m_sharedTimerFunction = WTFMove(function); } + void setFireInterval(Seconds interval) override { m_nextFireTime = interval + WallTime::now(); } + void stop() override { m_nextFireTime = WallTime(); } bool isActive() { return m_sharedTimerFunction && m_nextFireTime; } - double fireTime() { return m_nextFireTime; } + WallTime fireTime() { return m_nextFireTime; } void fire() { m_sharedTimerFunction(); } private: - void (*m_sharedTimerFunction)(); - double m_nextFireTime; + std::function<void()> m_sharedTimerFunction; + WallTime m_nextFireTime; }; class ModePredicate { @@ -87,7 +86,7 @@ private: }; WorkerRunLoop::WorkerRunLoop() - : m_sharedTimer(adoptPtr(new WorkerSharedTimer)) + : m_sharedTimer(std::make_unique<WorkerSharedTimer>()) , m_nestedCount(0) , m_uniqueId(0) { @@ -103,6 +102,11 @@ String WorkerRunLoop::defaultMode() return String(); } +String WorkerRunLoop::debuggerMode() +{ + return ASCIILiteral("debugger"); +} + class RunLoopSetup { WTF_MAKE_NONCOPYABLE(RunLoopSetup); public: @@ -118,7 +122,7 @@ public: { m_runLoop.m_nestedCount--; if (!m_runLoop.m_nestedCount) - threadGlobalData().threadTimers().setSharedTimer(0); + threadGlobalData().threadTimers().setSharedTimer(nullptr); } private: WorkerRunLoop& m_runLoop; @@ -146,14 +150,35 @@ MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, cons MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, const ModePredicate& predicate, WaitMode waitMode) { ASSERT(context); - ASSERT(context->thread()); - ASSERT(context->thread()->threadID() == currentThread()); - - double absoluteTime = 0.0; - if (waitMode == WaitForMessage) - absoluteTime = (predicate.isDefaultMode() && m_sharedTimer->isActive()) ? m_sharedTimer->fireTime() : MessageQueue<Task>::infiniteTime(); + ASSERT(context->thread().threadID() == currentThread()); + +#if PLATFORM(GTK) + GMainContext* mainContext = g_main_context_get_thread_default(); + if (g_main_context_pending(mainContext)) + g_main_context_iteration(mainContext, FALSE); +#endif + + WallTime deadline = WallTime::infinity(); + +#if USE(CF) + CFAbsoluteTime nextCFRunLoopTimerFireDate = CFRunLoopGetNextTimerFireDate(CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + double timeUntilNextCFRunLoopTimerInSeconds = nextCFRunLoopTimerFireDate - CFAbsoluteTimeGetCurrent(); + deadline = WallTime::now() + std::max(0_s, Seconds(timeUntilNextCFRunLoopTimerInSeconds)); +#endif + + WallTime absoluteTime; + if (waitMode == WaitForMessage) { + if (predicate.isDefaultMode() && m_sharedTimer->isActive()) + absoluteTime = std::min(deadline, m_sharedTimer->fireTime()); + else + absoluteTime = deadline; + } MessageQueueWaitResult result; + if (WorkerScriptController* script = context->script()) + script->releaseHeapAccess(); auto task = m_messageQueue.waitForMessageFilteredWithTimeout(result, predicate, absoluteTime); + if (WorkerScriptController* script = context->script()) + script->acquireHeapAccess(); // If the context is closing, don't execute any further JavaScript tasks (per section 4.1.1 of the Web Workers spec). However, there may be implementation cleanup tasks in the queue, so keep running through it. @@ -166,8 +191,12 @@ MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, cons break; case MessageQueueTimeout: - if (!context->isClosing()) + if (!context->isClosing() && !isNested()) m_sharedTimer->fire(); +#if USE(CF) + if (nextCFRunLoopTimerFireDate <= CFAbsoluteTimeGetCurrent()) + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, /*returnAfterSourceHandled*/ false); +#endif break; } @@ -177,8 +206,7 @@ MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, cons void WorkerRunLoop::runCleanupTasks(WorkerGlobalScope* context) { ASSERT(context); - ASSERT(context->thread()); - ASSERT(context->thread()->threadID() == currentThread()); + ASSERT(context->thread().threadID() == currentThread()); ASSERT(m_messageQueue.killed()); while (true) { @@ -194,35 +222,29 @@ void WorkerRunLoop::terminate() m_messageQueue.kill(); } -void WorkerRunLoop::postTask(PassOwnPtr<ScriptExecutionContext::Task> task) -{ - postTaskForMode(task, defaultMode()); -} - -void WorkerRunLoop::postTaskAndTerminate(PassOwnPtr<ScriptExecutionContext::Task> task) +void WorkerRunLoop::postTask(ScriptExecutionContext::Task&& task) { - m_messageQueue.appendAndKill(Task::create(task, defaultMode().isolatedCopy())); + postTaskForMode(WTFMove(task), defaultMode()); } -void WorkerRunLoop::postTaskForMode(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode) +void WorkerRunLoop::postTaskAndTerminate(ScriptExecutionContext::Task&& task) { - m_messageQueue.append(Task::create(task, mode.isolatedCopy())); + m_messageQueue.appendAndKill(std::make_unique<Task>(WTFMove(task), defaultMode())); } -std::unique_ptr<WorkerRunLoop::Task> WorkerRunLoop::Task::create(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode) +void WorkerRunLoop::postTaskForMode(ScriptExecutionContext::Task&& task, const String& mode) { - return std::unique_ptr<Task>(new Task(task, mode)); + m_messageQueue.append(std::make_unique<Task>(WTFMove(task), mode)); } -void WorkerRunLoop::Task::performTask(const WorkerRunLoop& runLoop, ScriptExecutionContext* context) +void WorkerRunLoop::Task::performTask(const WorkerRunLoop& runLoop, WorkerGlobalScope* context) { - WorkerGlobalScope* workerGlobalScope = static_cast<WorkerGlobalScope*>(context); - if ((!workerGlobalScope->isClosing() && !runLoop.terminated()) || m_task->isCleanupTask()) - m_task->performTask(context); + if ((!context->isClosing() && !runLoop.terminated()) || m_task.isCleanupTask()) + m_task.performTask(*context); } -WorkerRunLoop::Task::Task(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode) - : m_task(task) +WorkerRunLoop::Task::Task(ScriptExecutionContext::Task&& task, const String& mode) + : m_task(WTFMove(task)) , m_mode(mode.isolatedCopy()) { } |