blob: c5d195041de1b83fb5230b83c751aee7ae797804 [file] [log] [blame]
// Copyright 2019 The Chromium OS 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 "libhwsec/message_loop_idle.h"
namespace hwsec {
MessageLoopIdleEvent::MessageLoopIdleEvent(base::MessageLoop* message_loop)
: event_(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED),
observer_added_(false),
tasks_processed_(0),
was_idle_(false),
message_loop_(message_loop) {
PostTask();
}
void MessageLoopIdleEvent::WillProcessTask(
const base::PendingTask& pending_task) {
tasks_processed_++;
}
void MessageLoopIdleEvent::DidProcessTask(
const base::PendingTask& pending_task) {}
void MessageLoopIdleEvent::RunTask() {
// We need to add the observer in RunTask, since it can only be done by the
// thread that runs MessageLoop
if (!observer_added_) {
message_loop_->AddTaskObserver(this);
observer_added_ = true;
}
bool is_idle = (tasks_processed_ <= 1) && message_loop_->IsIdleForTesting();
if (was_idle_ && is_idle) {
// We need to remove the observer in RunTask, since it can only be done by
// the thread that runs MessageLoop
if (observer_added_) {
message_loop_->RemoveTaskObserver(this);
observer_added_ = false;
}
event_.Signal();
return;
}
was_idle_ = is_idle;
tasks_processed_ = 0;
PostTask();
}
void MessageLoopIdleEvent::Wait() {
event_.Wait();
}
bool MessageLoopIdleEvent::TimedWait(const base::TimeDelta& wait_delta) {
return event_.TimedWait(wait_delta);
}
void MessageLoopIdleEvent::PostTask() {
auto task =
base::Bind(&MessageLoopIdleEvent::RunTask, base::Unretained(this));
message_loop_->task_runner()->PostTask(FROM_HERE, task);
}
} // namespace hwsec