Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #pragma once
00021
00022 #include <atomic>
00023 #include <boost/asio/deadline_timer.hpp>
00024 #include <boost/chrono.hpp>
00025 #include <mutex>
00026 #include <condition_variable>
00027
00028 namespace OpcUa
00029 {
00030 class PeriodicTimer
00031 {
00032 public:
00033 PeriodicTimer(boost::asio::io_service& io)
00034 : Timer(io)
00035 , IsCanceled(true)
00036 , Stopped(true)
00037 {
00038 }
00039
00040 ~PeriodicTimer()
00041 {
00042 Cancel();
00043 }
00044
00045 void Start(const boost::asio::deadline_timer::duration_type& t, std::function<void()> handler)
00046 {
00047 std::unique_lock<std::mutex> lock(Mutex);
00048 if (!Stopped)
00049 return;
00050
00051 Stopped = false;
00052 IsCanceled = false;
00053 Timer.expires_from_now(t);
00054 Timer.async_wait([this, handler, t](const boost::system::error_code& error){
00055 OnTimer(error, handler, t);
00056 });
00057 }
00058
00059 void Cancel()
00060 {
00061 std::unique_lock<std::mutex> lock(Mutex);
00062 if (Stopped)
00063 return;
00064
00065 IsCanceled = true;
00066 Timer.cancel();
00067 StopEvent.wait(lock, [this](){
00068 return static_cast<bool>(Stopped);
00069 });
00070 }
00071
00072 private:
00073 void OnTimer(const boost::system::error_code& error, std::function<void()> handler, boost::asio::deadline_timer::duration_type t)
00074 {
00075 std::unique_lock<std::mutex> lock(Mutex);
00076 if (IsCanceled || error)
00077 {
00078 Stopped = true;
00079 IsCanceled = true;
00080 StopEvent.notify_all();
00081 return;
00082 }
00083
00084 handler();
00085
00086 Timer.expires_from_now(t);
00087 Timer.async_wait([this, handler, t](const boost::system::error_code& error){
00088 OnTimer(error, handler, t);
00089 });
00090 }
00091
00092 private:
00093 std::mutex Mutex;
00094 std::condition_variable StopEvent;
00095 boost::asio::deadline_timer Timer;
00096 std::atomic<bool> IsCanceled;
00097 std::atomic<bool> Stopped;
00098 };
00099 }