예제 #1
0
    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))));
            }
        }
    }
예제 #2
0
    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))));
    }
예제 #3
0
    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)));
    }
예제 #4
0
    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";
        }
    }
예제 #5
0
    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";
        }
    }
예제 #6
0
    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)));
    }
예제 #7
0
    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))));
    }
예제 #8
0
    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))));
    }
예제 #9
0
    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))));
            }
        }
    }