blob: 0f7c5ddc7dac2b41a6e78e3fa27bd2d7d48d029f [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/inspector/InspectorTaskRunner.h"
#include "wtf/Deque.h"
#include "wtf/ThreadingPrimitives.h"
#include <v8.h>
namespace blink {
InspectorTaskRunner::IgnoreInterruptsScope::IgnoreInterruptsScope(InspectorTaskRunner* taskRunner)
: m_wasIgnoring(taskRunner->m_ignoreInterrupts)
, m_taskRunner(taskRunner)
{
// There may be nested scopes e.g. when tasks are being executed on XHR breakpoint.
m_taskRunner->m_ignoreInterrupts = true;
}
InspectorTaskRunner::IgnoreInterruptsScope::~IgnoreInterruptsScope()
{
m_taskRunner->m_ignoreInterrupts = m_wasIgnoring;
}
class InspectorTaskRunner::ThreadSafeTaskQueue {
WTF_MAKE_NONCOPYABLE(ThreadSafeTaskQueue);
public:
ThreadSafeTaskQueue() { }
PassOwnPtr<Task> tryTake()
{
MutexLocker lock(m_mutex);
if (m_queue.isEmpty())
return nullptr;
return m_queue.takeFirst().release();
}
void append(PassOwnPtr<Task> task)
{
MutexLocker lock(m_mutex);
m_queue.append(task);
}
private:
Mutex m_mutex;
Deque<OwnPtr<Task>> m_queue;
};
InspectorTaskRunner::InspectorTaskRunner(v8::Isolate* isolate)
: m_isolate(isolate)
, m_taskQueue(adoptPtr(new ThreadSafeTaskQueue))
, m_ignoreInterrupts(false)
{
}
InspectorTaskRunner::~InspectorTaskRunner()
{
}
void InspectorTaskRunner::interruptAndRun(PassOwnPtr<Task> task)
{
m_taskQueue->append(task);
m_isolate->RequestInterrupt(&v8InterruptCallback, this);
}
void InspectorTaskRunner::runPendingTasks()
{
while (true) {
OwnPtr<Task> task = m_taskQueue->tryTake();
if (!task)
return;
task->run();
}
}
void InspectorTaskRunner::v8InterruptCallback(v8::Isolate*, void* data)
{
InspectorTaskRunner* runner = static_cast<InspectorTaskRunner*>(data);
if (runner->m_ignoreInterrupts)
return;
runner->runPendingTasks();
}
} // namespace blink