123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- #ifndef __ASIO2_CONNECT_TIMEOUT_COMPONENT_HPP__
- #define __ASIO2_CONNECT_TIMEOUT_COMPONENT_HPP__
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- #pragma once
- #endif
- #include <chrono>
- #include <asio2/base/iopool.hpp>
- #include <asio2/base/log.hpp>
- namespace asio2::detail
- {
- template<class derived_t, class args_t>
- class connect_timeout_cp
- {
- public:
-
- connect_timeout_cp() = default;
-
- ~connect_timeout_cp() = default;
-
- inline std::chrono::steady_clock::duration get_connect_timeout() const noexcept
- {
- return this->connect_timeout_;
- }
-
- template<class Rep, class Period>
- inline derived_t& set_connect_timeout(std::chrono::duration<Rep, Period> timeout) noexcept
- {
- if (timeout > std::chrono::duration_cast<
- std::chrono::duration<Rep, Period>>((std::chrono::steady_clock::duration::max)()))
- this->connect_timeout_ = (std::chrono::steady_clock::duration::max)();
- else
- this->connect_timeout_ = timeout;
- return static_cast<derived_t&>(*this);
- }
- protected:
- template<class Rep, class Period>
- inline void _make_connect_timeout_timer(
- std::shared_ptr<derived_t> this_ptr, std::chrono::duration<Rep, Period> duration)
- {
- derived_t& derive = static_cast<derived_t&>(*this);
- asio::dispatch(derive.io_->context(), make_allocator(derive.wallocator(),
- [this, this_ptr = std::move(this_ptr), duration = std::move(duration)]() mutable
- {
- derived_t& derive = static_cast<derived_t&>(*this);
- if (this->connect_timeout_timer_)
- {
- this->connect_timeout_timer_->cancel();
- }
- this->connect_timeout_timer_ = std::make_shared<safe_timer>(derive.io_->context());
- derive._post_connect_timeout_timer(std::move(this_ptr), this->connect_timeout_timer_, duration);
- }));
- }
- template<class Rep, class Period>
- inline void _post_connect_timeout_timer(std::shared_ptr<derived_t> this_ptr,
- std::shared_ptr<safe_timer> timer_ptr, std::chrono::duration<Rep, Period> duration)
- {
- derived_t& derive = static_cast<derived_t&>(*this);
- #if defined(_DEBUG) || defined(DEBUG)
- ASIO2_ASSERT(this->is_stop_connect_timeout_timer_called_ == false);
- #endif
-
- if (timer_ptr.get() != this->connect_timeout_timer_.get())
- return;
- safe_timer* ptimer = timer_ptr.get();
- ptimer->timer.expires_after(duration);
- ptimer->timer.async_wait(
- [&derive, this_ptr = std::move(this_ptr), timer_ptr = std::move(timer_ptr)]
- (const error_code& ec) mutable
- {
-
-
-
-
-
-
- derive._handle_connect_timeout_timer(ec, std::move(this_ptr), std::move(timer_ptr));
-
-
-
- });
- }
- template<class D = derived_t>
- inline void _handle_connect_timeout_timer(
- const error_code& ec, std::shared_ptr<D> this_ptr, std::shared_ptr<safe_timer> timer_ptr)
- {
- derived_t& derive = static_cast<derived_t&>(*this);
- ASIO2_ASSERT((!ec) || ec == asio::error::operation_aborted);
-
- if (timer_ptr.get() != this->connect_timeout_timer_.get())
- return;
-
- if (!this->connect_timeout_timer_)
- {
- ASIO2_ASSERT(false);
- return;
- }
- this->connect_timeout_timer_.reset();
-
- if (ec == asio::error::operation_aborted || timer_ptr->canceled.test_and_set())
- return;
- if constexpr (D::is_session())
- {
- if (!ec)
- {
- derive._do_disconnect(asio::error::timed_out, std::move(this_ptr));
- }
- else
- {
-
- ASIO2_ASSERT(false);
- derive._do_disconnect(ec, std::move(this_ptr));
- }
- }
- else
- {
-
- if (!ec)
- {
-
-
- error_code ec_ignore{};
- derive.socket().shutdown(asio::socket_base::shutdown_both, ec_ignore);
- derive.socket().cancel(ec_ignore);
- derive.socket().close(ec_ignore);
- ASIO2_ASSERT(!derive.socket().is_open());
- }
- }
- }
- inline void _stop_connect_timeout_timer()
- {
-
-
-
-
-
-
-
-
-
-
- derived_t& derive = static_cast<derived_t&>(*this);
- derive.dispatch([this]() mutable
- {
- #if defined(_DEBUG) || defined(DEBUG)
- this->is_stop_connect_timeout_timer_called_ = true;
- #endif
- if (this->connect_timeout_timer_)
- {
- this->connect_timeout_timer_->cancel();
- }
- });
- }
- protected:
-
-
- std::shared_ptr<safe_timer> connect_timeout_timer_;
- std::chrono::steady_clock::duration connect_timeout_ = std::chrono::seconds(30);
- #if defined(_DEBUG) || defined(DEBUG)
- bool is_stop_connect_timeout_timer_called_ = false;
- #endif
- };
- }
- #endif
|