summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.cpp174
1 files changed, 89 insertions, 85 deletions
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.cpp b/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.cpp
index b7ad2fd73ae..538f4ac2ed3 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.cpp
@@ -37,34 +37,55 @@
#include "platform/PlatformThreadData.h"
#include "platform/SharedTimer.h"
#include "platform/ThreadTimers.h"
+#include "platform/heap/ThreadState.h"
#include "wtf/CurrentTime.h"
namespace WebCore {
-class WorkerRunLoop::Task {
- WTF_MAKE_NONCOPYABLE(Task); WTF_MAKE_FAST_ALLOCATED;
+class WorkerRunLoopTask : public blink::WebThread::Task {
+ WTF_MAKE_NONCOPYABLE(WorkerRunLoopTask); WTF_MAKE_FAST_ALLOCATED;
public:
- static PassOwnPtr<Task> create(PassOwnPtr<ExecutionContextTask> task, const String& mode)
+ static PassOwnPtr<WorkerRunLoopTask> create(const WorkerRunLoop& runLoop, PassOwnPtr<ExecutionContextTask> task)
{
- return adoptPtr(new Task(task, mode));
+ return adoptPtr(new WorkerRunLoopTask(runLoop, task));
}
- const String& mode() const { return m_mode; }
- void performTask(const WorkerRunLoop& runLoop, ExecutionContext* context)
+
+ virtual ~WorkerRunLoopTask() { }
+
+ virtual void run() OVERRIDE
{
- WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
- if ((!workerGlobalScope->isClosing() && !runLoop.terminated()) || m_task->isCleanupTask())
- m_task->performTask(context);
+ WorkerGlobalScope* workerGlobalScope = m_runLoop.context();
+ if ((!workerGlobalScope->isClosing() && !m_runLoop.terminated()) || m_task->isCleanupTask())
+ m_task->performTask(workerGlobalScope);
}
private:
- Task(PassOwnPtr<ExecutionContextTask> task, const String& mode)
- : m_task(task)
- , m_mode(mode.isolatedCopy())
+ WorkerRunLoopTask(const WorkerRunLoop& runLoop, PassOwnPtr<ExecutionContextTask> task)
+ : m_runLoop(runLoop)
+ , m_task(task)
{
}
+ const WorkerRunLoop& m_runLoop;
OwnPtr<ExecutionContextTask> m_task;
- String m_mode;
+};
+
+class TickleDebuggerQueueTask FINAL : public ExecutionContextTask {
+public:
+ static PassOwnPtr<TickleDebuggerQueueTask> create(WorkerRunLoop* loop)
+ {
+ return adoptPtr(new TickleDebuggerQueueTask(loop));
+ }
+ virtual void performTask(ExecutionContext* context) OVERRIDE
+ {
+ ASSERT(context->isWorkerGlobalScope());
+ m_loop->runDebuggerTask(WorkerRunLoop::DontWaitForMessage);
+ }
+
+private:
+ explicit TickleDebuggerQueueTask(WorkerRunLoop* loop) : m_loop(loop) { }
+
+ WorkerRunLoop* m_loop;
};
class WorkerSharedTimer : public SharedTimer {
@@ -89,33 +110,10 @@ private:
double m_nextFireTime;
};
-class ModePredicate {
-public:
- ModePredicate(const String& mode)
- : m_mode(mode)
- , m_defaultMode(mode == WorkerRunLoop::defaultMode())
- {
- }
-
- bool isDefaultMode() const
- {
- return m_defaultMode;
- }
-
- bool operator()(WorkerRunLoop::Task* task) const
- {
- return m_defaultMode || m_mode == task->mode();
- }
-
-private:
- String m_mode;
- bool m_defaultMode;
-};
-
WorkerRunLoop::WorkerRunLoop()
: m_sharedTimer(adoptPtr(new WorkerSharedTimer))
+ , m_context(0)
, m_nestedCount(0)
- , m_uniqueId(0)
{
}
@@ -124,11 +122,6 @@ WorkerRunLoop::~WorkerRunLoop()
ASSERT(!m_nestedCount);
}
-String WorkerRunLoop::defaultMode()
-{
- return String();
-}
-
class RunLoopSetup {
WTF_MAKE_NONCOPYABLE(RunLoopSetup);
public:
@@ -154,44 +147,52 @@ private:
WorkerGlobalScope* m_context;
};
-void WorkerRunLoop::run(WorkerGlobalScope* context)
+void WorkerRunLoop::setWorkerGlobalScope(WorkerGlobalScope* context)
{
- RunLoopSetup setup(*this, context);
- ModePredicate modePredicate(defaultMode());
+ ASSERT(!m_context);
+ ASSERT(context);
+ m_context = context;
+}
+
+void WorkerRunLoop::run()
+{
+ ASSERT(m_context);
+ RunLoopSetup setup(*this, m_context);
MessageQueueWaitResult result;
do {
- result = runInMode(context, modePredicate, WaitForMessage);
+ ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
+ result = run(m_messageQueue, WaitForMessage);
} while (result != MessageQueueTerminated);
- runCleanupTasks(context);
+ runCleanupTasks();
}
-MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, const String& mode, WaitMode waitMode)
+MessageQueueWaitResult WorkerRunLoop::runDebuggerTask(WaitMode waitMode)
{
- RunLoopSetup setup(*this, context);
- ModePredicate modePredicate(mode);
- MessageQueueWaitResult result = runInMode(context, modePredicate, waitMode);
- return result;
+ ASSERT(m_context);
+ RunLoopSetup setup(*this, m_context);
+ return run(m_debuggerMessageQueue, waitMode);
}
-MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, const ModePredicate& predicate, WaitMode waitMode)
+MessageQueueWaitResult WorkerRunLoop::run(MessageQueue<blink::WebThread::Task>& queue, WaitMode waitMode)
{
- ASSERT(context);
- ASSERT(context->thread());
- ASSERT(context->thread()->isCurrentThread());
+ ASSERT(m_context);
+ ASSERT(m_context->thread());
+ ASSERT(m_context->thread()->isCurrentThread());
+ bool isDebuggerQueue = (&queue == &m_debuggerMessageQueue);
bool nextTimeoutEventIsIdleWatchdog;
MessageQueueWaitResult result;
- OwnPtr<WorkerRunLoop::Task> task;
+ OwnPtr<blink::WebThread::Task> task;
do {
double absoluteTime = 0.0;
nextTimeoutEventIsIdleWatchdog = false;
if (waitMode == WaitForMessage) {
- absoluteTime = (predicate.isDefaultMode() && m_sharedTimer->isActive()) ? m_sharedTimer->fireTime() : MessageQueue<Task>::infiniteTime();
+ absoluteTime = !isDebuggerQueue && m_sharedTimer->isActive() ? m_sharedTimer->fireTime() : MessageQueue<blink::WebThread::Task>::infiniteTime();
// Do a script engine idle notification if the next event is distant enough.
const double kMinIdleTimespan = 0.3; // seconds
- if (m_messageQueue.isEmpty() && absoluteTime > currentTime() + kMinIdleTimespan) {
- bool hasMoreWork = !context->idleNotification();
+ if (queue.isEmpty() && absoluteTime > currentTime() + kMinIdleTimespan) {
+ bool hasMoreWork = !m_context->idleNotification();
if (hasMoreWork) {
// Schedule a watchdog, so if there are no events within a particular time interval
// idle notifications won't stop firing.
@@ -204,7 +205,11 @@ MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, cons
}
}
}
- task = m_messageQueue.waitForMessageFilteredWithTimeout(result, predicate, absoluteTime);
+
+ {
+ ThreadState::SafePointScope safePointScope(ThreadState::NoHeapPointersOnStack);
+ task = queue.waitForMessageWithTimeout(result, absoluteTime);
+ }
} while (result == MessageQueueTimeout && nextTimeoutEventIsIdleWatchdog);
// If the context is closing, don't execute any further JavaScript tasks (per section 4.1.1 of the Web Workers spec).
@@ -215,13 +220,14 @@ MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, cons
break;
case MessageQueueMessageReceived:
- InspectorInstrumentation::willProcessTask(context);
- task->performTask(*this, context);
- InspectorInstrumentation::didProcessTask(context);
+ InspectorInstrumentation::willProcessTask(m_context);
+ task->run();
+ InspectorInstrumentation::didProcessTask(m_context);
break;
case MessageQueueTimeout:
- if (!context->isClosing())
+ ASSERT(!isDebuggerQueue || waitMode != WaitForMessage);
+ if (!m_context->isClosing())
m_sharedTimer->fire();
break;
}
@@ -229,49 +235,47 @@ MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, cons
return result;
}
-void WorkerRunLoop::runCleanupTasks(WorkerGlobalScope* context)
+void WorkerRunLoop::runCleanupTasks()
{
- ASSERT(context);
- ASSERT(context->thread());
- ASSERT(context->thread()->isCurrentThread());
+ ASSERT(m_context);
+ ASSERT(m_context->thread());
+ ASSERT(m_context->thread()->isCurrentThread());
ASSERT(m_messageQueue.killed());
+ ASSERT(m_debuggerMessageQueue.killed());
while (true) {
- OwnPtr<WorkerRunLoop::Task> task = m_messageQueue.tryGetMessageIgnoringKilled();
+ OwnPtr<blink::WebThread::Task> task = m_debuggerMessageQueue.tryGetMessageIgnoringKilled();
+ if (!task)
+ task = m_messageQueue.tryGetMessageIgnoringKilled();
if (!task)
return;
- task->performTask(*this, context);
+ task->run();
}
}
void WorkerRunLoop::terminate()
{
m_messageQueue.kill();
+ m_debuggerMessageQueue.kill();
}
bool WorkerRunLoop::postTask(PassOwnPtr<ExecutionContextTask> task)
{
- return postTaskForMode(task, defaultMode());
-}
-
-bool WorkerRunLoop::postTask(const Closure& closure)
-{
- return postTask(CallClosureTask::create(closure));
+ return m_messageQueue.append(WorkerRunLoopTask::create(*this, task));
}
void WorkerRunLoop::postTaskAndTerminate(PassOwnPtr<ExecutionContextTask> task)
{
- m_messageQueue.appendAndKill(Task::create(task, defaultMode().isolatedCopy()));
-}
-
-bool WorkerRunLoop::postTaskForMode(PassOwnPtr<ExecutionContextTask> task, const String& mode)
-{
- return m_messageQueue.append(Task::create(task, mode.isolatedCopy()));
+ m_debuggerMessageQueue.kill();
+ m_messageQueue.appendAndKill(WorkerRunLoopTask::create(*this, task));
}
-bool WorkerRunLoop::postTaskForMode(const Closure& closure, const String& mode)
+bool WorkerRunLoop::postDebuggerTask(PassOwnPtr<ExecutionContextTask> task)
{
- return postTaskForMode(CallClosureTask::create(closure), mode);
+ bool posted = m_debuggerMessageQueue.append(WorkerRunLoopTask::create(*this, task));
+ if (posted)
+ postTask(TickleDebuggerQueueTask::create(this));
+ return posted;
}
} // namespace WebCore