void do_resolve (std::vector <std::string> const& names, HandlerType const& handler, CompletionCounter) { check_precondition (! names.empty()); if (m_called_stop.load () == 0) { // TODO NIKB use emplace_back once we move to C++11 m_work.push_back(Work(names, handler)); m_journal.debug << "Queued new job with " << names.size() << " tasks. " << m_work.size() << " jobs outstanding."; if (m_work.size() == 1) { check_precondition (m_idle); m_journal.trace << "Waking up"; m_idle = false; m_io_service.post (m_strand.wrap (boost::bind ( &NameResolverImpl::do_work, this, CompletionCounter(this)))); } } }
void do_finish ( std::string name, boost::system::error_code const& ec, HandlerType handler, boost::asio::ip::tcp::resolver::iterator iter, CompletionCounter) { if (ec == boost::asio::error::operation_aborted) return; std::vector <beast::IP::Endpoint> addresses; // If we get an error message back, we don't return any // results that we may have gotten. if (!ec) { while (iter != boost::asio::ip::tcp::resolver::iterator()) { addresses.push_back (beast::IPAddressConversion::from_asio (*iter)); ++iter; } } handler (name, addresses); m_io_service.post (m_strand.wrap (std::bind ( &ResolverAsioImpl::do_work, this, CompletionCounter (this)))); }
void do_work (CompletionCounter) { if (m_called_stop.load () == 1) return; // We don't have any work to do at this time if (m_work.empty()) { m_idle = true; m_journal.trace << "Sleeping"; return; } if (m_work.front().names.empty()) m_work.pop_front(); std::string const name (m_work.front().names.back()); HandlerType handler (m_work.front().handler); m_work.front().names.pop_back(); HostAndPort const hp (parseName(name)); if (hp.first.empty()) { m_journal.error << "Unable to parse '" << name << "'"; m_io_service.post (m_strand.wrap (boost::bind ( &NameResolverImpl::do_work, this, CompletionCounter(this)))); return; } boost::asio::ip::tcp::resolver::query query ( hp.first, hp.second); m_resolver.async_resolve (query, boost::bind ( &NameResolverImpl::do_finish, this, name, boost::asio::placeholders::error, handler, boost::asio::placeholders::iterator, CompletionCounter(this))); }
void stop_async () override { if (m_stop_called.exchange (true) == false) { m_io_service.dispatch (m_strand.wrap (std::bind ( &ResolverAsioImpl::do_stop, this, CompletionCounter (this)))); JLOG(m_journal.debug()) << "Queued a stop request"; } }
void stop_async () { if (m_called_stop.exchange (1) == 0) { m_io_service.dispatch (m_strand.wrap (boost::bind ( &NameResolverImpl::do_stop, this, CompletionCounter (this)))); m_journal.debug << "Stopping"; } }
void do_work (CompletionCounter) { if (m_stop_called == true) return; // We don't have any work to do at this time if (m_work.empty ()) return; std::string const name (m_work.front ().names.back()); HandlerType handler (m_work.front ().handler); m_work.front ().names.pop_back (); if (m_work.front ().names.empty ()) m_work.pop_front(); HostAndPort const hp (parseName (name)); if (hp.first.empty ()) { JLOG(m_journal.error()) << "Unable to parse '" << name << "'"; m_io_service.post (m_strand.wrap (std::bind ( &ResolverAsioImpl::do_work, this, CompletionCounter (this)))); return; } boost::asio::ip::tcp::resolver::query query ( hp.first, hp.second); m_resolver.async_resolve (query, std::bind ( &ResolverAsioImpl::do_finish, this, name, std::placeholders::_1, handler, std::placeholders::_2, CompletionCounter (this))); }
void resolve ( std::vector <std::string> const& names, HandlerType const& handler) { check_precondition (m_called_stop.load () == 0); check_precondition (!names.empty()); // TODO NIKB use rvalue references to construct and move // reducing cost. m_io_service.dispatch (m_strand.wrap (boost::bind ( &NameResolverImpl::do_resolve, this, names, handler, CompletionCounter(this)))); }
void resolve ( std::vector <std::string> const& names, HandlerType const& handler) override { assert (m_stop_called == false); assert (m_stopped == true); assert (!names.empty()); // TODO NIKB use rvalue references to construct and move // reducing cost. m_io_service.dispatch (m_strand.wrap (std::bind ( &ResolverAsioImpl::do_resolve, this, names, handler, CompletionCounter (this)))); }
void do_resolve (std::vector <std::string> const& names, HandlerType const& handler, CompletionCounter) { assert (! names.empty()); if (m_stop_called == false) { m_work.emplace_back (names, handler); JLOG(m_journal.debug()) << "Queued new job with " << names.size() << " tasks. " << m_work.size() << " jobs outstanding."; if (m_work.size() > 0) { m_io_service.post (m_strand.wrap (std::bind ( &ResolverAsioImpl::do_work, this, CompletionCounter (this)))); } } }