mirror of
https://github.com/falcosecurity/falco.git
synced 2025-07-31 06:01:52 +00:00
new(userspace/falco): Watchdog timer utility
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
This commit is contained in:
parent
aea12f4f3b
commit
3b7401c2e5
96
userspace/falco/watchdog.h
Normal file
96
userspace/falco/watchdog.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright (C) 2020 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
|
||||
template<typename _T>
|
||||
class Watchdog
|
||||
{
|
||||
public:
|
||||
Watchdog():
|
||||
m_timeout(nullptr),
|
||||
m_is_running(false)
|
||||
{
|
||||
}
|
||||
|
||||
~Watchdog()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void start(std::function<void(_T)> cb,
|
||||
std::chrono::milliseconds resolution = std::chrono::milliseconds(100))
|
||||
{
|
||||
stop();
|
||||
m_is_running.store(true, std::memory_order_release);
|
||||
m_thread = std::thread([this, cb, resolution]() {
|
||||
const auto no_deadline = time_point{};
|
||||
timeout_data curr;
|
||||
while(m_is_running.load(std::memory_order_acquire))
|
||||
{
|
||||
auto t = m_timeout.exchange(nullptr, std::memory_order_release);
|
||||
if(t)
|
||||
{
|
||||
curr = *t;
|
||||
delete t;
|
||||
}
|
||||
if(curr.deadline != no_deadline && curr.deadline < std::chrono::steady_clock::now())
|
||||
{
|
||||
cb(curr.payload);
|
||||
curr.deadline = no_deadline;
|
||||
}
|
||||
std::this_thread::sleep_for(resolution);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
if(m_is_running.load(std::memory_order_acquire))
|
||||
{
|
||||
m_is_running.store(false, std::memory_order_release);
|
||||
if(m_thread.joinable())
|
||||
{
|
||||
m_thread.join();
|
||||
}
|
||||
delete m_timeout.exchange(nullptr, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
|
||||
inline void set_timeout(std::chrono::milliseconds timeout, _T payload) noexcept
|
||||
{
|
||||
delete m_timeout.exchange(new timeout_data{std::chrono::steady_clock::now() + timeout, payload}, std::memory_order_release);
|
||||
}
|
||||
|
||||
inline void cancel_timeout() noexcept
|
||||
{
|
||||
delete m_timeout.exchange(new timeout_data, std::memory_order_release);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::chrono::time_point<std::chrono::steady_clock> time_point;
|
||||
struct timeout_data
|
||||
{
|
||||
time_point deadline;
|
||||
_T payload;
|
||||
};
|
||||
std::atomic<timeout_data *> m_timeout;
|
||||
std::atomic<bool> m_is_running;
|
||||
std::thread m_thread;
|
||||
};
|
Loading…
Reference in New Issue
Block a user