summaryrefslogtreecommitdiff
path: root/Source/WebCore/workers/WorkerRunLoop.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/workers/WorkerRunLoop.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/workers/WorkerRunLoop.cpp')
-rw-r--r--Source/WebCore/workers/WorkerRunLoop.cpp104
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())
{
}