Skip to content

Instantly share code, notes, and snippets.

@cjtallman
Last active November 11, 2016 22:38
Show Gist options
  • Save cjtallman/75f853f6b1f066fce57c5d5e00fac2b5 to your computer and use it in GitHub Desktop.
Save cjtallman/75f853f6b1f066fce57c5d5e00fac2b5 to your computer and use it in GitHub Desktop.
Threaded callback wrapper in C++11
///////////////////////////////////////////////////////////////////////////////
///
/// @copyright Copyright (c) 2016 Chris Tallman.
///
/// @file ASyncCallback.hpp
/// @date 11/11/2016
/// @author ctallman
///
/// @brief Threaded callback wrapper class.
///
////////////////////////////////////////////////////////////////////////////////
#ifndef ASyncCallback_hpp__
#define ASyncCallback_hpp__
#include <atomic>
#include <thread>
template <typename TDuration>
class ASyncCallback
{
public:
typedef std::function<void(void)> Func;
typedef typename TDuration Duration;
ASyncCallback(const Func& func, const Duration period)
: _func(func), _period(period), _is_running(false), _is_periodic(true)
{
}
ASyncCallback(const Func& func) : _func(func), _is_running(false), _is_periodic(false)
{
Stop();
}
void Start()
{
if (!IsRunning())
{
_is_running.store(true);
if (_is_periodic)
_thread = std::thread(std::bind(&ASyncCallback::ThreadFuncPeriodic, this));
else
_thread = std::thread(std::bind(&ASyncCallback::ThreadFuncOnce, this));
}
}
void Stop()
{
if (IsRunning())
{
_is_running.store(false);
if (_thread.joinable())
_thread.join();
}
}
bool IsRunning() const { return _is_running.load(); }
private:
void ThreadFuncPeriodic()
{
while (IsRunning())
{
auto now = std::chrono::high_resolution_clock::now();
_func();
std::this_thread::sleep_until(now + _period);
}
Stop();
}
void ThreadFuncOnce()
{
_func();
Stop();
}
const Func _func;
const Duration _period;
std::thread _thread;
const bool _is_periodic;
std::atomic_bool _is_running;
};
#endif // ASyncCallback_hpp__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment