/* * Copyright (c) 2017-2023 zhllxt * * author : zhllxt * email : 37792738@qq.com * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef __ASIO2_TIMER_HPP__ #define __ASIO2_TIMER_HPP__ #if defined(_MSC_VER) && (_MSC_VER >= 1200) #pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace asio2::detail { struct template_args_timer { static constexpr std::size_t allocator_storage_size = 256; }; ASIO2_CLASS_FORWARD_DECLARE_BASE; template class timer_impl_t : public object_t , public iopool_cp , public thread_id_cp , public user_timer_cp , public post_cp , public condition_event_cp { ASIO2_CLASS_FRIEND_DECLARE_BASE; public: using super = object_t ; using self = timer_impl_t; using iopoolcp = iopool_cp; using args_type = args_t; /** * @brief constructor */ explicit timer_impl_t() : super() , iopool_cp (1) , user_timer_cp () , post_cp () , condition_event_cp() , io_ (iopoolcp::_get_io(0)) { this->start(); } template>, int> = 0> explicit timer_impl_t(Scheduler&& scheduler) : super() , iopool_cp (std::forward(scheduler)) , user_timer_cp () , post_cp () , condition_event_cp() , io_ (iopoolcp::_get_io(0)) { #if defined(ASIO2_ENABLE_LOG) #if defined(ASIO2_ALLOCATOR_STORAGE_SIZE) static_assert(decltype(wallocator_)::storage_size == ASIO2_ALLOCATOR_STORAGE_SIZE); #else static_assert(decltype(wallocator_)::storage_size == args_t::allocator_storage_size); #endif #endif this->start(); } /** * @brief destructor */ ~timer_impl_t() { this->stop(); } /** * @brief start */ inline bool start() { derived_t& derive = this->derived(); // if log is enabled, init the log first, otherwise when "Too many open files" error occurs, // the log file will be created failed too. #if defined(ASIO2_ENABLE_LOG) asio2::detail::get_logger(); #endif bool ret = this->start_iopool(); // start the io_context pool if (ret) { derive.io_->regobj(&derive); derive.dispatch([&derive]() mutable { // init the running thread id derive.io_->init_thread_id(); }); } return ret; } /** * @brief stop */ inline void stop() { if (this->is_iopool_stopped()) return; derived_t& derive = this->derived(); derive.io_->unregobj(&derive); // close user custom timers this->stop_all_timers(); // close all posted timed tasks this->stop_all_timed_tasks(); // close all async_events this->notify_all_condition_events(); // stop the io_context pool this->stop_iopool(); } /** * @brief destroy the content of all member variables, this is used for solve the memory leaks. * After this function is called, this class object cannot be used again. */ inline void destroy() { derived_t& derive = this->derived(); derive.io_.reset(); derive.destroy_iopool(); } public: /** * @brief get the io object reference */ inline io_t & io() noexcept { return *(this->io_); } /** * @brief get the io object reference */ inline io_t const& io() const noexcept { return *(this->io_); } protected: /** * @brief get the recv/read allocator object reference */ inline auto & rallocator() noexcept { return this->wallocator_; } /** * @brief get the send/write allocator object reference */ inline auto & wallocator() noexcept { return this->wallocator_; } protected: /// The io_context wrapper used to handle the accept event. std::shared_ptr io_; /// The memory to use for handler-based custom memory allocation. used fo send/write. handler_memory> wallocator_; }; } namespace asio2 { class timer : public detail::timer_impl_t { public: using detail::timer_impl_t::timer_impl_t; }; } #include #endif // !__ASIO2_TIMER_HPP__