1#include <xrpl/basics/Log.h> 
    2#include <xrpl/basics/Resolver.h> 
    3#include <xrpl/basics/ResolverAsio.h> 
    4#include <xrpl/beast/net/IPAddressConversion.h> 
    5#include <xrpl/beast/net/IPEndpoint.h> 
    6#include <xrpl/beast/utility/Journal.h> 
    7#include <xrpl/beast/utility/instrumentation.h> 
    9#include <boost/asio/bind_executor.hpp> 
   10#include <boost/asio/error.hpp> 
   11#include <boost/asio/io_context.hpp> 
   12#include <boost/asio/ip/tcp.hpp> 
   13#include <boost/system/detail/error_code.hpp> 
   35template <
class Derived>
 
   49            "ripple::AsyncObject::~AsyncObject : nothing pending");
 
 
   73                m_owner->asyncHandlersComplete();
 
 
 
   93            (
static_cast<Derived*
>(
this))->asyncHandlersComplete();
 
 
 
  110    boost::asio::strand<boost::asio::io_context::executor_type> 
m_strand;
 
  126        template <
class StringSequence>
 
 
  140        boost::asio::io_context& io_context,
 
 
  156            "ripple::ResolverAsioImpl::~ResolverAsioImpl : no pending work");
 
  158            m_stopped, 
"ripple::ResolverAsioImpl::~ResolverAsioImpl : stopped");
 
 
  181            m_stopped == 
true, 
"ripple::ResolverAsioImpl::start : stopped");
 
  184            "ripple::ResolverAsioImpl::start : not stopping");
 
 
  201            boost::asio::dispatch(
 
  203                boost::asio::bind_executor(
 
  208                        CompletionCounter(
this))));
 
 
  232            "ripple::ResolverAsioImpl::resolve : not stopping");
 
  235            "ripple::ResolverAsioImpl::resolve : names non-empty");
 
  239        boost::asio::dispatch(
 
  241            boost::asio::bind_executor(
 
  248                    CompletionCounter(
this))));
 
 
  258            "ripple::ResolverAsioImpl::do_stop : stopping");
 
 
  272        boost::system::error_code 
const& ec,
 
  274        boost::asio::ip::tcp::resolver::results_type results,
 
  277        if (ec == boost::asio::error::operation_aborted)
 
  281        auto iter = results.
begin();
 
  287            while (iter != results.end())
 
  295        handler(name, addresses);
 
  299            boost::asio::bind_executor(
 
  304                    CompletionCounter(
this))));
 
 
  326            std::placeholders::_1,
 
  336        if (host_first >= port_last)
 
  340        auto const find_port_separator = [](
char const c) -> 
bool {
 
  351            std::find_if(host_first, port_last, find_port_separator);
 
 
  374        m_work.front().names.pop_back();
 
  376        if (
m_work.front().names.empty())
 
  379        auto const [host, port] = 
parseName(name);
 
  387                boost::asio::bind_executor(
 
  392                        CompletionCounter(
this))));
 
  404                std::placeholders::_1,
 
  406                std::placeholders::_2,
 
  407                CompletionCounter(
this)));
 
 
  418            "ripple::ResolverAsioImpl::do_resolve : names non-empty");
 
  422            m_work.emplace_back(names, handler);
 
  425                << 
"Queued new job with " << names.
size() << 
" tasks. " 
  426                << 
m_work.size() << 
" jobs outstanding.";
 
  432                    boost::asio::bind_executor(
 
  437                            CompletionCounter(
this))));
 
 
 
T back_inserter(T... args)
 
static std::optional< Endpoint > from_string_checked(std::string const &s)
Create an Endpoint from a string.
 
A generic endpoint for log messages.
 
RAII container that maintains the count of pending I/O.
 
CompletionCounter(Derived *owner)
 
CompletionCounter(CompletionCounter const &other)
 
CompletionCounter & operator=(CompletionCounter const &)=delete
 
Mix-in to track when all pending I/O is complete.
 
std::atomic< int > m_pending
 
std::atomic< bool > m_stopped
 
boost::asio::strand< boost::asio::io_context::executor_type > m_strand
 
void do_work(CompletionCounter)
 
void resolve(std::vector< std::string > const &names, HandlerType const &handler) override
 
~ResolverAsioImpl() override
 
void stop() override
Issue a synchronous stop request.
 
void asyncHandlersComplete()
 
std::condition_variable m_cv
 
bool m_asyncHandlersCompleted
 
boost::asio::ip::tcp::resolver m_resolver
 
ResolverAsioImpl(boost::asio::io_context &io_context, beast::Journal journal)
 
std::pair< std::string, std::string > HostAndPort
 
void do_stop(CompletionCounter)
 
std::deque< Work > m_work
 
void start() override
Issue a synchronous start request.
 
std::atomic< bool > m_stop_called
 
void stop_async() override
Issue an asynchronous stop request.
 
HostAndPort parseName(std::string const &str)
 
boost::asio::io_context & m_io_context
 
void do_finish(std::string name, boost::system::error_code const &ec, HandlerType handler, boost::asio::ip::tcp::resolver::results_type results, CompletionCounter)
 
void do_resolve(std::vector< std::string > const &names, HandlerType const &handler, CompletionCounter)
 
static std::unique_ptr< ResolverAsio > New(boost::asio::io_context &, beast::Journal)
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
T reverse_copy(T... args)
 
static IP::Endpoint from_asio(boost::asio::ip::address const &address)
 
std::vector< std::string > names
 
Work(StringSequence const &names_, HandlerType const &handler_)