I have found the following implementation for a callback timer to use in my c++ application. However, this implementation requires me to "join" the thread from the start
caller, which effectively blocks the caller of the start function.
What I really like to do is the following.
- someone can call foo(data) multiple times and store them in a db.
- whenever foo(data) is called, it initiates a timer for few seconds.
- while the timer is counting down, foo(data) can be called several times and multiple items can be stored, but doesn't call erase until timer finishes
- whenever the timer is up, the "remove" function is called once to remove all the records from the db.
Bascially I want to be able to do a task, and wait a few seconds and batch do a single batch task B after a few seconds.
class CallBackTimer {
public:
/**
* Constructor of the CallBackTimer
*/
CallBackTimer() :_execute(false) { }
/**
* Destructor
*/
~CallBackTimer() {
if (_execute.load(std::memory_order_acquire)) {
stop();
};
}
/**
* Stops the timer
*/
void stop() {
_execute.store(false, std::memory_order_release);
if (_thd.joinable()) {
_thd.join();
}
}
/**
* Start the timer function
* @param interval Repeating duration in milliseconds, 0 indicates the @func will run only once
* @param delay Time in milliseconds to wait before the first callback
* @param func Callback function
*/
void start(int interval, int delay, std::function<void(void)> func) {
if(_execute.load(std::memory_order_acquire)) {
stop();
};
_execute.store(true, std::memory_order_release);
_thd = std::thread([this, interval, delay, func]() {
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
if (interval == 0) {
func();
stop();
} else {
while (_execute.load(std::memory_order_acquire)) {
func();
std::this_thread::sleep_for(std::chrono::milliseconds(interval));
}
}
});
}
/**
* Check if the timer is currently running
* @return bool, true if timer is running, false otherwise.
*/
bool is_running() const noexcept {
return ( _execute.load(std::memory_order_acquire) && _thd.joinable() );
}
private:
std::atomic<bool> _execute;
std::thread _thd;
};
I have tried modifying the above code using the thread.detach(). However, I am running issues in detached thread not being able to write (erase) from the database..
Any help and suggestions are appreciated!