blob: c90e2b22b4eb67985a1fed83fa7dda0cdf016a78 [file] [log] [blame]
// Copyright 2017 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 "cfm-device-monitor/camera-monitor/abstract_monitor.h"
#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string>
#include "base/bind.h"
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
namespace huddly_monitor {
AbstractMonitor::AbstractMonitor(bool init_wait_val, uint32_t sleep_time)
: monitor_lock_(),
wait_condition_(&monitor_lock_),
monitor_thread_(new base::Thread("monitor_thread")),
condition_(init_wait_val),
terminate_(false),
sleep_time_milliseconds_(sleep_time) {}
AbstractMonitor::~AbstractMonitor() { DestroyMonitor(); }
void AbstractMonitor::UpdateCondition(bool user_defined_cond) {
monitor_lock_.Acquire();
if ((condition_ = user_defined_cond)) {
wait_condition_.Signal();
}
monitor_lock_.Release();
}
bool AbstractMonitor::StartMonitor() {
monitor_thread_->Start();
monitor_thread_->task_runner().get()->PostTask(
FROM_HERE,
base::Bind(&AbstractMonitor::MonitorThread, base::Unretained(this)));
return true;
}
void AbstractMonitor::MonitorThread() {
std::string err_msg;
while (Monitor(&err_msg)) {
base::PlatformThread::Sleep(
base::Milliseconds(sleep_time_milliseconds_));
}
if (terminate_) {
VLOG(1) << "Monitor thread terminated gracefully.";
return;
}
LOG(ERROR) << "Monitor thread terminated due to failure.";
LOG(ERROR) << err_msg;
}
bool AbstractMonitor::Monitor(std::string *err_msg) {
monitor_lock_.Acquire();
while (!condition_) {
wait_condition_.Wait();
monitor_lock_.AssertAcquired();
}
if (terminate_) {
monitor_lock_.Release(); // Probably unnecessary, but safe.
return false;
}
monitor_lock_.Release();
if (!VitalsExist()) {
return Respond();
}
return true;
}
void AbstractMonitor::TerminateMonitorThread() {
monitor_lock_.Acquire();
// Indicate monitor thread should quit.
terminate_ = true;
// Ensure monitor thread exits condition variable.
condition_ = true;
monitor_lock_.Release();
// Wake up monitor thread.
wait_condition_.Broadcast();
}
void AbstractMonitor::DestroyMonitor() { TerminateMonitorThread(); }
} // namespace huddly_monitor