void HandlePollResponse(const std::string & upload_key, FSM & fsm, const mf::api::upload::poll_upload::Response & response) { if (!response.response_data) { auto timer = fsm.Timer(); timer->expires_from_now( std::chrono::seconds(poll_upload_retry_timeout_seconds)); timer->async_wait(boost::bind(&RetryPoll<FSM>, upload_key, fsm.AsFrontShared(), boost::asio::placeholders::error)); } else { const auto & response_data = *response.response_data; // if result is negative, it indicates a failure if (response_data.result < 0) { fsm.ProcessEvent( event::Error{std::error_code(response_data.result, poll_result_category()), "Poll upload bad response"}); } else if (response_data.fileerror != 0) { fsm.ProcessEvent(event::Error{ std::error_code(response_data.fileerror, poll_upload_file_error_category()), "Poll upload file error received"}); } else if (response_data.quickkey) { HandlePollCompleteResponse(fsm, response); } else { auto timer = fsm.Timer(); timer->expires_from_now( std::chrono::seconds(poll_upload_retry_timeout_seconds)); timer->async_wait(boost::bind(&RetryPoll<FSM>, upload_key, fsm.AsFrontShared(), boost::asio::placeholders::error)); } } }
void deadline_timer::wait() { ptime diff = expires_from_now(); if(diff <= ptime::zero) return; ptime::sleep(diff); }
void handler( const boost::system::error_code& error ) { if( error == boost::asio::error::operation_aborted ) { // Happens if we pause it } else if(error) { // DARC_WARNING("PeriodicTimer callback gave some error %u", error.value()); } else if( state_ == STOPPED ) { // Just ignore it } else { // Todo: system time can actually not be trusted. What about using boost::chrono? boost::posix_time::time_duration diff = boost::posix_time::microsec_clock::universal_time() - expected_deadline_; expires_from_now( period_ - diff ); //DARC_INFO("Diff: %s", boost::posix_time::to_simple_string(diff).c_str()); expected_deadline_ += period_; // std::cout << diff.total_milliseconds() << std::endl; async_wait( boost::bind( &periodic_timer::handler, this, boost::asio::placeholders::error ) ); if(state_ == RUNNING) { callback_(); } } }
high_resolution_timer::high_resolution_timer(io_service& io_service, const duration_type& expiry_time) : m_expiration_time(time_type()) , m_io_service(io_service) , m_expired(true) { expires_from_now(expiry_time); }
bool Conn::Write(Packet &&pkt, callbacks_func_type &&cb) { auto timer = std::make_shared< boost::asio::deadline_timer >(io); timer->expires_from_now( boost::posix_time::milliseconds(read_timeout) ); timer->async_wait( boost::bind(&Conn::onTimeout, shared_from_this(), boost::asio::placeholders::error, pkt.hdr.sync, timer) ); if( LOG_DEBUG ) log_func("[iproto_conn] %s:%u: sending packet sync=%u", ep.address().to_string().c_str(), ep.port(), pkt.hdr.sync); callbacks_map[pkt.hdr.sync] = std::make_pair(std::move(timer), std::forward<callbacks_func_type>(cb)); return dropPacketWrite( std::forward<Packet>(pkt) ); }
std::shared_ptr<boost::asio::deadline_timer> RWHandler::setTimeoutTimer(int seconds) { auto timer = std::make_shared<boost::asio::deadline_timer>(m_io_service); timer->expires_from_now(boost::posix_time::seconds(seconds)); auto self(shared_from_this()); timer->async_wait([self](const boost::system::error_code& ec) { if (!ec) { self->onClosed(CLOSED_TYPE::TIMEOUT); } }); return timer; }
// 握手 void async_handshake(socket_ptr const& sp, endpoint const& addr) { async_handshaking_.set(); auto handler = BEX_IO_BIND(&this_type::on_async_handshake, this, BEX_IO_PH_ERROR, sp, addr); if (opts_->ssl_opts) { auto timed_handler = timer_handler<allocator>(handler, ios_); timed_handler.expires_from_now(boost::posix_time::milliseconds(opts_->ssl_opts->handshake_overtime)); timed_handler.async_wait(BEX_IO_BIND(&this_type::on_async_handshake, this, make_error_code(errc::handshake_overtime), sp, addr)); protocol_traits_type::async_handshake(sp, ssl::stream_base::client, timed_handler); } else protocol_traits_type::async_handshake(sp, ssl::stream_base::client, handler); }
void sleep(std::size_t ms,CO co,boost::system::error_code& e) { BOOST_ASSERT(co != NULL); if (ms == 0) { return; } timer_handler<CO> handler(co,e); expires_from_now(boost::posix_time::milliseconds(ms)); async_wait(handler); ////////////////////////// co -> yield(); ///////////////////////// if(e) { ORCHID_DEBUG("timer sleep error: %s",e.message().c_str()); } return; }
// 带超时的异步连接 bool async_connect_timed(endpoint const& addr, boost::posix_time::time_duration time) { if (is_running() || !async_connecting_.set()) return false; socket_ptr sp = protocol_type::alloc_socket(ios_, *opts_, ec_); if (ec_) return false; /// 连接超时计时器, 异步等待 auto timed_handler = timer_handler<allocator>(BEX_IO_BIND(&this_type::on_async_connect_timed, this, BEX_IO_PH_ERROR, sp, addr, time), ios_); timed_handler.expires_from_now(time); timed_handler.async_wait(BEX_IO_BIND(&this_type::on_overtime, this, BEX_IO_PH_ERROR, sp, errc::connect_overtime)); sp->lowest_layer().async_connect(addr, timed_handler); // 启动工作线程 mstrand_service_.startup(opts_->workthread_count); return true; }
void on_start() { expected_deadline_ = boost::posix_time::microsec_clock::universal_time() + period_; expires_from_now( period_ ); async_wait( boost::bind( &periodic_timer::handler, this, boost::asio::placeholders::error ) ); }
std::size_t high_resolution_timer::expires_from_now(const duration_type& expiry_time) { boost::system::error_code ec; return expires_from_now(expiry_time, ec); }
std::size_t timer::expires_from_now( const duration_type & expiry_time, boost::system::error_code & ec ) { ec = boost::system::error_code(); return expires_from_now( expiry_time ); }