61 lines
1.6 KiB
C++
61 lines
1.6 KiB
C++
/*
|
|
Copyright (c) 2017 Microsoft Corporation. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
Author: Gabriel Ebner
|
|
*/
|
|
#include "util/timer.h"
|
|
|
|
#if defined(LEAN_MULTI_THREAD)
|
|
namespace lean {
|
|
constexpr chrono::steady_clock::duration accuracy = chrono::milliseconds(10);
|
|
|
|
single_timer::single_timer():
|
|
m_shutting_down(false),
|
|
m_thread(std::bind(&single_timer::worker, this)) {}
|
|
|
|
single_timer::~single_timer() {
|
|
{
|
|
unique_lock<mutex> lock(m_mutex);
|
|
m_shutting_down = true;
|
|
m_timer_changed.notify_one();
|
|
}
|
|
m_thread.join();
|
|
}
|
|
|
|
void single_timer::worker() {
|
|
unique_lock<mutex> lock(m_mutex);
|
|
while (!m_shutting_down) {
|
|
auto now = chrono::steady_clock::now();
|
|
if (m_time && *m_time <= now + accuracy) {
|
|
m_time = optional<chrono::steady_clock::time_point>();
|
|
if (auto cb = std::move(m_cb)) {
|
|
lock.unlock();
|
|
cb();
|
|
lock.lock();
|
|
}
|
|
} else if (m_time) {
|
|
m_timer_changed.wait_for(lock, *m_time - now);
|
|
} else {
|
|
m_timer_changed.wait(lock);
|
|
}
|
|
}
|
|
}
|
|
|
|
void single_timer::set(chrono::steady_clock::time_point const & time, callback const & cb, bool overwrite) {
|
|
unique_lock<mutex> lock(m_mutex);
|
|
if (overwrite || !m_time) {
|
|
m_time = optional<chrono::steady_clock::time_point>(time);
|
|
m_cb = cb;
|
|
m_timer_changed.notify_one();
|
|
}
|
|
}
|
|
|
|
void single_timer::reset() {
|
|
unique_lock<mutex> lock(m_mutex);
|
|
m_time = optional<chrono::steady_clock::time_point>();
|
|
m_cb = nullptr;
|
|
m_timer_changed.notify_one();
|
|
}
|
|
}
|
|
#endif
|