123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- #ifndef __ASIO2_CONDITION_EVENT_COMPONENT_HPP__
- #define __ASIO2_CONDITION_EVENT_COMPONENT_HPP__
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- #pragma once
- #endif
- #include <cstddef>
- #include <map>
- #include <limits>
- #include <memory>
- #include <type_traits>
- #include <chrono>
- #include <mutex>
- #include <asio2/base/iopool.hpp>
- #include <asio2/base/detail/object.hpp>
- #include <asio2/base/detail/allocator.hpp>
- #include <asio2/util/spin_lock.hpp>
- namespace asio2::detail
- {
- template<class, class> class condition_event_cp;
- template<class, class> class rdc_call_cp_impl;
- }
- namespace asio2
- {
- class [[deprecated("Replace async_event with condition_event")]] async_event : public detail::object_t<async_event>
- {
- };
- class condition_event : public detail::object_t<condition_event>
- {
- template<class, class> friend class asio2::detail::condition_event_cp;
- template<class, class> friend class asio2::detail::rdc_call_cp_impl;
- public:
- explicit condition_event(std::shared_ptr<detail::io_t>& iot)
- : event_timer_io_(iot)
- {
- }
- ~condition_event() noexcept
- {
- }
- protected:
- template <typename WaitHandler>
- inline void async_wait(WaitHandler&& handler)
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- std::shared_ptr<detail::io_t> io_ptr = this->event_timer_io_.lock();
- if (!io_ptr)
- return;
- this->event_timer_ = std::make_unique<asio::steady_timer>(io_ptr->context());
- io_ptr->timers().emplace(this->event_timer_.get());
-
-
- this->event_timer_->expires_after((std::chrono::nanoseconds::max)());
-
-
-
-
-
- this->event_timer_->async_wait(
- [this, handler = std::forward<WaitHandler>(handler)](const error_code& ec) mutable
- {
- ASIO2_ASSERT((!ec) || ec == asio::error::operation_aborted);
- detail::ignore_unused(ec);
- std::shared_ptr<detail::io_t> io_ptr = this->event_timer_io_.lock();
- if (!io_ptr)
- return;
- io_ptr->timers().erase(this->event_timer_.get());
- handler();
- });
- }
- public:
-
- inline void notify()
- {
-
-
- std::shared_ptr<detail::io_t> io_ptr = this->event_timer_io_.lock();
- if (!io_ptr)
- return;
- asio::dispatch(io_ptr->context(), [this, this_ptr = this->selfptr()]() mutable
- {
- detail::ignore_unused(this_ptr);
- detail::cancel_timer(*(this->event_timer_));
- });
- }
- protected:
-
- std::weak_ptr<detail::io_t> event_timer_io_;
-
- std::unique_ptr<asio::steady_timer> event_timer_;
- };
- }
- namespace asio2::detail
- {
- template<class derived_t, class args_t = void>
- class condition_event_cp
- {
- public:
-
- condition_event_cp() = default;
-
- ~condition_event_cp() = default;
- public:
-
- template<typename Function>
- inline std::shared_ptr<condition_event> post_condition_event(Function&& fn)
- {
- derived_t& derive = static_cast<derived_t&>(*this);
- std::shared_ptr<condition_event> event_ptr = std::make_shared<condition_event>(derive.io_);
- asio::dispatch(derive.io_->context(), make_allocator(derive.wallocator(),
- [this, this_ptr = derive.selfptr(), event_ptr, fn = std::forward<Function>(fn)]() mutable
- {
- condition_event* evt = event_ptr.get();
- this->condition_events_.emplace(evt, std::move(event_ptr));
- evt->async_wait([this, this_ptr = std::move(this_ptr), key = evt, fn = std::move(fn)]() mutable
- {
- fn();
- this->condition_events_.erase(key);
- });
- }));
- return event_ptr;
- }
-
- inline derived_t& notify_all_condition_events()
- {
- derived_t& derive = static_cast<derived_t&>(*this);
-
- asio::dispatch(derive.io_->context(), make_allocator(derive.wallocator(),
- [this, this_ptr = derive.selfptr()]() mutable
- {
- for (auto&[key, event_ptr] : this->condition_events_)
- {
- detail::ignore_unused(this_ptr, key);
- event_ptr->notify();
- }
- }));
- return derive;
- }
- protected:
-
-
-
-
- std::map<condition_event*, std::shared_ptr<condition_event>> condition_events_;
- };
- }
- #endif
|