#ifndef TIMER_H_ #define TIMER_H_ #include #include #include #include #include #include #include class NodeTimer { public: NodeTimer() :expired_(true), try_to_expire_(false) { } NodeTimer(const NodeTimer& t) { expired_ = t.expired_.load(); try_to_expire_ = t.try_to_expire_.load(); } ~NodeTimer() { StopTimer(); } void StartTimer(int interval, std::function task) { if (expired_ == false) { return; } expired_ = false; std::thread([this, interval, task]() { while (!try_to_expire_) { std::this_thread::sleep_for(std::chrono::milliseconds(interval)); task(); } // { std::lock_guard locker(mutex_); expired_ = true; expired_cond_.notify_one(); } }).detach(); } void StopTimer() { if (expired_) { return; } if (try_to_expire_) { // return; } try_to_expire_ = true; { std::unique_lock locker(mutex_); expired_cond_.wait(locker, [this] {return expired_ == true; }); if (expired_ == true) { // try_to_expire_ = false; } } } //the following 2 functions can be removed from the class because we will not use them template void SyncWait(int after, callable&& f, arguments&&... args) { std::function::type()> task (std::bind(std::forward(f), std::forward(args)...)); std::this_thread::sleep_for(std::chrono::milliseconds(after)); task(); } template void AsyncWait(int after, callable&& f, arguments&&... args) { std::function::type()> task (std::bind(std::forward(f), std::forward(args)...)); std::thread([after, task]() { std::this_thread::sleep_for(std::chrono::milliseconds(after)); task(); }).detach(); } private: std::atomic expired_; std::atomic try_to_expire_; std::mutex mutex_; std::condition_variable expired_cond_; }; #endif