Last active
January 9, 2023 14:05
-
-
Save ADCDS/081326f9033f8d7ab557b670442bef10 to your computer and use it in GitHub Desktop.
Timed task scheduler using boost asio
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by agiu on 1/4/23. | |
// | |
#ifndef INCLUDE_TIMED_SCHEDULER_HPP | |
#define INCLUDE_TIMED_SCHEDULER_HPP | |
#include <boost/asio/io_context.hpp> | |
#include <boost/system/error_code.hpp> | |
#include <boost/asio/steady_timer.hpp> | |
template<typename io_context> | |
class scheduler : public std::enable_shared_from_this<scheduler<io_context>> { | |
using boost_ec = boost::system::error_code; | |
using timer_sptr = std::shared_ptr<boost::asio::steady_timer>; | |
using task_completion_handler = std::function<void(const boost_ec &)>; | |
io_context &_io_ctx; | |
struct task { | |
timer_sptr _timer; | |
explicit task(const timer_sptr &timer) : _timer(timer) {} | |
}; | |
mutable std::mutex mtx_tasks; | |
std::unordered_map <uint16_t, task> _tasks; | |
public: | |
explicit scheduler(io_context &io_ctx) : _io_ctx(io_ctx) {}; | |
uint16_t add_task(std::chrono::milliseconds expire_after, task_completion_handler &&cb) { | |
std::lock_guard<std::mutex> g(mtx_tasks); | |
const auto task_id = static_cast<uint16_t>(_tasks.size()); | |
auto weak_self = std::weak_ptr<scheduler>(this->shared_from_this()); | |
const auto timer = std::make_shared<boost::asio::steady_timer>(_io_ctx); | |
timer->expires_after(expire_after); | |
timer->async_wait([weak_self, timer, task_id, handler = std::forward<task_completion_handler>(cb)]( | |
const boost_ec &ec) { | |
handler(ec); | |
if (auto self = weak_self.lock()) { | |
std::lock_guard<std::mutex> g(self->mtx_tasks); | |
self->_tasks.erase(task_id); | |
} | |
}); | |
_tasks.emplace(task_id, task{timer}); | |
return task_id; | |
}; | |
void cancel_task(uint16_t task_id) { | |
std::lock_guard<std::mutex> g(mtx_tasks); | |
const auto find_it = _tasks.find(task_id); | |
if (find_it == _tasks.end()) | |
return; | |
const auto &task = find_it->second; | |
task._timer->cancel(); | |
}; | |
}; | |
#endif //INCLUDE_TIMED_SCHEDULER_HPP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment