// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/accessibility/features/devtools/debug_command_queue.h"
#include "base/task/sequenced_task_runner.h"
namespace ax {
DebugCommandQueue::DebugCommandQueue()
: v8_runner_(base::SequencedTaskRunner::GetCurrentDefault()),
wake_up_(&lock_) {}
DebugCommandQueue::~DebugCommandQueue() = default;
void DebugCommandQueue::QuitPauseForDebugger() {
// Can be called from any thread.
base::AutoLock auto_lock(lock_);
wake_up_.Signal();
}
void DebugCommandQueue::QueueTaskForV8Thread(base::OnceClosure task) {
DCHECK(task);
// Can be called from any thread.
base::AutoLock auto_lock(lock_);
queue_.push(std::move(task));
v8_runner_->PostTask(FROM_HERE,
base::BindOnce(&DebugCommandQueue::RunQueue, this));
}
void DebugCommandQueue::RunQueue() {
DCHECK(v8_runner_->RunsTasksInCurrentSequence());
// Note: one of commands in the queue can cause PauseForDebuggerAndRunCommands
// to be entered. This is OK since we pull tasks off one-by-one and run them
// w/o a lock held.
base::AutoLock auto_lock(lock_);
RunQueueWithLockHeld();
}
void DebugCommandQueue::RunQueueWithLockHeld() EXCLUSIVE_LOCKS_REQUIRED(lock_) {
DCHECK(v8_runner_->RunsTasksInCurrentSequence());
while (!queue_.empty()) {
base::OnceClosure to_run = std::move(queue_.front());
queue_.pop();
{
// Relinquish lock for running callback.
base::AutoUnlock temporary_unlock(lock_);
std::move(to_run).Run();
}
}
}
} // namespace ax