Avoid deprecated Boost.Asio interfaces

Change-Id: I00d285893ff61619f49dff8a8a55d0d0e2c309a7
This commit is contained in:
Davide Pesavento committed 2023-11-10 17:40:43 -05:00
1 parent 550d8c99ab
commit 2f46d6543e
69 files changed
+605 -712

No files matched your search

+5 -1
View File
@@ -128,7 +128,11 @@ class CompilerFlags:
def getGeneralFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []}
return {
'CXXFLAGS': [],
'LINKFLAGS': [],
'DEFINES': ['BOOST_ASIO_NO_DEPRECATED', 'BOOST_FILESYSTEM_NO_DEPRECATED'],
}
def getDebugFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in debug mode"""
+6 -6
View File
@@ -49,13 +49,13 @@ Consumer that uses Scheduler
The following example demonstrates how to use :ndn-cxx:`Scheduler` to schedule arbitrary
events for execution at specific points of time.
The library internally uses `boost::asio::io_service
<https://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/reference/io_service.html>`_ to
implement fully asynchronous NDN operations (i.e., sending and receiving Interests and
Data). In addition to network-related operations, ``boost::asio::io_service`` can be used
The library internally uses `boost::asio::io_context
<https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/reference/io_context.html>`__
to implement fully asynchronous NDN operations (i.e., sending and receiving Interests and
Data). In addition to network-related operations, ``boost::asio::io_context`` can be used
to execute any arbitrary callback within the processing thread (run either explicitly via
``io_service::run()`` or implicitly via :ndn-cxx:`Face::processEvents` as in previous
examples). :ndn-cxx:`Scheduler` is just a wrapper on top of ``io_service``, providing a
``io_context::run()`` or implicitly via :ndn-cxx:`Face::processEvents` as in previous
examples). :ndn-cxx:`Scheduler` is just a wrapper on top of ``io_context``, providing a
simple interface to schedule tasks at specific times.
The highlighted lines in the example demonstrate all that is needed to express a second
+1 -1
View File
@@ -145,7 +145,7 @@ Deprecated
Use versions that accept reference to ``io_service`` object.
- ``Face::ioService`` method, use :ndn-cxx:`Face::getIoService` instead.
- ``Face::ioService`` method, use ``Face::getIoService`` instead.
- :ndn-cxx:`Interest` constructor that accepts name, individual selectors, and individual
guiders as constructor parameters.
+8 -8
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2022 Regents of the University of California.
* Copyright (c) 2013-2023 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -22,7 +22,7 @@
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/io_context.hpp>
#include <iostream>
// Enclosing code in ndn simplifies coding (can also use `using namespace ndn`)
@@ -52,8 +52,8 @@ public:
// Schedule a new event
m_scheduler.schedule(3_s, [this] { delayedInterest(); });
// m_ioService.run() will block until all events finished or m_ioService.stop() is called
m_ioService.run();
// m_ioCtx.run() will block until all events finished or m_ioCtx.stop() is called
m_ioCtx.run();
// Alternatively, m_face.processEvents() can also be called.
// processEvents will block until the requested data received or timeout occurs.
@@ -100,10 +100,10 @@ private:
}
private:
// Explicitly create io_service object, which will be shared between Face and Scheduler
boost::asio::io_service m_ioService;
Face m_face{m_ioService};
Scheduler m_scheduler{m_ioService};
// Explicitly create io_context object, which will be shared between Face and Scheduler
boost::asio::io_context m_ioCtx;
Face m_face{m_ioCtx};
Scheduler m_scheduler{m_ioCtx};
};
} // namespace examples
-5
View File
@@ -22,13 +22,8 @@
#ifndef NDN_CXX_DETAIL_ASIO_FWD_HPP
#define NDN_CXX_DETAIL_ASIO_FWD_HPP
#include <boost/version.hpp>
namespace boost::asio {
class io_context;
using io_service = io_context;
} // namespace boost::asio
#endif // NDN_CXX_DETAIL_ASIO_FWD_HPP
-4
View File
@@ -68,10 +68,6 @@ using std::weak_ptr;
using std::make_shared;
using std::make_unique;
using std::static_pointer_cast;
using std::dynamic_pointer_cast;
using std::const_pointer_cast;
using std::to_string;
using namespace std::string_literals;
using namespace std::string_view_literals;
+1 -1
View File
@@ -73,7 +73,7 @@ TagHost::getTag() const
static_assert(std::is_convertible_v<T*, Tag*>, "T must inherit from ndn::Tag");
if (auto it = m_tags.find(T::getTypeId()); it != m_tags.end()) {
return static_pointer_cast<T>(it->second);
return std::static_pointer_cast<T>(it->second);
}
return nullptr;
}
+1 -1
View File
@@ -34,7 +34,7 @@ Encoder::Encoder(size_t totalReserve, size_t reserveFromBack)
}
Encoder::Encoder(const Block& block)
: m_buffer(const_pointer_cast<Buffer>(block.getBuffer()))
: m_buffer(std::const_pointer_cast<Buffer>(block.getBuffer()))
, m_begin(m_buffer->begin() + (block.begin() - m_buffer->begin()))
, m_end(m_buffer->begin() + (block.end() - m_buffer->begin()))
{
+72 -75
View File
@@ -20,31 +20,20 @@
*/
#include "ndn-cxx/face.hpp"
#include "ndn-cxx/encoding/tlv.hpp"
#include "ndn-cxx/impl/face-impl.hpp"
#include "ndn-cxx/net/face-uri.hpp"
#include "ndn-cxx/transport/tcp-transport.hpp"
#include "ndn-cxx/transport/unix-transport.hpp"
#include "ndn-cxx/util/config-file.hpp"
#include "ndn-cxx/util/scope.hpp"
#include "ndn-cxx/util/time.hpp"
// NDN_LOG_INIT(ndn.Face) is declared in face-impl.hpp
// A callback scheduled through io.post and io.dispatch may be invoked after the face is destructed.
// To prevent this situation, use these macros to capture Face::m_impl as weak_ptr and skip callback
// execution if the face has been destructed.
#define IO_CAPTURE_WEAK_IMPL(OP) \
{ \
weak_ptr<Impl> implWeak(m_impl); \
m_ioService.OP([=] { \
auto impl = implWeak.lock(); \
if (impl != nullptr) {
#define IO_CAPTURE_WEAK_IMPL_END \
} \
}); \
}
namespace ndn {
// NDN_LOG_INIT(ndn.Face) is declared in face-impl.hpp
Face::OversizedPacketError::OversizedPacketError(char pktType, const Name& name, size_t wireSize)
: Error((pktType == 'I' ? "Interest " : pktType == 'D' ? "Data " : "Nack ") +
name.toUri() + " encodes into " + std::to_string(wireSize) + " octets, "
@@ -56,50 +45,50 @@ Face::OversizedPacketError::OversizedPacketError(char pktType, const Name& name,
}
Face::Face(shared_ptr<Transport> transport)
: m_internalIoService(make_unique<boost::asio::io_service>())
, m_ioService(*m_internalIoService)
: m_internalIoCtx(make_unique<boost::asio::io_context>())
, m_ioCtx(*m_internalIoCtx)
, m_internalKeyChain(make_unique<KeyChain>())
{
construct(std::move(transport), *m_internalKeyChain);
}
Face::Face(boost::asio::io_service& ioService)
: m_ioService(ioService)
Face::Face(boost::asio::io_context& ioCtx)
: m_ioCtx(ioCtx)
, m_internalKeyChain(make_unique<KeyChain>())
{
construct(nullptr, *m_internalKeyChain);
}
Face::Face(const std::string& host, const std::string& port)
: m_internalIoService(make_unique<boost::asio::io_service>())
, m_ioService(*m_internalIoService)
: m_internalIoCtx(make_unique<boost::asio::io_context>())
, m_ioCtx(*m_internalIoCtx)
, m_internalKeyChain(make_unique<KeyChain>())
{
construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
}
Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
: m_internalIoService(make_unique<boost::asio::io_service>())
, m_ioService(*m_internalIoService)
: m_internalIoCtx(make_unique<boost::asio::io_context>())
, m_ioCtx(*m_internalIoCtx)
{
construct(std::move(transport), keyChain);
}
Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService)
: m_ioService(ioService)
Face::Face(shared_ptr<Transport> transport, boost::asio::io_context& ioCtx)
: m_ioCtx(ioCtx)
, m_internalKeyChain(make_unique<KeyChain>())
{
construct(std::move(transport), *m_internalKeyChain);
}
Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain)
: m_ioService(ioService)
Face::Face(shared_ptr<Transport> transport, boost::asio::io_context& ioCtx, KeyChain& keyChain)
: m_ioCtx(ioCtx)
{
construct(std::move(transport), keyChain);
}
shared_ptr<Transport>
Face::makeDefaultTransport()
static shared_ptr<Transport>
makeDefaultTransport()
{
std::string transportUri;
@@ -117,11 +106,8 @@ Face::makeDefaultTransport()
return UnixTransport::create("");
}
std::string protocol;
try {
FaceUri uri(transportUri);
protocol = uri.getScheme();
std::string protocol = FaceUri(transportUri).getScheme();
if (protocol == "unix") {
return UnixTransport::create(transportUri);
}
@@ -152,9 +138,11 @@ Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
}
m_transport = std::move(transport);
IO_CAPTURE_WEAK_IMPL(post) {
impl->ensureConnected(false);
} IO_CAPTURE_WEAK_IMPL_END
boost::asio::post(m_ioCtx, [w = m_impl->weak_from_this()] {
if (auto impl = w.lock(); impl != nullptr) {
impl->ensureConnected(false);
}
});
}
Face::~Face() = default;
@@ -166,13 +154,14 @@ Face::expressInterest(const Interest& interest,
const TimeoutCallback& afterTimeout)
{
auto id = m_impl->m_pendingInterestTable.allocateId();
auto interest2 = make_shared<Interest>(interest);
interest2->getNonce();
IO_CAPTURE_WEAK_IMPL(post) {
impl->expressInterest(id, interest2, afterSatisfied, afterNacked, afterTimeout);
} IO_CAPTURE_WEAK_IMPL_END
boost::asio::post(m_ioCtx, [=, w = m_impl->weak_from_this()] {
if (auto impl = w.lock(); impl != nullptr) {
impl->expressInterest(id, interest2, afterSatisfied, afterNacked, afterTimeout);
}
});
return PendingInterestHandle(m_impl, id);
}
@@ -180,9 +169,11 @@ Face::expressInterest(const Interest& interest,
void
Face::removeAllPendingInterests()
{
IO_CAPTURE_WEAK_IMPL(post) {
impl->removeAllPendingInterests();
} IO_CAPTURE_WEAK_IMPL_END
boost::asio::post(m_ioCtx, [w = m_impl->weak_from_this()] {
if (auto impl = w.lock(); impl != nullptr) {
impl->removeAllPendingInterests();
}
});
}
size_t
@@ -192,19 +183,23 @@ Face::getNPendingInterests() const
}
void
Face::put(Data data)
Face::put(const Data& data)
{
IO_CAPTURE_WEAK_IMPL(post) {
impl->putData(data);
} IO_CAPTURE_WEAK_IMPL_END
boost::asio::post(m_ioCtx, [data, w = m_impl->weak_from_this()] {
if (auto impl = w.lock(); impl != nullptr) {
impl->putData(data);
}
});
}
void
Face::put(lp::Nack nack)
Face::put(const lp::Nack& nack)
{
IO_CAPTURE_WEAK_IMPL(post) {
impl->putNack(nack);
} IO_CAPTURE_WEAK_IMPL_END
boost::asio::post(m_ioCtx, [nack, w = m_impl->weak_from_this()] {
if (auto impl = w.lock(); impl != nullptr) {
impl->putNack(nack);
}
});
}
RegisteredPrefixHandle
@@ -234,9 +229,11 @@ Face::setInterestFilter(const InterestFilter& filter, const InterestCallback& on
{
auto id = m_impl->m_interestFilterTable.allocateId();
IO_CAPTURE_WEAK_IMPL(post) {
impl->setInterestFilter(id, filter, onInterest);
} IO_CAPTURE_WEAK_IMPL_END
boost::asio::post(m_ioCtx, [=, w = m_impl->weak_from_this()] {
if (auto impl = w.lock(); impl != nullptr) {
impl->setInterestFilter(id, filter, onInterest);
}
});
return InterestFilterHandle(m_impl, id);
}
@@ -256,44 +253,47 @@ Face::registerPrefix(const Name& prefix,
}
void
Face::doProcessEvents(time::milliseconds timeout, bool keepThread)
Face::doProcessEvents(time::milliseconds timeout, bool keepRunning)
{
if (m_ioService.stopped()) {
m_ioService.reset(); // ensure that run()/poll() will do some work
if (m_ioCtx.stopped()) {
m_ioCtx.restart(); // ensure that run()/poll() will do some work
}
auto onThrow = make_scope_fail([this] { m_impl->shutdown(); });
if (timeout < 0_ms) {
// do not block if timeout is negative, but process pending events
m_ioService.poll();
m_ioCtx.poll();
return;
}
if (timeout > 0_ms) {
// TODO: consider using m_ioCtx.run_for(timeout) in this case
m_impl->m_processEventsTimeoutEvent = m_impl->m_scheduler.schedule(timeout,
[&io = m_ioService, &work = m_impl->m_ioServiceWork] {
[&io = m_ioCtx, &work = m_impl->m_workGuard] {
io.stop();
work.reset();
});
}
if (keepThread) {
// work will ensure that m_ioService is running until work object exists
m_impl->m_ioServiceWork = make_unique<boost::asio::io_service::work>(m_ioService);
if (keepRunning) {
// m_workGuard ensures that m_ioCtx keeps running even when it runs out of work (events)
m_impl->m_workGuard = make_unique<Impl::IoContextWorkGuard>(m_ioCtx.get_executor());
}
m_ioService.run();
m_ioCtx.run();
}
void
Face::shutdown()
{
IO_CAPTURE_WEAK_IMPL(post) {
impl->shutdown();
if (m_transport->getState() != Transport::State::CLOSED)
m_transport->close();
} IO_CAPTURE_WEAK_IMPL_END
boost::asio::post(m_ioCtx, [this, w = m_impl->weak_from_this()] {
if (auto impl = w.lock(); impl != nullptr) {
impl->shutdown();
if (m_transport->getState() != Transport::State::CLOSED)
m_transport->close();
}
});
}
/**
@@ -344,8 +344,7 @@ Face::onReceiveElement(const Block& blockFromDaemon)
PendingInterestHandle::PendingInterestHandle(weak_ptr<Face::Impl> weakImpl, detail::RecordId id)
: CancelHandle([w = std::move(weakImpl), id] {
auto impl = w.lock();
if (impl != nullptr) {
if (auto impl = w.lock(); impl != nullptr) {
impl->asyncRemovePendingInterest(id);
}
})
@@ -381,8 +380,7 @@ RegisteredPrefixHandle::unregister(const weak_ptr<Face::Impl>& weakImpl, detail:
const UnregisterPrefixSuccessCallback& onSuccess,
const UnregisterPrefixFailureCallback& onFailure)
{
auto impl = weakImpl.lock();
if (impl != nullptr) {
if (auto impl = weakImpl.lock(); impl != nullptr) {
impl->asyncUnregisterPrefix(id, onSuccess, onFailure);
}
else if (onFailure) {
@@ -392,8 +390,7 @@ RegisteredPrefixHandle::unregister(const weak_ptr<Face::Impl>& weakImpl, detail:
InterestFilterHandle::InterestFilterHandle(weak_ptr<Face::Impl> weakImpl, detail::RecordId id)
: CancelHandle([w = std::move(weakImpl), id] {
auto impl = w.lock();
if (impl != nullptr) {
if (auto impl = w.lock(); impl != nullptr) {
impl->asyncUnsetInterestFilter(id);
}
})
+69 -66
View File
@@ -118,7 +118,7 @@ public:
public: // constructors
/**
* @brief Create Face using given transport (or default transport if omitted)
* @brief Create Face using the given Transport (or default transport if omitted).
* @param transport the transport for lower layer communication. If nullptr,
* a default transport will be used. The default transport is
* determined from a FaceUri in NDN_CLIENT_TRANSPORT environ,
@@ -132,38 +132,36 @@ public: // constructors
Face(shared_ptr<Transport> transport = nullptr);
/**
* @brief Create Face using default transport and given io_service
* @brief Create Face using default transport and given io_context.
*
* Usage examples:
*
* @code
* Face face1;
* Face face2(face1.getIoService());
* Face face2(face1.getIoContext());
*
* // Now the following ensures that events on both faces are processed
* face1.processEvents();
* // or face1.getIoService().run();
* // or face1.getIoContext().run();
* @endcode
*
* or
*
* @code
* boost::asio::io_service ioService;
* Face face1(ioService);
* Face face2(ioService);
*
* ioService.run();
* boost::asio::io_context ioCtx;
* Face face1(ioCtx);
* Face face2(ioCtx);
* ioCtx.run();
* @endcode
*
* @param ioService A reference to boost::io_service object that should control all
* IO operations.
* @param ioCtx A reference to the io_context object that should control all I/O operations.
* @throw ConfigFile::Error the configuration file cannot be parsed or specifies an unsupported protocol
*/
explicit
Face(boost::asio::io_service& ioService);
Face(boost::asio::io_context& ioCtx);
/**
* @brief Create Face using TcpTransport
* @brief Create Face using TcpTransport.
*
* @param host IP address or hostname of the NDN forwarder
* @param port port number or service name of the NDN forwarder (**default**: "6363")
@@ -172,7 +170,7 @@ public: // constructors
Face(const std::string& host, const std::string& port = "6363");
/**
* @brief Create Face using given transport and KeyChain
* @brief Create Face using the given Transport and KeyChain.
* @param transport the transport for lower layer communication. If nullptr,
* a default transport will be used.
* @param keyChain the KeyChain to sign commands
@@ -186,35 +184,35 @@ public: // constructors
Face(shared_ptr<Transport> transport, KeyChain& keyChain);
/**
* @brief Create Face using given transport and io_service
* @brief Create Face using the given Transport and io_context.
* @param transport the transport for lower layer communication. If nullptr,
* a default transport will be used.
* @param ioService the io_service that controls all IO operations
* @param ioCtx the io_context that controls all I/O operations
*
* @sa Face(boost::asio::io_service&)
* @sa Face(boost::asio::io_context&)
* @sa Face(shared_ptr<Transport>)
*
* @throw ConfigFile::Error @p transport is nullptr, and the configuration file cannot be
* parsed or specifies an unsupported protocol
* @note shared_ptr is passed by value because ownership is shared with this class
*/
Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService);
Face(shared_ptr<Transport> transport, boost::asio::io_context& ioCtx);
/**
* @brief Create a new Face using given Transport and io_service
* @brief Create Face using the given Transport, io_context, and KeyChain.
* @param transport the transport for lower layer communication. If nullptr,
* a default transport will be used.
* @param ioService the io_service that controls all IO operations
* @param ioCtx the io_context that controls all I/O operations
* @param keyChain the KeyChain to sign commands
*
* @sa Face(boost::asio::io_service&)
* @sa Face(boost::asio::io_context&)
* @sa Face(shared_ptr<Transport>, KeyChain&)
*
* @throw ConfigFile::Error @p transport is nullptr, and the configuration file cannot be
* parsed or specifies an unsupported protocol
* @note shared_ptr is passed by value because ownership is shared with this class
*/
Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain);
Face(shared_ptr<Transport> transport, boost::asio::io_context& ioCtx, KeyChain& keyChain);
virtual
~Face();
@@ -228,8 +226,8 @@ public: // consumer
* @param afterNacked function to be invoked if Network NACK is returned
* @param afterTimeout function to be invoked if neither Data nor Network NACK
* is returned within InterestLifetime
* @throw OversizedPacketError encoded Interest size exceeds MAX_NDN_PACKET_SIZE
* @return A handle for canceling the pending Interest.
* @throw OversizedPacketError Encoded Interest size exceeds #MAX_NDN_PACKET_SIZE.
*/
PendingInterestHandle
expressInterest(const Interest& interest,
@@ -343,61 +341,62 @@ public: // producer
/**
* @brief Publish a Data packet.
* @param data the Data; a copy will be made, so that the caller is not required to
* maintain the argument unchanged
* @param data The Data packet; a copy will be made, so that the caller is not required to
* maintain the argument unchanged.
*
* This method can be called to satisfy incoming Interests, or to add Data packet into the cache
* of the local NDN forwarder if forwarder is configured to accept unsolicited Data.
*
* @throw OversizedPacketError encoded Data size exceeds MAX_NDN_PACKET_SIZE
* @throw OversizedPacketError Encoded Data size exceeds #MAX_NDN_PACKET_SIZE.
*/
void
put(Data data);
put(const Data& data);
/**
* @brief Send a %Network Nack.
* @param nack the Nack; a copy will be made, so that the caller is not required to
* maintain the argument unchanged
* @throw OversizedPacketError encoded Nack size exceeds MAX_NDN_PACKET_SIZE
* @param nack The Nack packet; a copy will be made, so that the caller is not required to
* maintain the argument unchanged.
* @throw OversizedPacketError Encoded Nack size exceeds #MAX_NDN_PACKET_SIZE.
*/
void
put(lp::Nack nack);
put(const lp::Nack& nack);
public: // IO routine
public: // event loop routines
/**
* @brief Process any data to receive or call timeout callbacks.
* @brief Run the event loop to process any pending work and execute completion handlers.
*
* This call will block forever (with the default timeout of 0) to process I/O on the face.
* This call will block forever (with the default @p timeout of 0) to process I/O on the face.
* To exit cleanly on a producer, clear any Interest filters and wait for processEvents() to
* return. To exit after an error, one can call shutdown().
* In consumer applications, processEvents() will return when all expressed Interests have been
* satisfied, Nacked, or timed out. To terminate earlier, a consumer application should cancel
* all previously expressed and still-pending Interests.
*
* If a positive timeout is specified, then processEvents() will exit after this timeout, provided
* it is not stopped earlier with shutdown() or when all active events finish. processEvents()
* can be called repeatedly, if desired.
* If @p timeout is a positive value, then processEvents() will return after the specified
* duration has elapsed, unless the event loop is stopped earlier with shutdown() or runs
* out of work to do.
*
* If a negative timeout is specified, then processEvents will not block and will process only
* pending events.
* If a negative @p timeout is specified, then processEvents() will not block and will process
* only handlers that are ready to run.
*
* @param timeout maximum time to block the thread
* @param keepThread Keep thread in a blocked state (in event processing), even when
* processEvents() can be called repeatedly, if desired.
*
* @param timeout Maximum amount of time to block the event loop (see above).
* @param keepRunning Keep thread in a blocked state (in event processing), even when
* there are no outstanding events (e.g., no Interest/Data is expected).
* If timeout is zero and this parameter is true, the only way to stop
* processEvents() is to call shutdown().
* Ignored if @p timeout is negative. If @p timeout is 0 and @p keepRunning
* is true, the only way to stop processEvents() is to call shutdown().
*
* @note This may throw an exception for reading data or in the callback for processing
* the data. If you call this from an main event loop, you may want to catch and
* log/disregard all exceptions.
*
* @throw OversizedPacketError encoded packet size exceeds MAX_NDN_PACKET_SIZE
* @throw OversizedPacketError Encoded packet size exceeds #MAX_NDN_PACKET_SIZE.
*/
void
processEvents(time::milliseconds timeout = time::milliseconds::zero(),
bool keepThread = false)
processEvents(time::milliseconds timeout = 0_ms, bool keepRunning = false)
{
this->doProcessEvents(timeout, keepThread);
this->doProcessEvents(timeout, keepRunning);
}
/**
@@ -405,8 +404,8 @@ public: // IO routine
*
* This method cancels all pending operations and closes the connection to the NDN forwarder.
*
* Note that this method does not stop the io_service if it is shared between multiple Faces or
* with other IO objects (e.g., Scheduler).
* Note that this method does not stop the io_context if it is shared between multiple Faces or
* with other I/O objects (e.g., Scheduler).
*
* @warning Calling this method may cause outgoing packets to be lost. Producers that shut down
* immediately after sending a Data packet should instead clear all Interest filters to
@@ -417,35 +416,39 @@ public: // IO routine
shutdown();
/**
* @brief Returns a reference to the io_service used by this face.
* @brief Returns a reference to the io_context used by this face.
*/
boost::asio::io_service&
getIoService()
boost::asio::io_context&
getIoContext() const noexcept
{
return m_ioService;
return m_ioCtx;
}
/**
* @deprecated Use getIoContext()
*/
[[deprecated("use getIoContext")]]
boost::asio::io_context&
getIoService() const noexcept
{
return m_ioCtx;
}
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
/**
* @brief Returns the underlying transport.
*/
shared_ptr<Transport>
Transport&
getTransport() const
{
return m_transport;
return *m_transport;
}
protected:
virtual void
doProcessEvents(time::milliseconds timeout, bool keepThread);
doProcessEvents(time::milliseconds timeout, bool keepRunning);
private:
/**
* @throw ConfigFile::Error on parse error and unsupported protocols
*/
shared_ptr<Transport>
makeDefaultTransport();
/**
* @throw Face::Error on unsupported protocol
*/
@@ -456,10 +459,10 @@ private:
onReceiveElement(const Block& blockFromDaemon);
private:
/// the io_service owned by this Face, may be null
unique_ptr<boost::asio::io_service> m_internalIoService;
/// the io_service used by this Face
boost::asio::io_service& m_ioService;
/// The io_context owned by this Face, may be null if using an externally provided io_context.
unique_ptr<boost::asio::io_context> m_internalIoCtx;
/// The io_context used by this Face.
boost::asio::io_context& m_ioCtx;
shared_ptr<Transport> m_transport;
+24 -21
View File
@@ -31,12 +31,16 @@
#include "ndn-cxx/lp/tags.hpp"
#include "ndn-cxx/mgmt/nfd/command-options.hpp"
#include "ndn-cxx/mgmt/nfd/controller.hpp"
#include "ndn-cxx/transport/tcp-transport.hpp"
#include "ndn-cxx/transport/unix-transport.hpp"
#include "ndn-cxx/transport/transport.hpp"
#include "ndn-cxx/util/logger.hpp"
#include "ndn-cxx/util/scheduler.hpp"
NDN_LOG_INIT(ndn.Face);
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
namespace ndn {
//
// INFO level: prefix registration, etc.
//
// DEBUG level: packet logging.
@@ -49,17 +53,18 @@ NDN_LOG_INIT(ndn.Face);
// DEBUG level.
//
// TRACE level: more detailed unstructured messages.
//
NDN_LOG_INIT(ndn.Face);
namespace ndn {
/** @brief Implementation detail of Face.
/**
* @brief Implementation detail of Face.
*/
class Face::Impl : public std::enable_shared_from_this<Face::Impl>
{
public:
Impl(Face& face, KeyChain& keyChain)
: m_face(face)
, m_scheduler(m_face.getIoService())
, m_scheduler(m_face.getIoContext())
, m_nfdController(m_face, keyChain)
{
auto onEmptyPitOrNoRegisteredPrefixes = [this] {
@@ -67,10 +72,10 @@ public:
// (+async_read) from within onInterest/onData callback. After onInterest/onData
// finishes, there is another +async_read with the same memory block. A few of such
// async_read duplications can cause various effects and result in segfault.
m_face.getIoService().post([this] {
boost::asio::post(m_face.getIoContext(), [this] {
if (m_pendingInterestTable.empty() && m_registeredPrefixTable.empty()) {
m_face.m_transport->pause();
if (!m_ioServiceWork) {
if (!m_workGuard) {
m_processEventsTimeoutEvent.cancel();
}
}
@@ -108,9 +113,8 @@ public: // consumer
void
asyncRemovePendingInterest(detail::RecordId id)
{
m_face.getIoService().post([id, w = weak_from_this()] {
auto impl = w.lock();
if (impl != nullptr) {
boost::asio::post(m_face.getIoContext(), [id, w = weak_from_this()] {
if (auto impl = w.lock(); impl != nullptr) {
impl->m_pendingInterestTable.erase(id);
}
});
@@ -194,9 +198,8 @@ public: // producer
void
asyncUnsetInterestFilter(detail::RecordId id)
{
m_face.getIoService().post([id, w = weak_from_this()] {
auto impl = w.lock();
if (impl != nullptr) {
boost::asio::post(m_face.getIoContext(), [id, w = weak_from_this()] {
if (auto impl = w.lock(); impl != nullptr) {
impl->unsetInterestFilter(id);
}
});
@@ -293,9 +296,8 @@ public: // prefix registration
const UnregisterPrefixSuccessCallback& onSuccess,
const UnregisterPrefixFailureCallback& onFailure)
{
m_face.getIoService().post([=, w = weak_from_this()] {
auto impl = w.lock();
if (impl != nullptr) {
boost::asio::post(m_face.getIoContext(), [=, w = weak_from_this()] {
if (auto impl = w.lock(); impl != nullptr) {
impl->unregisterPrefix(id, onSuccess, onFailure);
}
});
@@ -306,7 +308,7 @@ public: // IO routine
ensureConnected(bool wantResume)
{
if (m_face.m_transport->getState() == Transport::State::CLOSED) {
m_face.m_transport->connect(m_face.getIoService(),
m_face.m_transport->connect(m_face.getIoContext(),
[this] (const Block& wire) { m_face.onReceiveElement(wire); });
}
@@ -318,7 +320,7 @@ public: // IO routine
void
shutdown()
{
m_ioServiceWork.reset();
m_workGuard.reset();
m_pendingInterestTable.clear();
m_registeredPrefixTable.clear();
}
@@ -417,7 +419,8 @@ private:
detail::RecordContainer<InterestFilterRecord> m_interestFilterTable;
detail::RecordContainer<RegisteredPrefix> m_registeredPrefixTable;
unique_ptr<boost::asio::io_service::work> m_ioServiceWork; // if thread needs to be preserved
using IoContextWorkGuard = boost::asio::executor_work_guard<boost::asio::io_context::executor_type>;
unique_ptr<IoContextWorkGuard> m_workGuard;
friend Face;
};
+5 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2018 Regents of the University of California.
* Copyright (c) 2013-2023 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -28,8 +28,8 @@ InMemoryStorageFifo::InMemoryStorageFifo(size_t limit)
{
}
InMemoryStorageFifo::InMemoryStorageFifo(boost::asio::io_service& ioService, size_t limit)
: InMemoryStorage(ioService, limit)
InMemoryStorageFifo::InMemoryStorageFifo(boost::asio::io_context& ioCtx, size_t limit)
: InMemoryStorage(ioCtx, limit)
{
}
@@ -44,7 +44,7 @@ bool
InMemoryStorageFifo::evictItem()
{
if (!m_cleanupIndex.get<byArrival>().empty()) {
CleanupIndex::index<byArrival>::type::iterator it = m_cleanupIndex.get<byArrival>().begin();
auto it = m_cleanupIndex.get<byArrival>().begin();
eraseImpl((*it)->getFullName());
m_cleanupIndex.get<byArrival>().erase(it);
return true;
@@ -56,7 +56,7 @@ InMemoryStorageFifo::evictItem()
void
InMemoryStorageFifo::beforeErase(InMemoryStorageEntry* entry)
{
CleanupIndex::index<byEntity>::type::iterator it = m_cleanupIndex.get<byEntity>().find(entry);
auto it = m_cleanupIndex.get<byEntity>().find(entry);
if (it != m_cleanupIndex.get<byEntity>().end())
m_cleanupIndex.get<byEntity>().erase(it);
}
+3 -2
View File
@@ -30,7 +30,8 @@
namespace ndn {
/** @brief Provides in-memory storage employing First-In-First-Out (FIFO) replacement policy.
/**
* @brief Provides in-memory storage employing First-In-First-Out (FIFO) replacement policy.
*/
class InMemoryStorageFifo : public InMemoryStorage
{
@@ -39,7 +40,7 @@ public:
InMemoryStorageFifo(size_t limit = 16);
explicit
InMemoryStorageFifo(boost::asio::io_service& ioService, size_t limit = 16);
InMemoryStorageFifo(boost::asio::io_context& ioCtx, size_t limit = 16);
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
/** @brief Removes one Data packet from in-memory storage based on FIFO
+6 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2018 Regents of the University of California.
* Copyright (c) 2013-2023 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -28,8 +28,8 @@ InMemoryStorageLfu::InMemoryStorageLfu(size_t limit)
{
}
InMemoryStorageLfu::InMemoryStorageLfu(boost::asio::io_service& ioService, size_t limit)
: InMemoryStorage(ioService, limit)
InMemoryStorageLfu::InMemoryStorageLfu(boost::asio::io_context& ioCtx, size_t limit)
: InMemoryStorage(ioCtx, limit)
{
}
@@ -47,7 +47,7 @@ bool
InMemoryStorageLfu::evictItem()
{
if (!m_cleanupIndex.get<byFrequency>().empty()) {
CleanupIndex::index<byFrequency>::type::iterator it = m_cleanupIndex.get<byFrequency>().begin();
auto it = m_cleanupIndex.get<byFrequency>().begin();
eraseImpl(((*it).entry)->getFullName());
m_cleanupIndex.get<byFrequency>().erase(it);
return true;
@@ -59,7 +59,7 @@ InMemoryStorageLfu::evictItem()
void
InMemoryStorageLfu::beforeErase(InMemoryStorageEntry* entry)
{
CleanupIndex::index<byEntity>::type::iterator it = m_cleanupIndex.get<byEntity>().find(entry);
auto it = m_cleanupIndex.get<byEntity>().find(entry);
if (it != m_cleanupIndex.get<byEntity>().end())
m_cleanupIndex.get<byEntity>().erase(it);
}
@@ -67,7 +67,7 @@ InMemoryStorageLfu::beforeErase(InMemoryStorageEntry* entry)
void
InMemoryStorageLfu::afterAccess(InMemoryStorageEntry* entry)
{
CleanupIndex::index<byEntity>::type::iterator it = m_cleanupIndex.get<byEntity>().find(entry);
auto it = m_cleanupIndex.get<byEntity>().find(entry);
m_cleanupIndex.get<byEntity>().modify(it, &incrementFrequency);
}
+4 -4
View File
@@ -32,9 +32,9 @@
namespace ndn {
/** @brief Provides an in-memory storage with Least Frequently Used (LFU) replacement policy.
* @note The frequency right now is usage count.
* @sa https://en.wikipedia.org/w/index.php?title=Least_frequently_used&oldid=604542656
/**
* @brief Provides an in-memory storage with Least Frequently Used (LFU) replacement policy.
* @note The frequency right now is usage count.
*/
class InMemoryStorageLfu : public InMemoryStorage
{
@@ -43,7 +43,7 @@ public:
InMemoryStorageLfu(size_t limit = 16);
explicit
InMemoryStorageLfu(boost::asio::io_service& ioService, size_t limit = 16);
InMemoryStorageLfu(boost::asio::io_context& ioCtx, size_t limit = 16);
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
/** @brief Removes one Data packet from in-memory storage based on LFU, i.e. evict the least
+5 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2018 Regents of the University of California.
* Copyright (c) 2013-2023 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -28,9 +28,8 @@ InMemoryStorageLru::InMemoryStorageLru(size_t limit)
{
}
InMemoryStorageLru::InMemoryStorageLru(boost::asio::io_service& ioService,
size_t limit)
: InMemoryStorage(ioService, limit)
InMemoryStorageLru::InMemoryStorageLru(boost::asio::io_context& ioCtx, size_t limit)
: InMemoryStorage(ioCtx, limit)
{
}
@@ -46,7 +45,7 @@ bool
InMemoryStorageLru::evictItem()
{
if (!m_cleanupIndex.get<byUsedTime>().empty()) {
CleanupIndex::index<byUsedTime>::type::iterator it = m_cleanupIndex.get<byUsedTime>().begin();
auto it = m_cleanupIndex.get<byUsedTime>().begin();
eraseImpl((*it)->getFullName());
m_cleanupIndex.get<byUsedTime>().erase(it);
return true;
@@ -58,7 +57,7 @@ InMemoryStorageLru::evictItem()
void
InMemoryStorageLru::beforeErase(InMemoryStorageEntry* entry)
{
CleanupIndex::index<byEntity>::type::iterator it = m_cleanupIndex.get<byEntity>().find(entry);
auto it = m_cleanupIndex.get<byEntity>().find(entry);
if (it != m_cleanupIndex.get<byEntity>().end())
m_cleanupIndex.get<byEntity>().erase(it);
}
+3 -2
View File
@@ -32,7 +32,8 @@
namespace ndn {
/** @brief Provides in-memory storage employing Least Recently Used (LRU) replacement policy.
/**
* @brief Provides in-memory storage employing Least Recently Used (LRU) replacement policy.
*/
class InMemoryStorageLru : public InMemoryStorage
{
@@ -41,7 +42,7 @@ public:
InMemoryStorageLru(size_t limit = 16);
explicit
InMemoryStorageLru(boost::asio::io_service& ioService, size_t limit = 16);
InMemoryStorageLru(boost::asio::io_context& ioCtx, size_t limit = 16);
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
/** @brief Removes one Data packet from in-memory storage based on LRU, i.e. evict the least
@@ -1,42 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "ndn-cxx/ims/in-memory-storage-persistent.hpp"
namespace ndn {
InMemoryStoragePersistent::InMemoryStoragePersistent()
: InMemoryStorage()
{
}
InMemoryStoragePersistent::InMemoryStoragePersistent(boost::asio::io_service& ioService)
: InMemoryStorage(ioService)
{
}
bool
InMemoryStoragePersistent::evictItem()
{
return false;
}
} // namespace ndn
+16 -10
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2021 Regents of the University of California.
* Copyright (c) 2013-2023 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -26,26 +26,32 @@
namespace ndn {
/** @brief Provides application cache with persistent storage, of which no replacement policy will
* be employed. Entries will only be deleted by explicit application control.
/**
* @brief Provides application cache with persistent storage, of which no replacement policy will
* be employed. Entries will only be deleted by explicit application control.
*/
class InMemoryStoragePersistent : public InMemoryStorage
{
public:
InMemoryStoragePersistent();
InMemoryStoragePersistent() = default;
explicit
InMemoryStoragePersistent(boost::asio::io_service& ioService);
InMemoryStoragePersistent(boost::asio::io_context& ioCtx)
: InMemoryStorage(ioCtx)
{
}
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
/** @brief Do nothing.
/**
* @brief Do nothing.
*
* This storage is persistent, and does not support eviction.
*
* @return false
* This storage is persistent, and thus does not support eviction.
*/
bool
evictItem() override;
evictItem() override
{
return false;
}
};
} // namespace ndn
+2 -2
View File
@@ -47,11 +47,11 @@ InMemoryStorage::InMemoryStorage(size_t limit)
init();
}
InMemoryStorage::InMemoryStorage(boost::asio::io_service& ioService, size_t limit)
InMemoryStorage::InMemoryStorage(boost::asio::io_context& ioCtx, size_t limit)
: m_limit(limit)
, m_nPackets(0)
{
m_scheduler = make_unique<Scheduler>(ioService);
m_scheduler = make_unique<Scheduler>(ioCtx);
init();
}
+1 -1
View File
@@ -117,7 +117,7 @@ public:
* The InMemoryStorage created through this method will handle MustBeFresh in interest processing
*/
explicit
InMemoryStorage(boost::asio::io_service& ioService,
InMemoryStorage(boost::asio::io_context& ioCtx,
size_t limit = std::numeric_limits<size_t>::max());
/** @note Please make sure to implement it to free m_freeEntries and evict
+1 -1
View File
@@ -47,7 +47,7 @@ Dispatcher::Dispatcher(Face& face, KeyChain& keyChain,
: m_face(face)
, m_keyChain(keyChain)
, m_signingInfo(signingInfo)
, m_storage(m_face.getIoService(), imsCapacity)
, m_storage(m_face.getIoContext(), imsCapacity)
{
}
+25 -58
View File
@@ -22,7 +22,6 @@
#include "ndn-cxx/net/dns.hpp"
#include "ndn-cxx/util/scheduler.hpp"
#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/udp.hpp>
#include <boost/asio/post.hpp>
@@ -31,22 +30,17 @@ namespace ndn::dns {
class Resolver : noncopyable
{
public:
using protocol = boost::asio::ip::udp;
using iterator = protocol::resolver::iterator;
using query = protocol::resolver::query;
public:
Resolver(boost::asio::io_service& ioService,
Resolver(boost::asio::io_context& ioCtx,
const AddressSelector& addressSelector)
: m_resolver(ioService)
: m_resolver(ioCtx)
, m_addressSelector(addressSelector)
, m_scheduler(ioService)
, m_scheduler(ioCtx)
{
BOOST_ASSERT(m_addressSelector != nullptr);
}
void
asyncResolve(const query& q,
asyncResolve(const std::string& host,
const SuccessCallback& onSuccess,
const ErrorCallback& onError,
time::nanoseconds timeout,
@@ -55,23 +49,18 @@ public:
m_onSuccess = onSuccess;
m_onError = onError;
m_resolver.async_resolve(q, [=] (auto&&... args) {
m_resolver.async_resolve(host, "", [=] (auto&&... args) {
onResolveResult(std::forward<decltype(args)>(args)..., self);
});
m_resolveTimeout = m_scheduler.schedule(timeout, [=] { onResolveTimeout(self); });
}
iterator
syncResolve(const query& q)
{
return selectAddress(m_resolver.resolve(q));
}
private:
void
onResolveResult(const boost::system::error_code& error,
iterator it, const shared_ptr<Resolver>& self)
const boost::asio::ip::udp::resolver::results_type& results,
const shared_ptr<Resolver>& self)
{
m_resolveTimeout.cancel();
@@ -79,21 +68,22 @@ private:
boost::asio::post(m_resolver.get_executor(), [self] {});
if (error) {
if (error == boost::asio::error::operation_aborted)
return;
if (m_onError)
m_onError("Hostname cannot be resolved: " + error.message());
if (m_onError && error != boost::asio::error::operation_aborted) {
m_onError("Hostname could not be resolved: " + error.message());
}
return;
}
it = selectAddress(it);
if (it != iterator() && m_onSuccess) {
m_onSuccess(it->endpoint().address());
for (const auto& entry : results) {
if (m_addressSelector(entry.endpoint().address())) {
if (m_onSuccess) {
m_onSuccess(entry.endpoint().address());
}
return;
}
}
else if (m_onError) {
if (m_onError) {
m_onError("No endpoints match the specified address selector");
}
}
@@ -106,21 +96,13 @@ private:
// ensure the Resolver isn't destructed while callbacks are still pending, see #2653
boost::asio::post(m_resolver.get_executor(), [self] {});
if (m_onError)
if (m_onError) {
m_onError("Hostname resolution timed out");
}
iterator
selectAddress(iterator it) const
{
while (it != iterator() && !m_addressSelector(it->endpoint().address())) {
++it;
}
return it;
}
private:
protocol::resolver m_resolver;
boost::asio::ip::udp::resolver m_resolver;
AddressSelector m_addressSelector;
SuccessCallback m_onSuccess;
@@ -134,28 +116,13 @@ void
asyncResolve(const std::string& host,
const SuccessCallback& onSuccess,
const ErrorCallback& onError,
boost::asio::io_service& ioService,
boost::asio::io_context& ioCtx,
const AddressSelector& addressSelector,
time::nanoseconds timeout)
{
auto resolver = make_shared<Resolver>(ioService, addressSelector);
resolver->asyncResolve(Resolver::query(host, ""), onSuccess, onError, timeout, resolver);
// resolver will be destroyed when async operation finishes or ioService stops
}
IpAddress
syncResolve(const std::string& host,
boost::asio::io_service& ioService,
const AddressSelector& addressSelector)
{
Resolver resolver(ioService, addressSelector);
auto it = resolver.syncResolve(Resolver::query(host, ""));
if (it == Resolver::iterator()) {
NDN_THROW(Error("No endpoints match the specified address selector"));
}
return it->endpoint().address();
auto resolver = make_shared<Resolver>(ioCtx, addressSelector);
resolver->asyncResolve(host, onSuccess, onError, timeout, resolver);
// resolver will be destroyed when async operation finishes or ioCtx stops
}
} // namespace ndn::dns
+10 -32
View File
@@ -29,13 +29,12 @@
namespace ndn::dns {
using IpAddress = boost::asio::ip::address;
using AddressSelector = std::function<bool(const IpAddress&)>;
using AddressSelector = std::function<bool(const boost::asio::ip::address&)>;
struct AnyAddress
{
bool
operator()(const IpAddress& address) const
operator()(const boost::asio::ip::address&) const
{
return true;
}
@@ -44,7 +43,7 @@ struct AnyAddress
struct Ipv4Only
{
bool
operator()(const IpAddress& address) const
operator()(const boost::asio::ip::address& address) const
{
return address.is_v4();
}
@@ -53,22 +52,17 @@ struct Ipv4Only
struct Ipv6Only
{
bool
operator()(const IpAddress& address) const
operator()(const boost::asio::ip::address& address) const
{
return address.is_v6();
}
};
class Error : public std::runtime_error
{
public:
using std::runtime_error::runtime_error;
};
using SuccessCallback = std::function<void(const IpAddress& address)>;
using SuccessCallback = std::function<void(const boost::asio::ip::address& address)>;
using ErrorCallback = std::function<void(const std::string& reason)>;
/** \brief Asynchronously resolve host
/**
* \brief Asynchronously resolve \p host.
*
* If an address selector predicate is specified, then each resolved IP address
* is checked against the predicate.
@@ -80,34 +74,18 @@ using ErrorCallback = std::function<void(const std::string& reason)>;
* - dns::Ipv6Address()
*
* \warning Even after the DNS resolution has timed out, it's possible that
* \p ioService keeps running and \p onSuccess is invoked at a later time.
* \p ioCtx keeps running and \p onSuccess is invoked at a later time.
* This could cause segmentation fault if \p onSuccess is deallocated.
* To stop the io_service, explicitly invoke \p ioService.stop().
* To stop the io_context, explicitly invoke \p ioCtx.stop().
*/
void
asyncResolve(const std::string& host,
const SuccessCallback& onSuccess,
const ErrorCallback& onError,
boost::asio::io_service& ioService,
boost::asio::io_context& ioCtx,
const AddressSelector& addressSelector = AnyAddress(),
time::nanoseconds timeout = 4_s);
/** \brief Synchronously resolve host
*
* If an address selector predicate is specified, then each resolved IP address
* is checked against the predicate.
*
* Available address selector predicates:
*
* - dns::AnyAddress()
* - dns::Ipv4Address()
* - dns::Ipv6Address()
*/
IpAddress
syncResolve(const std::string& host,
boost::asio::io_service& ioService,
const AddressSelector& addressSelector = AnyAddress());
} // namespace ndn::dns
#endif // NDN_CXX_NET_DNS_HPP
+11 -11
View File
@@ -220,7 +220,7 @@ public:
canonize(const FaceUri& faceUri,
const FaceUri::CanonizeSuccessCallback& onSuccess,
const FaceUri::CanonizeFailureCallback& onFailure,
boost::asio::io_service& io, time::nanoseconds timeout) const = 0;
boost::asio::io_context& io, time::nanoseconds timeout) const = 0;
};
template<typename Protocol>
@@ -244,7 +244,7 @@ public:
}
boost::system::error_code ec;
auto addr = boost::asio::ip::address::from_string(unescapeHost(faceUri.getHost()), ec);
auto addr = boost::asio::ip::make_address(unescapeHost(faceUri.getHost()), ec);
if (ec) {
return false;
}
@@ -287,7 +287,7 @@ public:
canonize(const FaceUri& faceUri,
const FaceUri::CanonizeSuccessCallback& onSuccess,
const FaceUri::CanonizeFailureCallback& onFailure,
boost::asio::io_service& io, time::nanoseconds timeout) const override
boost::asio::io_context& io, time::nanoseconds timeout) const override
{
if (this->isCanonical(faceUri)) {
onSuccess(faceUri);
@@ -297,7 +297,7 @@ public:
// make a copy because caller may modify faceUri
auto uri = make_shared<FaceUri>(faceUri);
boost::system::error_code ec;
auto ipAddress = boost::asio::ip::address::from_string(unescapeHost(faceUri.getHost()), ec);
auto ipAddress = boost::asio::ip::make_address(unescapeHost(faceUri.getHost()), ec);
if (!ec) {
// No need to resolve IP address if host is already an IP
if ((faceUri.getScheme() == m_v4Scheme && !ipAddress.is_v4()) ||
@@ -345,7 +345,7 @@ private:
onDnsSuccess(const shared_ptr<FaceUri>& faceUri,
const FaceUri::CanonizeSuccessCallback& onSuccess,
const FaceUri::CanonizeFailureCallback& onFailure,
const dns::IpAddress& ipAddress) const
const boost::asio::ip::address& ipAddress) const
{
auto [isOk, reason] = this->checkAddress(ipAddress);
if (!isOk) {
@@ -383,7 +383,7 @@ private:
* (false,reason) if the address is not allowable.
*/
virtual std::pair<bool, std::string>
checkAddress(const dns::IpAddress&) const
checkAddress(const boost::asio::ip::address&) const
{
return {true, ""};
}
@@ -425,7 +425,7 @@ public:
protected:
std::pair<bool, std::string>
checkAddress(const dns::IpAddress& ipAddress) const override
checkAddress(const boost::asio::ip::address& ipAddress) const override
{
if (ipAddress.is_multicast()) {
return {false, "cannot use multicast address"};
@@ -461,7 +461,7 @@ public:
canonize(const FaceUri& faceUri,
const FaceUri::CanonizeSuccessCallback& onSuccess,
const FaceUri::CanonizeFailureCallback& onFailure,
boost::asio::io_service&, time::nanoseconds timeout) const override
boost::asio::io_context&, time::nanoseconds timeout) const override
{
auto addr = ethernet::Address::fromString(faceUri.getHost());
if (addr.isNull()) {
@@ -493,7 +493,7 @@ public:
canonize(const FaceUri& faceUri,
const FaceUri::CanonizeSuccessCallback& onSuccess,
const FaceUri::CanonizeFailureCallback& onFailure,
boost::asio::io_service&, time::nanoseconds timeout) const override
boost::asio::io_context&, time::nanoseconds timeout) const override
{
if (faceUri.getHost().empty()) {
onFailure("network interface name is missing");
@@ -539,7 +539,7 @@ public:
canonize(const FaceUri& faceUri,
const FaceUri::CanonizeSuccessCallback& onSuccess,
const FaceUri::CanonizeFailureCallback& onFailure,
boost::asio::io_service&, time::nanoseconds timeout) const override
boost::asio::io_context&, time::nanoseconds timeout) const override
{
if (this->isCanonical(faceUri)) {
onSuccess(faceUri);
@@ -618,7 +618,7 @@ FaceUri::isCanonical() const
void
FaceUri::canonize(const CanonizeSuccessCallback& onSuccess,
const CanonizeFailureCallback& onFailure,
boost::asio::io_service& io, time::nanoseconds timeout) const
boost::asio::io_context& io, time::nanoseconds timeout) const
{
const CanonizeProvider* cp = getCanonizeProvider(this->getScheme());
if (cp == nullptr) {
+2 -2
View File
@@ -167,7 +167,7 @@ public: // canonical FaceUri
*
* \param onSuccess function to call after this FaceUri is converted to canonical form
* \param onFailure function to call if this FaceUri cannot be converted to canonical form
* \param io reference to `boost::asio::io_service` instance
* \param io reference to `boost::asio::io_context` instance
* \param timeout maximum allowable duration of the operations.
* It's intentional not to provide a default value: the caller should set
* a reasonable value in balance between network delay and user experience.
@@ -175,7 +175,7 @@ public: // canonical FaceUri
void
canonize(const CanonizeSuccessCallback& onSuccess,
const CanonizeFailureCallback& onFailure,
boost::asio::io_service& io,
boost::asio::io_context& io,
time::nanoseconds timeout) const;
private:
+3 -3
View File
@@ -86,7 +86,7 @@ private:
int m_value;
};
NetlinkSocket::NetlinkSocket(boost::asio::io_service& io)
NetlinkSocket::NetlinkSocket(boost::asio::io_context& io)
: m_sock(make_shared<boost::asio::generic::raw_protocol::socket>(io))
, m_pid(0)
, m_seqNum(static_cast<uint32_t>(time::system_clock::now().time_since_epoch().count()))
@@ -340,7 +340,7 @@ NetlinkSocket::receiveAndValidate()
}
}
RtnlSocket::RtnlSocket(boost::asio::io_service& io)
RtnlSocket::RtnlSocket(boost::asio::io_context& io)
: NetlinkSocket(io)
{
}
@@ -409,7 +409,7 @@ RtnlSocket::nlmsgTypeToString(uint16_t type) const
#undef RTM_STRINGIFY
}
GenlSocket::GenlSocket(boost::asio::io_service& io)
GenlSocket::GenlSocket(boost::asio::io_context& io)
: NetlinkSocket(io)
{
m_cachedFamilyIds["nlctrl"] = GENL_ID_CTRL;
+3 -3
View File
@@ -53,7 +53,7 @@ public:
protected:
explicit
NetlinkSocket(boost::asio::io_service& io);
NetlinkSocket(boost::asio::io_context& io);
~NetlinkSocket();
@@ -87,7 +87,7 @@ class RtnlSocket final : public NetlinkSocket
{
public:
explicit
RtnlSocket(boost::asio::io_service& io);
RtnlSocket(boost::asio::io_context& io);
void
open();
@@ -128,7 +128,7 @@ class GenlSocket final : public NetlinkSocket
{
public:
explicit
GenlSocket(boost::asio::io_service& io);
GenlSocket(boost::asio::io_context& io);
void
open();
@@ -43,7 +43,7 @@ namespace ndn::net {
NDN_LOG_INIT(ndn.NetworkMonitor);
NetworkMonitorImplNetlink::NetworkMonitorImplNetlink(boost::asio::io_service& io)
NetworkMonitorImplNetlink::NetworkMonitorImplNetlink(boost::asio::io_context& io)
: m_rtnlSocket(io)
, m_genlSocket(io)
{
@@ -44,7 +44,7 @@ public:
* \brief Initialize netlink socket and start enumerating interfaces.
*/
explicit
NetworkMonitorImplNetlink(boost::asio::io_service& io);
NetworkMonitorImplNetlink(boost::asio::io_context& io);
uint32_t
getCapabilities() const final
@@ -32,7 +32,7 @@ class NetworkMonitorImplNoop final : public NetworkMonitorImpl
{
public:
explicit
NetworkMonitorImplNoop(boost::asio::io_service&)
NetworkMonitorImplNoop(boost::asio::io_context&)
{
}
@@ -62,9 +62,9 @@
#include <net/if_types.h> // for IFT_* constants
#include <netinet/in.h> // for struct sockaddr_in{,6}
#include <boost/asio/io_service.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/udp.hpp>
#include <boost/asio/post.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
@@ -101,7 +101,7 @@ private:
ifaddrs* m_ifaList = nullptr;
};
NetworkMonitorImplOsx::NetworkMonitorImplOsx(boost::asio::io_service& io)
NetworkMonitorImplOsx::NetworkMonitorImplOsx(boost::asio::io_context& io)
: m_scheduler(io)
, m_context{0, this, nullptr, nullptr, nullptr}
, m_scStore(SCDynamicStoreCreate(nullptr, CFSTR("net.named-data.ndn-cxx.NetworkMonitor"),
@@ -142,7 +142,7 @@ NetworkMonitorImplOsx::NetworkMonitorImplOsx(boost::asio::io_service& io)
NDN_THROW(Error("SCDynamicStoreSetNotificationKeys failed"));
}
io.post([this] { enumerateInterfaces(); });
boost::asio::post(io, [this] { enumerateInterfaces(); });
}
NetworkMonitorImplOsx::~NetworkMonitorImplOsx()
@@ -386,7 +386,7 @@ NetworkMonitorImplOsx::updateInterfaceInfo(NetworkInterface& netif, const IfAddr
if (ipAddr.is_loopback()) {
scope = AddressScope::HOST;
}
else if ((ipAddr.is_v4() && (ipAddr.to_v4().to_ulong() & 0xFFFF0000) == 0xA9FE0000) ||
else if ((ipAddr.is_v4() && (ipAddr.to_v4().to_uint() & 0xFFFF0000) == 0xA9FE0000) ||
(ipAddr.is_v6() && ipAddr.to_v6().is_link_local())) {
scope = AddressScope::LINK;
}
@@ -45,7 +45,7 @@ class IfAddrs;
class NetworkMonitorImplOsx final : public NetworkMonitorImpl
{
public:
NetworkMonitorImplOsx(boost::asio::io_service& io);
NetworkMonitorImplOsx(boost::asio::io_context& io);
~NetworkMonitorImplOsx() final;
+2 -2
View File
@@ -42,7 +42,7 @@ namespace ndn::net {
NDN_LOG_INIT(ndn.NetworkMonitor);
static unique_ptr<NetworkMonitorImpl>
makeNetworkMonitorImpl(boost::asio::io_service& io)
makeNetworkMonitorImpl(boost::asio::io_context& io)
{
try {
return make_unique<NETWORK_MONITOR_IMPL_TYPE>(io);
@@ -54,7 +54,7 @@ makeNetworkMonitorImpl(boost::asio::io_service& io)
}
}
NetworkMonitor::NetworkMonitor(boost::asio::io_service& io)
NetworkMonitor::NetworkMonitor(boost::asio::io_context& io)
: NetworkMonitor(makeNetworkMonitorImpl(io))
{
}
+2 -2
View File
@@ -60,10 +60,10 @@ public:
/**
* @brief Construct instance, request enumeration of all network interfaces, and start
* monitoring for network state changes.
* @param io io_service instance that will dispatch events
* @param ioCtx io_context instance that will dispatch events
*/
explicit
NetworkMonitor(boost::asio::io_service& io);
NetworkMonitor(boost::asio::io_context& ioCtx);
enum Capability : uint32_t {
/// NetworkMonitor is not supported and is a no-op
@@ -67,7 +67,7 @@ CertificateBundleFetcher::doFetch(const shared_ptr<CertificateRequest>& certRequ
const shared_ptr<ValidationState>& state,
const ValidationContinuation& continueValidation)
{
auto dataValidationState = dynamic_pointer_cast<DataValidationState>(state);
auto dataValidationState = std::dynamic_pointer_cast<DataValidationState>(state);
if (dataValidationState == nullptr) {
return m_inner->fetch(certRequest, state, continueValidation);
}
@@ -45,7 +45,7 @@ CertificateFetcherDirectFetch::doFetch(const shared_ptr<CertificateRequest>& key
const ValidationContinuation& continueValidation)
{
uint64_t incomingFaceId = 0;
auto interestState = dynamic_pointer_cast<InterestValidationState>(state);
auto interestState = std::dynamic_pointer_cast<InterestValidationState>(state);
if (interestState != nullptr) {
auto incomingFaceIdTag = interestState->getOriginalInterest().getTag<lp::IncomingFaceIdTag>();
if (incomingFaceIdTag != nullptr) {
@@ -53,7 +53,7 @@ CertificateFetcherDirectFetch::doFetch(const shared_ptr<CertificateRequest>& key
}
}
else {
auto dataState = dynamic_pointer_cast<DataValidationState>(state);
auto dataState = std::dynamic_pointer_cast<DataValidationState>(state);
auto incomingFaceIdTag = dataState->getOriginalData().getTag<lp::IncomingFaceIdTag>();
if (incomingFaceIdTag != nullptr) {
incomingFaceId = incomingFaceIdTag->get();
@@ -35,7 +35,7 @@ NDN_LOG_INIT(ndn.security.CertificateFetcher);
CertificateFetcherFromNetwork::CertificateFetcherFromNetwork(Face& face)
: m_face(face)
, m_scheduler(face.getIoService())
, m_scheduler(face.getIoContext())
{
}
@@ -146,7 +146,7 @@ ValidationPolicyCommandInterest::checkTimestamp(const shared_ptr<ValidationState
}
}
auto interestState = dynamic_pointer_cast<InterestValidationState>(state);
auto interestState = std::dynamic_pointer_cast<InterestValidationState>(state);
BOOST_ASSERT(interestState != nullptr);
interestState->afterSuccess.connect([=] (const Interest&) { insertNewRecord(keyName, timestamp); });
return true;
@@ -129,7 +129,7 @@ ValidationPolicySignedInterest::checkIncomingInterest(const shared_ptr<Validatio
}
if (m_options.maxRecordCount != 0) {
auto interestState = dynamic_pointer_cast<InterestValidationState>(state);
auto interestState = std::dynamic_pointer_cast<InterestValidationState>(state);
BOOST_ASSERT(interestState != nullptr);
interestState->afterSuccess.connect([=] (const Interest&) {
insertRecord(keyName, timestamp, seqNum, nonce);
@@ -44,10 +44,10 @@ public:
using Impl = StreamTransportImpl<BaseTransport, Protocol>;
using TransmissionQueue = std::queue<Block, std::list<Block>>;
StreamTransportImpl(BaseTransport& transport, boost::asio::io_service& ioService)
StreamTransportImpl(BaseTransport& transport, boost::asio::io_context& ioCtx)
: m_transport(transport)
, m_socket(ioService)
, m_connectTimer(ioService)
, m_socket(ioCtx)
, m_connectTimer(ioCtx)
{
}
@@ -61,7 +61,7 @@ public:
// Wait at most 4 seconds to connect
/// @todo Decide whether this number should be configurable
m_connectTimer.expires_from_now(std::chrono::seconds(4));
m_connectTimer.expires_after(std::chrono::seconds(4));
m_connectTimer.async_wait([self = this->shared_from_this()] (const auto& error) {
self->connectTimeoutHandler(error);
});
@@ -77,8 +77,8 @@ public:
{
m_transport.setState(Transport::State::CLOSED);
m_connectTimer.cancel();
boost::system::error_code error; // to silently ignore all errors
m_connectTimer.cancel(error);
m_socket.cancel(error);
m_socket.close(error);
@@ -33,13 +33,13 @@ template<typename BaseTransport, typename Protocol>
class StreamTransportWithResolverImpl : public StreamTransportImpl<BaseTransport, Protocol>
{
public:
StreamTransportWithResolverImpl(BaseTransport& transport, boost::asio::io_service& ioService)
: StreamTransportImpl<BaseTransport, Protocol>(transport, ioService)
StreamTransportWithResolverImpl(BaseTransport& transport, boost::asio::io_context& ioCtx)
: StreamTransportImpl<BaseTransport, Protocol>(transport, ioCtx)
{
}
void
connect(const typename Protocol::resolver::query& query)
connect(std::string_view host, std::string_view port)
{
if (this->m_transport.getState() == Transport::State::CONNECTING) {
return;
@@ -48,13 +48,13 @@ public:
// Wait at most 4 seconds to connect
/// @todo Decide whether this number should be configurable
this->m_connectTimer.expires_from_now(std::chrono::seconds(4));
this->m_connectTimer.expires_after(std::chrono::seconds(4));
this->m_connectTimer.async_wait([self = this->shared_from_base()] (const auto& ec) {
self->connectTimeoutHandler(ec);
});
auto resolver = make_shared<typename Protocol::resolver>(this->m_socket.get_executor());
resolver->async_resolve(query, [self = this->shared_from_base(), resolver] (auto&&... args) {
resolver->async_resolve(host, port, [self = this->shared_from_base(), resolver] (auto&&... args) {
self->resolveHandler(std::forward<decltype(args)>(args)..., resolver);
});
}
@@ -62,23 +62,20 @@ public:
protected:
void
resolveHandler(const boost::system::error_code& error,
typename Protocol::resolver::iterator endpoint,
const typename Protocol::resolver::results_type& endpoints,
const shared_ptr<typename Protocol::resolver>&)
{
if (error) {
if (error == boost::system::errc::operation_canceled)
return;
NDN_THROW(Transport::Error(error, "Error during resolution of host or port"));
}
typename Protocol::resolver::iterator end;
if (endpoint == end) {
this->m_transport.close();
NDN_THROW(Transport::Error(error, "Unable to resolve host or port"));
NDN_THROW(Transport::Error(error, "unable to resolve host or port"));
}
this->m_socket.async_connect(*endpoint, [self = this->shared_from_base()] (const auto& ec) {
BOOST_ASSERT(!endpoints.empty()); // guaranteed by Asio if the resolve operation is successful
this->m_socket.async_connect(*endpoints.begin(), [self = this->shared_from_base()] (const auto& ec) {
self->connectHandler(ec);
});
}
@@ -89,7 +86,7 @@ private:
shared_ptr<Impl>
shared_from_base()
{
return static_pointer_cast<Impl>(this->shared_from_this());
return std::static_pointer_cast<Impl>(this->shared_from_this());
}
};
+4 -6
View File
@@ -78,17 +78,15 @@ TcpTransport::getSocketHostAndPortFromUri(const std::string& uriString)
}
void
TcpTransport::connect(boost::asio::io_service& ioService, ReceiveCallback receiveCallback)
TcpTransport::connect(boost::asio::io_context& ioCtx, ReceiveCallback receiveCallback)
{
NDN_LOG_DEBUG("connect host=" << m_host << " port=" << m_port);
if (m_impl == nullptr) {
Transport::connect(ioService, std::move(receiveCallback));
m_impl = make_shared<Impl>(*this, ioService);
Transport::connect(ioCtx, std::move(receiveCallback));
m_impl = make_shared<Impl>(*this, ioCtx);
}
boost::asio::ip::tcp::resolver::query query(m_host, m_port);
m_impl->connect(query);
m_impl->connect(m_host, m_port);
}
void
+7 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2022 Regents of the University of California.
* Copyright (c) 2013-2023 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -38,7 +38,8 @@ class StreamTransportWithResolverImpl;
} // namespace detail
/** \brief A transport using TCP socket.
/**
* \brief A transport that uses a TCP socket for communication.
*/
class TcpTransport : public Transport
{
@@ -49,7 +50,7 @@ public:
~TcpTransport() override;
void
connect(boost::asio::io_service& ioService, ReceiveCallback receiveCallback) override;
connect(boost::asio::io_context& ioCtx, ReceiveCallback receiveCallback) override;
void
close() override;
@@ -63,8 +64,9 @@ public:
void
send(const Block& wire) override;
/** \brief Create transport with parameters defined in URI.
* \throw Transport::Error incorrect URI or unsupported protocol is specified
/**
* \brief Create transport with parameters defined in URI.
* \throw Transport::Error incorrect URI or unsupported protocol is specified
*/
static shared_ptr<TcpTransport>
create(const std::string& uri);
+3 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2019 Regents of the University of California.
* Copyright (c) 2013-2023 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -29,11 +29,11 @@ Transport::Error::Error(const boost::system::error_code& code, const std::string
}
void
Transport::connect(boost::asio::io_service& ioService, ReceiveCallback receiveCallback)
Transport::connect(boost::asio::io_context& ioCtx, ReceiveCallback receiveCallback)
{
BOOST_ASSERT(receiveCallback != nullptr);
m_ioService = &ioService;
m_ioCtx = &ioCtx;
m_receiveCallback = std::move(receiveCallback);
}
+4 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2022 Regents of the University of California.
* Copyright (c) 2013-2023 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -59,12 +59,12 @@ public:
/**
* \brief Asynchronously open the connection.
* \param ioService io_service to create socket on
* \param ioCtx io_context to create socket on
* \param receiveCallback callback function when a TLV block is received; must not be empty
* \throw boost::system::system_error connection cannot be established
*/
virtual void
connect(boost::asio::io_service& ioService, ReceiveCallback receiveCallback);
connect(boost::asio::io_context& ioCtx, ReceiveCallback receiveCallback);
/**
* \brief Close the connection.
@@ -113,7 +113,7 @@ protected:
}
protected:
boost::asio::io_service* m_ioService = nullptr;
boost::asio::io_context* m_ioCtx = nullptr;
ReceiveCallback m_receiveCallback;
private:
+3 -3
View File
@@ -76,13 +76,13 @@ UnixTransport::create(const std::string& uri)
}
void
UnixTransport::connect(boost::asio::io_service& ioService, ReceiveCallback receiveCallback)
UnixTransport::connect(boost::asio::io_context& ioCtx, ReceiveCallback receiveCallback)
{
NDN_LOG_DEBUG("connect path=" << m_unixSocket);
if (m_impl == nullptr) {
Transport::connect(ioService, std::move(receiveCallback));
m_impl = make_shared<Impl>(*this, ioService);
Transport::connect(ioCtx, std::move(receiveCallback));
m_impl = make_shared<Impl>(*this, ioCtx);
}
m_impl->connect(boost::asio::local::stream_protocol::endpoint(m_unixSocket));
+7 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2022 Regents of the University of California.
* Copyright (c) 2013-2023 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -35,7 +35,8 @@ class StreamTransportImpl;
} // namespace detail
/** \brief A transport using Unix stream socket.
/**
* \brief A transport that uses a Unix stream socket for communication.
*/
class UnixTransport : public Transport
{
@@ -46,7 +47,7 @@ public:
~UnixTransport() override;
void
connect(boost::asio::io_service& ioService, ReceiveCallback receiveCallback) override;
connect(boost::asio::io_context& ioCtx, ReceiveCallback receiveCallback) override;
void
close() override;
@@ -60,8 +61,9 @@ public:
void
send(const Block& wire) override;
/** \brief Create transport with parameters defined in URI.
* \throw Transport::Error incorrect URI or unsupported protocol is specified
/**
* \brief Create transport with parameters defined in URI.
* \throw Transport::Error incorrect URI or unsupported protocol is specified
*/
static shared_ptr<UnixTransport>
create(const std::string& uri);
+17 -15
View File
@@ -20,6 +20,7 @@
*/
#include "ndn-cxx/util/dummy-client-face.hpp"
#include "ndn-cxx/impl/lp-field-tag.hpp"
#include "ndn-cxx/lp/packet.hpp"
#include "ndn-cxx/lp/tags.hpp"
@@ -27,7 +28,8 @@
#include "ndn-cxx/mgmt/nfd/control-response.hpp"
#include "ndn-cxx/transport/transport.hpp"
#include <boost/asio/io_service.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
namespace ndn {
@@ -93,16 +95,16 @@ DummyClientFace::DummyClientFace(KeyChain& keyChain, const Options& options)
this->construct(options);
}
DummyClientFace::DummyClientFace(boost::asio::io_service& ioService, const Options& options)
: Face(make_shared<DummyClientFace::Transport>(), ioService)
DummyClientFace::DummyClientFace(boost::asio::io_context& ioCtx, const Options& options)
: Face(make_shared<DummyClientFace::Transport>(), ioCtx)
, m_internalKeyChain(make_unique<KeyChain>())
, m_keyChain(*m_internalKeyChain)
{
this->construct(options);
}
DummyClientFace::DummyClientFace(boost::asio::io_service& ioService, KeyChain& keyChain, const Options& options)
: Face(make_shared<DummyClientFace::Transport>(), ioService, keyChain)
DummyClientFace::DummyClientFace(boost::asio::io_context& ioCtx, KeyChain& keyChain, const Options& options)
: Face(make_shared<DummyClientFace::Transport>(), ioCtx, keyChain)
, m_keyChain(keyChain)
{
this->construct(options);
@@ -116,7 +118,7 @@ DummyClientFace::~DummyClientFace()
void
DummyClientFace::construct(const Options& options)
{
static_pointer_cast<Transport>(getTransport())->onSendBlock.connect([this] (Block packet) {
static_cast<Transport&>(getTransport()).onSendBlock.connect([this] (Block packet) {
packet.encode();
lp::Packet lpPacket(packet);
auto frag = lpPacket.get<lp::FragmentField>();
@@ -145,10 +147,10 @@ DummyClientFace::construct(const Options& options)
});
if (options.enablePacketLogging)
this->enablePacketLogging();
enablePacketLogging();
if (options.enableRegistrationReply)
this->enableRegistrationReply(options.registrationReplyFaceId);
enableRegistrationReply(options.registrationReplyFaceId);
m_processEventsOverride = options.processEventsOverride;
@@ -226,10 +228,10 @@ DummyClientFace::enableRegistrationReply(uint64_t faceId)
resp.setCode(200);
resp.setBody(params.wireEncode());
shared_ptr<Data> data = make_shared<Data>(name);
auto data = make_shared<Data>(name);
data->setContent(resp.wireEncode());
m_keyChain.sign(*data, security::SigningInfo(security::SigningInfo::SIGNER_TYPE_SHA256));
this->getIoService().post([this, data] { this->receive(*data); });
boost::asio::post(getIoContext(), [this, data] { this->receive(*data); });
});
}
@@ -242,7 +244,7 @@ DummyClientFace::receive(const Interest& interest)
addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, interest);
addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, interest);
static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode());
static_cast<Transport&>(getTransport()).receive(lpPacket.wireEncode());
}
void
@@ -253,7 +255,7 @@ DummyClientFace::receive(const Data& data)
addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, data);
addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, data);
static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode());
static_cast<Transport&>(getTransport()).receive(lpPacket.wireEncode());
}
void
@@ -267,7 +269,7 @@ DummyClientFace::receive(const lp::Nack& nack)
addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, nack);
addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, nack);
static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode());
static_cast<Transport&>(getTransport()).receive(lpPacket.wireEncode());
}
void
@@ -313,13 +315,13 @@ DummyClientFace::unlink()
}
void
DummyClientFace::doProcessEvents(time::milliseconds timeout, bool keepThread)
DummyClientFace::doProcessEvents(time::milliseconds timeout, bool keepRunning)
{
if (m_processEventsOverride != nullptr) {
m_processEventsOverride(timeout);
}
else {
this->Face::doProcessEvents(timeout, keepThread);
Face::doProcessEvents(timeout, keepRunning);
}
}
+7 -7
View File
@@ -83,24 +83,24 @@ public:
AlreadyLinkedError();
};
/** \brief Create a dummy face with internal IO service.
/** \brief Create a dummy face with internal I/O context.
*/
explicit
DummyClientFace(const Options& options = Options());
/** \brief Create a dummy face with internal IO service and the specified KeyChain.
/** \brief Create a dummy face with internal I/O context and the specified KeyChain.
*/
explicit
DummyClientFace(KeyChain& keyChain, const Options& options = Options());
/** \brief Create a dummy face with the provided IO service.
/** \brief Create a dummy face with the provided I/O context.
*/
explicit
DummyClientFace(boost::asio::io_service& ioService, const Options& options = Options());
DummyClientFace(boost::asio::io_context& ioCtx, const Options& options = Options());
/** \brief Create a dummy face with the provided IO service and the specified KeyChain.
/** \brief Create a dummy face with the provided I/O context and the specified KeyChain.
*/
DummyClientFace(boost::asio::io_service& ioService, KeyChain& keyChain,
DummyClientFace(boost::asio::io_context& ioCtx, KeyChain& keyChain,
const Options& options = Options());
~DummyClientFace() override;
@@ -146,7 +146,7 @@ private:
enableRegistrationReply(uint64_t faceId);
void
doProcessEvents(time::milliseconds timeout, bool keepThread) override;
doProcessEvents(time::milliseconds timeout, bool keepRunning) override;
public:
/** \brief Interests sent out of this DummyClientFace.
+1 -1
View File
@@ -40,7 +40,7 @@ NotificationSubscriberBase::NotificationSubscriberBase(Face& face, const Name& p
, m_lastSequenceNum(std::numeric_limits<uint64_t>::max())
, m_lastNackSequenceNum(std::numeric_limits<uint64_t>::max())
, m_attempts(1)
, m_scheduler(face.getIoService())
, m_scheduler(face.getIoContext())
, m_interestLifetime(interestLifetime)
{
}
+12 -19
View File
@@ -25,27 +25,20 @@
namespace ndn::scheduler {
/** \brief Stores internal information about a scheduled event
/**
* \brief Stores internal information about a scheduled event.
*/
class EventInfo : noncopyable
struct EventInfo : noncopyable
{
public:
EventInfo(time::nanoseconds after, EventCallback&& cb)
: callback(std::move(cb))
, expireTime(time::steady_clock::now() + after)
: expiry(time::steady_clock::now() + after)
, callback(std::move(cb))
{
}
[[nodiscard]] time::nanoseconds
expiresFromNow() const
{
return std::max(expireTime - time::steady_clock::now(), 0_ns);
}
public:
time::steady_clock::time_point expiry;
EventCallback callback;
Scheduler::EventQueue::const_iterator queueIt;
time::steady_clock::time_point expireTime;
bool isExpired = false;
};
@@ -71,11 +64,11 @@ bool
Scheduler::EventQueueCompare::operator()(const shared_ptr<EventInfo>& a,
const shared_ptr<EventInfo>& b) const noexcept
{
return a->expireTime < b->expireTime;
return a->expiry < b->expiry;
}
Scheduler::Scheduler(boost::asio::io_service& ioService)
: m_timer(make_unique<detail::SteadyTimer>(ioService))
Scheduler::Scheduler(boost::asio::io_context& ioCtx)
: m_timer(make_unique<detail::SteadyTimer>(ioCtx))
{
}
@@ -125,8 +118,8 @@ void
Scheduler::scheduleNext()
{
if (!m_queue.empty()) {
m_timer->expires_from_now((*m_queue.begin())->expiresFromNow());
m_timer->async_wait([this] (const auto& error) { this->executeEvent(error); });
m_timer->expires_at((*m_queue.begin())->expiry);
m_timer->async_wait([this] (const auto& error) { executeEvent(error); });
}
}
@@ -148,7 +141,7 @@ Scheduler::executeEvent(const boost::system::error_code& error)
while (!m_queue.empty()) {
auto head = m_queue.begin();
shared_ptr<EventInfo> info = *head;
if (info->expireTime > now) {
if (info->expiry > now) {
break;
}
+5 -4
View File
@@ -40,7 +40,7 @@ class SteadyTimer;
namespace scheduler {
class Scheduler;
class EventInfo;
struct EventInfo;
/** \brief Function to be invoked when a scheduled event expires
*/
@@ -130,13 +130,14 @@ private:
*/
using ScopedEventId = detail::ScopedCancelHandle<EventId>;
/** \brief Generic time-based scheduler
/**
* \brief Generic time-based event scheduler.
*/
class Scheduler : noncopyable
{
public:
explicit
Scheduler(boost::asio::io_service& ioService);
Scheduler(boost::asio::io_context& ioCtx);
~Scheduler();
@@ -162,7 +163,7 @@ private:
/** \brief Execute expired events
*
* If an event callback throws, the exception is propagated to the thread running the io_service.
* If an event callback throws, the exception is propagated to the thread running the io_context.
* In case there are other expired events, they will be processed in the next invocation.
*/
void
+4 -3
View File
@@ -27,7 +27,8 @@
#include "ndn-cxx/lp/nack.hpp"
#include "ndn-cxx/lp/nack-header.hpp"
#include <boost/asio/io_service.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/range/adaptor/map.hpp>
@@ -61,7 +62,7 @@ SegmentFetcher::SegmentFetcher(Face& face,
const SegmentFetcher::Options& options)
: m_options(options)
, m_face(face)
, m_scheduler(m_face.getIoService())
, m_scheduler(m_face.getIoContext())
, m_validator(validator)
, m_rttEstimator(make_shared<util::RttEstimator::Options>(options.rttOptions))
, m_timeLastSegmentReceived(time::steady_clock::now())
@@ -91,7 +92,7 @@ SegmentFetcher::stop()
}
m_pendingSegments.clear(); // cancels pending Interests and timeout events
m_face.getIoService().post([self = std::move(m_this)] {});
boost::asio::post(m_face.getIoContext(), [self = std::move(m_this)] {});
}
bool
+3 -3
View File
@@ -25,14 +25,14 @@
#include "ndn-cxx/util/scheduler.hpp"
#include "tests/benchmarks/timed-execute.hpp"
#include <boost/asio/io_service.hpp>
#include <boost/asio/io_context.hpp>
#include <iostream>
namespace ndn::tests {
BOOST_AUTO_TEST_CASE(ScheduleCancel)
{
boost::asio::io_service io;
boost::asio::io_context io;
Scheduler sched(io);
const size_t nEvents = 1000000;
@@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE(ScheduleCancel)
BOOST_AUTO_TEST_CASE(Execute)
{
boost::asio::io_service io;
boost::asio::io_context io;
Scheduler sched(io);
const size_t nEvents = 1000000;
+4 -4
View File
@@ -68,7 +68,7 @@ class FaceFixture : public KeyChainFixture
protected:
FaceFixture()
: face(TransportType::create(""), m_keyChain)
, sched(face.getIoService())
, sched(face.getIoContext())
{
}
@@ -82,7 +82,7 @@ protected:
sendInterest(time::nanoseconds delay, const Interest& interest, char& outcome)
{
if (face2 == nullptr) {
face2 = make_unique<Face>(TransportType::create(""), face.getIoService(), m_keyChain);
face2 = make_unique<Face>(TransportType::create(""), face.getIoContext(), m_keyChain);
}
outcome = '?';
@@ -101,13 +101,13 @@ protected:
return sendInterest(delay, interest, ignoredOutcome);
}
/** \brief Stop io_service after a delay
/** \brief Stop io_context after a delay
* \return scheduled event id
*/
scheduler::EventId
terminateAfter(time::nanoseconds delay)
{
return sched.schedule(delay, [this] { face.getIoService().stop(); });
return sched.schedule(delay, [this] { face.getIoContext().stop(); });
}
protected:
+2 -2
View File
@@ -30,7 +30,7 @@
#include "ndn-cxx/util/string-helper.hpp"
#include "ndn-cxx/util/time.hpp"
#include <boost/asio/io_service.hpp>
#include <boost/asio/io_context.hpp>
#include <iostream>
namespace ndn::tests {
@@ -48,7 +48,7 @@ logEvent(const shared_ptr<const NetworkInterface>& ni = nullptr, std::ostream& o
BOOST_AUTO_TEST_CASE(Signals)
{
boost::asio::io_service io;
boost::asio::io_context io;
NetworkMonitor monitor(io);
std::cout << "capabilities=" << AsHex{monitor.getCapabilities()} << std::endl;
+2 -2
View File
@@ -649,8 +649,8 @@ BOOST_AUTO_TEST_CASE(ToAsioConstBuffer)
{
Block block = "0101A0"_block;
boost::asio::const_buffer buffer(block);
BOOST_CHECK_EQUAL(boost::asio::buffer_cast<const uint8_t*>(buffer), block.data());
BOOST_CHECK_EQUAL(boost::asio::buffer_size(buffer), block.size());
BOOST_CHECK_EQUAL(buffer.data(), block.data());
BOOST_CHECK_EQUAL(buffer.size(), block.size());
}
BOOST_AUTO_TEST_CASE(Equality)
+109 -107
View File
@@ -96,8 +96,8 @@ BOOST_AUTO_TEST_CASE(ReplyData)
BOOST_CHECK_EQUAL(i.getName(), "/Hello/World");
++nData;
},
std::bind([] { BOOST_FAIL("Unexpected Nack"); }),
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected Nack"); },
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
advanceClocks(40_ms);
@@ -112,9 +112,9 @@ BOOST_AUTO_TEST_CASE(ReplyData)
size_t nTimeouts = 0;
face.expressInterest(*makeInterest("/Hello/World/a/2", false, 50_ms),
std::bind([]{}),
std::bind([]{}),
std::bind([&nTimeouts] { ++nTimeouts; }));
[] (auto&&...) {},
[] (auto&&...) {},
[&] (auto&&...) { ++nTimeouts; });
advanceClocks(200_ms, 5);
BOOST_CHECK_EQUAL(nTimeouts, 1);
}
@@ -124,14 +124,14 @@ BOOST_AUTO_TEST_CASE(MultipleData)
size_t nData = 0;
face.expressInterest(*makeInterest("/Hello/World", true, 50_ms),
[&] (const auto&, const auto&) { ++nData; },
std::bind([] { BOOST_FAIL("Unexpected Nack"); }),
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[&] (auto&&...) { ++nData; },
[] (auto&&...) { BOOST_FAIL("Unexpected Nack"); },
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
face.expressInterest(*makeInterest("/Hello/World/a", true, 50_ms),
[&] (const auto&, const auto&) { ++nData; },
std::bind([] { BOOST_FAIL("Unexpected Nack"); }),
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[&] (auto&&...) { ++nData; },
[] (auto&&...) { BOOST_FAIL("Unexpected Nack"); },
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
advanceClocks(40_ms);
@@ -148,8 +148,8 @@ BOOST_AUTO_TEST_CASE(EmptyDataCallback)
{
face.expressInterest(*makeInterest("/Hello/World", true),
nullptr,
std::bind([] { BOOST_FAIL("Unexpected Nack"); }),
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected Nack"); },
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
advanceClocks(1_ms);
BOOST_CHECK_NO_THROW(do {
@@ -162,13 +162,12 @@ BOOST_AUTO_TEST_CASE(Timeout)
{
size_t nTimeouts = 0;
face.expressInterest(*makeInterest("/Hello/World", false, 50_ms),
std::bind([] { BOOST_FAIL("Unexpected Data"); }),
std::bind([] { BOOST_FAIL("Unexpected Nack"); }),
[] (auto&&...) { BOOST_FAIL("Unexpected Data"); },
[] (auto&&...) { BOOST_FAIL("Unexpected Nack"); },
[&nTimeouts] (const Interest& i) {
BOOST_CHECK_EQUAL(i.getName(), "/Hello/World");
++nTimeouts;
});
advanceClocks(200_ms, 5);
BOOST_CHECK_EQUAL(nTimeouts, 1);
@@ -180,8 +179,8 @@ BOOST_AUTO_TEST_CASE(Timeout)
BOOST_AUTO_TEST_CASE(EmptyTimeoutCallback)
{
face.expressInterest(*makeInterest("/Hello/World", false, 50_ms),
std::bind([] { BOOST_FAIL("Unexpected Data"); }),
std::bind([] { BOOST_FAIL("Unexpected Nack"); }),
[] (auto&&...) { BOOST_FAIL("Unexpected Data"); },
[] (auto&&...) { BOOST_FAIL("Unexpected Nack"); },
nullptr);
advanceClocks(40_ms);
@@ -195,16 +194,15 @@ BOOST_AUTO_TEST_CASE(ReplyNack)
size_t nNacks = 0;
auto interest = makeInterest("/Hello/World", false, 50_ms);
face.expressInterest(*interest,
std::bind([] { BOOST_FAIL("Unexpected Data"); }),
[] (auto&&...) { BOOST_FAIL("Unexpected Data"); },
[&] (const Interest& i, const lp::Nack& n) {
BOOST_CHECK(i.getName().isPrefixOf(n.getInterest().getName()));
BOOST_CHECK_EQUAL(i.getName(), "/Hello/World");
BOOST_CHECK_EQUAL(n.getReason(), lp::NackReason::DUPLICATE);
++nNacks;
},
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
advanceClocks(40_ms);
@@ -222,15 +220,15 @@ BOOST_AUTO_TEST_CASE(MultipleNacks)
auto interest = makeInterest("/Hello/World", false, 50_ms, 1);
face.expressInterest(*interest,
std::bind([] { BOOST_FAIL("Unexpected Data"); }),
[] (auto&&...) { BOOST_FAIL("Unexpected Data"); },
[&] (const auto&, const auto&) { ++nNacks; },
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
interest->setNonce(2);
face.expressInterest(*interest,
std::bind([] { BOOST_FAIL("Unexpected Data"); }),
[] (auto&&...) { BOOST_FAIL("Unexpected Data"); },
[&] (const auto&, const auto&) { ++nNacks; },
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
advanceClocks(40_ms);
@@ -245,9 +243,9 @@ BOOST_AUTO_TEST_CASE(MultipleNacks)
BOOST_AUTO_TEST_CASE(EmptyNackCallback)
{
face.expressInterest(*makeInterest("/Hello/World"),
std::bind([] { BOOST_FAIL("Unexpected Data"); }),
[] (auto&&...) { BOOST_FAIL("Unexpected Data"); },
nullptr,
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
advanceClocks(1_ms);
BOOST_CHECK_NO_THROW(do {
@@ -259,7 +257,7 @@ BOOST_AUTO_TEST_CASE(EmptyNackCallback)
BOOST_AUTO_TEST_CASE(PutDataFromDataCallback) // Bug 4596
{
face.expressInterest(*makeInterest("/localhost/notification/1"),
[&] (const auto&, const auto&) {
[&] (auto&&...) {
face.put(*makeData("/chronosync/sampleDigest/1"));
}, nullptr, nullptr);
advanceClocks(10_ms);
@@ -290,9 +288,9 @@ BOOST_AUTO_TEST_CASE(DestroyWithPendingInterest)
BOOST_AUTO_TEST_CASE(Handle)
{
auto hdl = face.expressInterest(*makeInterest("/Hello/World", true, 50_ms),
std::bind([] { BOOST_FAIL("Unexpected data"); }),
std::bind([] { BOOST_FAIL("Unexpected nack"); }),
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected data"); },
[] (auto&&...) { BOOST_FAIL("Unexpected nack"); },
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
advanceClocks(1_ms);
hdl.cancel();
advanceClocks(1_ms);
@@ -302,9 +300,9 @@ BOOST_AUTO_TEST_CASE(Handle)
// cancel after destructing face
auto face2 = make_unique<DummyClientFace>(m_io, m_keyChain);
auto hdl2 = face2->expressInterest(*makeInterest("/Hello/World", true, 50_ms),
std::bind([] { BOOST_FAIL("Unexpected data"); }),
std::bind([] { BOOST_FAIL("Unexpected nack"); }),
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected data"); },
[] (auto&&...) { BOOST_FAIL("Unexpected nack"); },
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
advanceClocks(1_ms);
face2.reset();
advanceClocks(1_ms);
@@ -320,14 +318,14 @@ BOOST_AUTO_TEST_SUITE_END() // ExpressInterest
BOOST_AUTO_TEST_CASE(RemoveAllPendingInterests)
{
face.expressInterest(*makeInterest("/Hello/World/0", false, 50_ms),
std::bind([] { BOOST_FAIL("Unexpected data"); }),
std::bind([] { BOOST_FAIL("Unexpected nack"); }),
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected data"); },
[] (auto&&...) { BOOST_FAIL("Unexpected nack"); },
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
face.expressInterest(*makeInterest("/Hello/World/1", false, 50_ms),
std::bind([] { BOOST_FAIL("Unexpected data"); }),
std::bind([] { BOOST_FAIL("Unexpected nack"); }),
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected data"); },
[] (auto&&...) { BOOST_FAIL("Unexpected nack"); },
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
advanceClocks(10_ms);
@@ -370,18 +368,19 @@ BOOST_AUTO_TEST_CASE(PutDataLoopback)
bool hasInterest1 = false, hasData = false;
// first InterestFilter allows loopback and should receive Interest
face.setInterestFilter("/", [&] (const InterestFilter&, const Interest&) {
face.setInterestFilter("/", [&] (auto&&...) {
hasInterest1 = true;
// do not respond with Data right away, so Face must send Interest to forwarder
});
// second InterestFilter disallows loopback and should not receive Interest
face.setInterestFilter(InterestFilter("/").allowLoopback(false),
std::bind([] { BOOST_ERROR("Unexpected Interest on second InterestFilter"); }));
[] (auto&&...) { BOOST_ERROR("Unexpected Interest on second InterestFilter"); });
face.expressInterest(*makeInterest("/A", true),
std::bind([&] { hasData = true; }),
std::bind([] { BOOST_FAIL("Unexpected nack"); }),
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[&] (auto&&...) { hasData = true; },
[] (auto&&...) { BOOST_FAIL("Unexpected nack"); },
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
advanceClocks(1_ms);
BOOST_CHECK_EQUAL(hasInterest1, true); // Interest looped back
BOOST_CHECK_EQUAL(face.sentInterests.size(), 1); // Interest sent to forwarder
@@ -397,12 +396,12 @@ BOOST_AUTO_TEST_CASE(PutMultipleData)
{
bool hasInterest1 = false;
// register two Interest destinations
face.setInterestFilter("/", std::bind([&] {
face.setInterestFilter("/", [&] (auto&&...) {
hasInterest1 = true;
// sending Data right away from the first destination, don't care whether Interest goes to second destination
face.put(*makeData("/A/B"));
}));
face.setInterestFilter("/", std::bind([]{}));
});
face.setInterestFilter("/", [] (auto&&...) {});
advanceClocks(10_ms);
face.receive(*makeInterest("/A", true));
@@ -417,7 +416,8 @@ BOOST_AUTO_TEST_CASE(PutMultipleData)
BOOST_AUTO_TEST_CASE(PutNack)
{
face.setInterestFilter("/", std::bind([]{})); // register one Interest destination so that face can accept Nacks
// register one Interest destination so that face can accept Nacks
face.setInterestFilter("/", [] (auto&&...) {});
advanceClocks(10_ms);
BOOST_CHECK_EQUAL(face.sentNacks.size(), 0);
@@ -457,7 +457,7 @@ BOOST_AUTO_TEST_CASE(PutMultipleNack)
// sending Nack right away from the first destination, Interest should still go to second destination
face.put(makeNack(interest, lp::NackReason::CONGESTION));
});
face.setInterestFilter("/", std::bind([&] { hasInterest2 = true; }));
face.setInterestFilter("/", [&] (auto&&...) { hasInterest2 = true; });
advanceClocks(10_ms);
auto interest = makeInterest("/A", false, std::nullopt, 14333271);
@@ -487,18 +487,19 @@ BOOST_AUTO_TEST_CASE(PutMultipleNackLoopback)
hasInterest1 = true;
face.put(makeNack(interest, lp::NackReason::CONGESTION));
});
// second InterestFilter disallows loopback and should not receive Interest
face.setInterestFilter(InterestFilter("/").allowLoopback(false),
std::bind([] { BOOST_ERROR("Unexpected Interest on second InterestFilter"); }));
[] (auto&&...) { BOOST_ERROR("Unexpected Interest on second InterestFilter"); });
auto interest = makeInterest("/A", false, std::nullopt, 28395852);
face.expressInterest(*interest,
std::bind([] { BOOST_FAIL("Unexpected data"); }),
[] (auto&&...) { BOOST_FAIL("Unexpected data"); },
[&] (const Interest&, const lp::Nack& nack) {
hasNack = true;
BOOST_CHECK_EQUAL(nack.getReason(), lp::NackReason::CONGESTION);
},
std::bind([] { BOOST_FAIL("Unexpected timeout"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected timeout"); });
advanceClocks(1_ms);
BOOST_CHECK_EQUAL(hasInterest1, true); // Interest looped back
BOOST_CHECK_EQUAL(face.sentInterests.size(), 1); // Interest sent to forwarder
@@ -553,7 +554,7 @@ BOOST_AUTO_TEST_CASE(Handle)
// cancel after destructing face
auto face2 = make_unique<DummyClientFace>(m_io, m_keyChain);
hdl = face2->registerPrefix("/Hello/World/2", nullptr,
std::bind([] { BOOST_FAIL("Unexpected registerPrefix failure"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected failure"); });
advanceClocks(1_ms);
face2.reset();
advanceClocks(1_ms);
@@ -563,7 +564,7 @@ BOOST_AUTO_TEST_CASE(Handle)
// unregister after destructing face
auto face3 = make_unique<DummyClientFace>(m_io, m_keyChain);
hdl = face3->registerPrefix("/Hello/World/3", nullptr,
std::bind([] { BOOST_FAIL("Unexpected registerPrefix failure"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected failure"); });
advanceClocks(1_ms);
face3.reset();
advanceClocks(1_ms);
@@ -579,9 +580,9 @@ BOOST_AUTO_TEST_CASE(SetAndCancel)
size_t nInterests = 0;
size_t nRegs = 0;
auto hdl = face.setInterestFilter("/Hello/World",
std::bind([&nInterests] { ++nInterests; }),
std::bind([&nRegs] { ++nRegs; }),
std::bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
[&] (auto&&...) { ++nInterests; },
[&] (auto&&...) { ++nRegs; },
[] (auto&&...) { BOOST_FAIL("Unexpected failure"); });
advanceClocks(25_ms, 4);
BOOST_CHECK_EQUAL(nRegs, 1);
BOOST_CHECK_EQUAL(nInterests, 0);
@@ -623,8 +624,8 @@ BOOST_AUTO_TEST_CASE(WithoutSuccessCallback)
{
size_t nInterests = 0;
auto hdl = face.setInterestFilter("/Hello/World",
std::bind([&nInterests] { ++nInterests; }),
std::bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
[&] (auto&&...) { ++nInterests; },
[] (auto&&...) { BOOST_FAIL("Unexpected failure"); });
advanceClocks(25_ms, 4);
BOOST_CHECK_EQUAL(nInterests, 0);
@@ -654,9 +655,9 @@ BOOST_FIXTURE_TEST_CASE(Failure, FaceFixture<NoPrefixRegReply>)
// don't enable registration reply
size_t nRegFailed = 0;
face.setInterestFilter("/Hello/World",
std::bind([] { BOOST_FAIL("Unexpected Interest"); }),
std::bind([] { BOOST_FAIL("Unexpected success of setInterestFilter"); }),
std::bind([&nRegFailed] { ++nRegFailed; }));
[] (auto&&...) { BOOST_FAIL("Unexpected Interest"); },
[] (auto&&...) { BOOST_FAIL("Unexpected success"); },
[&] (auto&&...) { ++nRegFailed; });
advanceClocks(25_ms, 4);
BOOST_CHECK_EQUAL(nRegFailed, 0);
@@ -670,8 +671,8 @@ BOOST_FIXTURE_TEST_CASE(FailureWithoutSuccessCallback, FaceFixture<NoPrefixRegRe
// don't enable registration reply
size_t nRegFailed = 0;
face.setInterestFilter("/Hello/World",
std::bind([] { BOOST_FAIL("Unexpected Interest"); }),
std::bind([&nRegFailed] { ++nRegFailed; }));
[] (auto&&...) { BOOST_FAIL("Unexpected Interest"); },
[&] (auto&&...) { ++nRegFailed; });
advanceClocks(25_ms, 4);
BOOST_CHECK_EQUAL(nRegFailed, 0);
@@ -684,21 +685,21 @@ BOOST_AUTO_TEST_CASE(SimilarFilters)
{
size_t nInInterests1 = 0;
face.setInterestFilter("/Hello/World",
std::bind([&nInInterests1] { ++nInInterests1; }),
[&nInInterests1] (auto&&...) { ++nInInterests1; },
nullptr,
std::bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected failure"); });
size_t nInInterests2 = 0;
face.setInterestFilter("/Hello",
std::bind([&nInInterests2] { ++nInInterests2; }),
[&nInInterests2] (auto&&...) { ++nInInterests2; },
nullptr,
std::bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected failure"); });
size_t nInInterests3 = 0;
face.setInterestFilter("/Los/Angeles/Lakers",
std::bind([&nInInterests3] { ++nInInterests3; }),
[&nInInterests3] (auto&&...) { ++nInInterests3; },
nullptr,
std::bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected failure"); });
advanceClocks(25_ms, 4);
@@ -714,9 +715,9 @@ BOOST_AUTO_TEST_CASE(RegexFilter)
{
size_t nInInterests = 0;
face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
std::bind([&nInInterests] { ++nInInterests; }),
[&nInInterests] (auto&&...) { ++nInInterests; },
nullptr,
std::bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected failure"); });
advanceClocks(25_ms, 4);
@@ -736,11 +737,14 @@ BOOST_AUTO_TEST_CASE(RegexFilter)
BOOST_AUTO_TEST_CASE(RegexFilterError)
{
face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
// Do NOT use 'auto' for this lambda. This is testing the (failure of)
// implicit conversion from InterestFilter to Name, therefore the type
// of the first parameter must be explicit.
[] (const Name&, const Interest&) {
BOOST_FAIL("InterestFilter::Error should have been triggered");
BOOST_FAIL("InterestFilter::Error should have been raised");
},
nullptr,
std::bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
[] (auto&&...) { BOOST_FAIL("Unexpected failure"); });
advanceClocks(25_ms, 4);
@@ -751,12 +755,12 @@ BOOST_AUTO_TEST_CASE(RegexFilterAndRegisterPrefix)
{
size_t nInInterests = 0;
face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
std::bind([&nInInterests] { ++nInInterests; }));
[&] (auto&&...) { ++nInInterests; });
size_t nRegSuccesses = 0;
face.registerPrefix("/Hello/World",
std::bind([&nRegSuccesses] { ++nRegSuccesses; }),
std::bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
[&] (auto&&...) { ++nRegSuccesses; },
[] (auto&&...) { BOOST_FAIL("Unexpected failure"); });
advanceClocks(25_ms, 4);
BOOST_CHECK_EQUAL(nRegSuccesses, 1);
@@ -780,11 +784,11 @@ BOOST_FIXTURE_TEST_CASE(WithoutRegisterPrefix, FaceFixture<NoPrefixRegReply>) //
// Regular Face won't accept incoming packets until something is sent.
int hit = 0;
face.setInterestFilter(Name("/"), std::bind([&hit] { ++hit; }));
face.processEvents(time::milliseconds(-1));
face.setInterestFilter(Name("/"), [&hit] (auto&&...) { ++hit; });
face.processEvents(-1_ms);
face.receive(*makeInterest("/A"));
face.processEvents(time::milliseconds(-1));
face.processEvents(-1_ms);
BOOST_CHECK_EQUAL(hit, 1);
}
@@ -792,7 +796,7 @@ BOOST_FIXTURE_TEST_CASE(WithoutRegisterPrefix, FaceFixture<NoPrefixRegReply>) //
BOOST_AUTO_TEST_CASE(Handle)
{
int hit = 0;
InterestFilterHandle hdl = face.setInterestFilter(Name("/"), std::bind([&hit] { ++hit; }));
InterestFilterHandle hdl = face.setInterestFilter(Name("/"), [&hit] (auto&&...) { ++hit; });
face.processEvents(-1_ms);
face.receive(*makeInterest("/A"));
@@ -820,18 +824,18 @@ BOOST_AUTO_TEST_SUITE_END() // SetInterestFilter
BOOST_AUTO_TEST_CASE(ProcessEvents)
{
face.processEvents(time::milliseconds(-1)); // io_service::reset()/poll() inside
face.processEvents(-1_ms); // io_context::restart()/poll() inside
size_t nRegSuccesses = 0;
int nRegSuccesses = 0;
face.registerPrefix("/Hello/World",
std::bind([&nRegSuccesses] { ++nRegSuccesses; }),
std::bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
[&] (auto&&...) { ++nRegSuccesses; },
[] (auto&&...) { BOOST_FAIL("Unexpected failure"); });
// io_service::poll() without reset
face.getIoService().poll();
// io_context::poll() without reset
face.getIoContext().poll();
BOOST_CHECK_EQUAL(nRegSuccesses, 0);
face.processEvents(time::milliseconds(-1)); // io_service::reset()/poll() inside
face.processEvents(-1_ms); // io_context::restart()/poll() inside
BOOST_CHECK_EQUAL(nRegSuccesses, 1);
}
@@ -852,16 +856,14 @@ using ndn::Transport;
BOOST_FIXTURE_TEST_CASE(FaceTransport, IoKeyChainFixture)
{
BOOST_CHECK(Face().getTransport() != nullptr);
BOOST_CHECK(Face(shared_ptr<Transport>()).getTransport() != nullptr);
BOOST_CHECK(Face(shared_ptr<Transport>(), m_io).getTransport() != nullptr);
BOOST_CHECK(Face(shared_ptr<Transport>(), m_io, m_keyChain).getTransport() != nullptr);
BOOST_CHECK_NO_THROW(Face(shared_ptr<Transport>()));
BOOST_CHECK_NO_THROW(Face(shared_ptr<Transport>(), m_io));
BOOST_CHECK_NO_THROW(Face(shared_ptr<Transport>(), m_io, m_keyChain));
auto transport = make_shared<TcpTransport>("localhost", "6363"); // no real io operations will be scheduled
BOOST_CHECK(Face(transport).getTransport() == transport);
BOOST_CHECK(Face(transport, m_io).getTransport() == transport);
BOOST_CHECK(Face(transport, m_io, m_keyChain).getTransport() == transport);
BOOST_CHECK(&Face(transport).getTransport() == transport.get());
BOOST_CHECK(&Face(transport, m_io).getTransport() == transport.get());
BOOST_CHECK(&Face(transport, m_io, m_keyChain).getTransport() == transport.get());
}
class WithEnv
@@ -914,8 +916,8 @@ using ConfigOptions = boost::mpl::vector<WithEnv, WithConfig>;
BOOST_FIXTURE_TEST_CASE(NoConfig, WithEnvAndConfig) // fixture configures test HOME and PIB/TPM path
{
shared_ptr<Face> face;
BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
BOOST_CHECK(dynamic_pointer_cast<UnixTransport>(face->getTransport()) != nullptr);
BOOST_CHECK_NO_THROW(face = make_shared<Face>());
BOOST_CHECK(dynamic_cast<UnixTransport*>(&face->getTransport()) != nullptr);
}
BOOST_FIXTURE_TEST_CASE_TEMPLATE(Unix, T, ConfigOptions, T)
@@ -923,8 +925,8 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(Unix, T, ConfigOptions, T)
this->configure("unix://some/path");
shared_ptr<Face> face;
BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
BOOST_CHECK(dynamic_pointer_cast<UnixTransport>(face->getTransport()) != nullptr);
BOOST_CHECK_NO_THROW(face = make_shared<Face>());
BOOST_CHECK(dynamic_cast<UnixTransport*>(&face->getTransport()) != nullptr);
}
BOOST_FIXTURE_TEST_CASE_TEMPLATE(Tcp, T, ConfigOptions, T)
@@ -932,8 +934,8 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(Tcp, T, ConfigOptions, T)
this->configure("tcp://127.0.0.1:6000");
shared_ptr<Face> face;
BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
BOOST_CHECK(dynamic_pointer_cast<TcpTransport>(face->getTransport()) != nullptr);
BOOST_CHECK_NO_THROW(face = make_shared<Face>());
BOOST_CHECK(dynamic_cast<TcpTransport*>(&face->getTransport()) != nullptr);
}
BOOST_FIXTURE_TEST_CASE_TEMPLATE(WrongTransport, T, ConfigOptions, T)
@@ -956,8 +958,8 @@ BOOST_FIXTURE_TEST_CASE(EnvOverride, WithEnvAndConfig)
this->WithConfig::configure("unix://some/path");
shared_ptr<Face> face;
BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
BOOST_CHECK(dynamic_pointer_cast<TcpTransport>(face->getTransport()) != nullptr);
BOOST_CHECK_NO_THROW(face = make_shared<Face>());
BOOST_CHECK(dynamic_cast<TcpTransport*>(&face->getTransport()) != nullptr);
}
BOOST_FIXTURE_TEST_CASE(ExplicitTransport, WithEnvAndConfig)
@@ -967,8 +969,8 @@ BOOST_FIXTURE_TEST_CASE(ExplicitTransport, WithEnvAndConfig)
auto transport = make_shared<UnixTransport>("unix://some/path");
shared_ptr<Face> face;
BOOST_REQUIRE_NO_THROW(face = make_shared<Face>(transport));
BOOST_CHECK(dynamic_pointer_cast<UnixTransport>(face->getTransport()) != nullptr);
BOOST_CHECK_NO_THROW(face = make_shared<Face>(transport));
BOOST_CHECK(dynamic_cast<UnixTransport*>(&face->getTransport()) != nullptr);
}
BOOST_AUTO_TEST_SUITE_END() // Transport
+2 -2
View File
@@ -24,7 +24,7 @@
#include "tests/unit/clock-fixture.hpp"
#include <boost/asio/io_service.hpp>
#include <boost/asio/io_context.hpp>
namespace ndn::tests {
@@ -41,7 +41,7 @@ private:
}
protected:
boost::asio::io_service m_io;
boost::asio::io_context m_io;
};
} // namespace ndn::tests
+31 -42
View File
@@ -24,20 +24,19 @@
#include "tests/boost-test.hpp"
#include "tests/unit/net/network-configuration-detector.hpp"
#include <boost/asio/io_service.hpp>
#include <boost/asio/io_context.hpp>
namespace ndn::tests {
using namespace ndn::dns;
using boost::asio::ip::address_v4;
using boost::asio::ip::address_v6;
namespace ip = boost::asio::ip;
class DnsFixture
{
public:
void
onSuccess(const IpAddress& resolvedAddress,
const IpAddress& expectedAddress,
onSuccess(const boost::asio::ip::address& resolvedAddress,
const boost::asio::ip::address& expectedAddress,
bool isValid,
bool shouldCheckAddress = false)
{
@@ -66,105 +65,95 @@ public:
protected:
int m_nFailures = 0;
int m_nSuccesses = 0;
boost::asio::io_service m_ioService;
boost::asio::io_context m_ioCtx;
};
BOOST_AUTO_TEST_SUITE(Net)
BOOST_FIXTURE_TEST_SUITE(TestDns, DnsFixture)
BOOST_AUTO_TEST_CASE(Asynchronous)
BOOST_AUTO_TEST_CASE(Failure)
{
SKIP_IF_IP_UNAVAILABLE();
asyncResolve("nothost.nothost.nothost.arpa",
std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v4()), false, false),
std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v4(), false, false),
[this] (auto&&...) { onFailure(true); },
m_ioService); // should fail
m_ioCtx); // should fail
m_ioService.run();
m_ioCtx.run();
BOOST_CHECK_EQUAL(m_nFailures, 1);
BOOST_CHECK_EQUAL(m_nSuccesses, 0);
}
BOOST_AUTO_TEST_CASE(AsynchronousV4)
BOOST_AUTO_TEST_CASE(Ipv4)
{
SKIP_IF_IPV4_UNAVAILABLE();
asyncResolve("192.0.2.1",
std::bind(&DnsFixture::onSuccess, this, _1,
IpAddress(address_v4::from_string("192.0.2.1")), true, true),
std::bind(&DnsFixture::onSuccess, this, _1, ip::make_address_v4("192.0.2.1"), true, true),
[this] (auto&&...) { onFailure(false); },
m_ioService);
m_ioCtx);
m_ioService.run();
m_ioCtx.run();
BOOST_CHECK_EQUAL(m_nFailures, 0);
BOOST_CHECK_EQUAL(m_nSuccesses, 1);
}
BOOST_AUTO_TEST_CASE(AsynchronousV6)
BOOST_AUTO_TEST_CASE(Ipv6)
{
SKIP_IF_IPV6_UNAVAILABLE();
asyncResolve("ipv6.google.com", // only IPv6 address should be available
std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v6()), true, false),
std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v6(), true, false),
[this] (auto&&...) { onFailure(false); },
m_ioService);
m_ioCtx);
asyncResolve("2001:db8:3f9:0:3025:ccc5:eeeb:86d3",
std::bind(&DnsFixture::onSuccess, this, _1,
IpAddress(address_v6::from_string("2001:db8:3f9:0:3025:ccc5:eeeb:86d3")),
true, true),
ip::make_address_v6("2001:db8:3f9:0:3025:ccc5:eeeb:86d3"), true, true),
[this] (auto&&...) { onFailure(false); },
m_ioService);
m_ioCtx);
m_ioService.run();
m_ioCtx.run();
BOOST_CHECK_EQUAL(m_nFailures, 0);
BOOST_CHECK_EQUAL(m_nSuccesses, 2);
}
BOOST_AUTO_TEST_CASE(AsynchronousV4AndV6)
BOOST_AUTO_TEST_CASE(WithAddressSelector)
{
SKIP_IF_IPV4_UNAVAILABLE();
SKIP_IF_IPV6_UNAVAILABLE();
asyncResolve("named-data.net",
std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v4()), true, false),
std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v4(), true, false),
[this] (auto&&...) { onFailure(false); },
m_ioService, Ipv4Only());
m_ioCtx, Ipv4Only());
asyncResolve("a.root-servers.net",
std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v4()), true, false),
std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v4(), true, false),
[this] (auto&&...) { onFailure(false); },
m_ioService, Ipv4Only()); // request IPv4 address
m_ioCtx, Ipv4Only()); // request IPv4 address
asyncResolve("a.root-servers.net",
std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v6()), true, false),
std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v6(), true, false),
[this] (auto&&...) { onFailure(false); },
m_ioService, Ipv6Only()); // request IPv6 address
m_ioCtx, Ipv6Only()); // request IPv6 address
asyncResolve("ipv6.google.com", // only IPv6 address should be available
std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v6()), true, false),
std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v6(), true, false),
[this] (auto&&...) { onFailure(false); },
m_ioService, Ipv6Only());
m_ioCtx, Ipv6Only());
asyncResolve("ipv6.google.com", // only IPv6 address should be available
std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v6()), false, false),
std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v6(), false, false),
[this] (auto&&...) { onFailure(true); },
m_ioService, Ipv4Only()); // should fail
m_ioCtx, Ipv4Only()); // should fail
m_ioService.run();
m_ioCtx.run();
BOOST_CHECK_EQUAL(m_nFailures, 1);
BOOST_CHECK_EQUAL(m_nSuccesses, 4);
}
BOOST_AUTO_TEST_CASE(Synchronous)
{
SKIP_IF_IP_UNAVAILABLE();
IpAddress address = syncResolve("named-data.net", m_ioService);
BOOST_CHECK(address.is_v4() || address.is_v6());
}
BOOST_AUTO_TEST_SUITE_END() // TestDns
BOOST_AUTO_TEST_SUITE_END() // Net
+6 -6
View File
@@ -94,7 +94,7 @@ protected:
shared_ptr<const net::NetworkInterface> m_netif;
private:
boost::asio::io_service m_io;
boost::asio::io_context m_io;
};
BOOST_AUTO_TEST_CASE(ParseInternal)
@@ -147,11 +147,11 @@ BOOST_AUTO_TEST_CASE(ParseUdp)
namespace ip = boost::asio::ip;
ip::udp::endpoint endpoint4(ip::address_v4::from_string("192.0.2.1"), 7777);
ip::udp::endpoint endpoint4(ip::make_address_v4("192.0.2.1"), 7777);
uri = FaceUri(endpoint4);
BOOST_CHECK_EQUAL(uri.toString(), "udp4://192.0.2.1:7777");
ip::udp::endpoint endpoint6(ip::address_v6::from_string("2001:DB8::1"), 7777);
ip::udp::endpoint endpoint6(ip::make_address_v6("2001:DB8::1"), 7777);
uri = FaceUri(endpoint6);
BOOST_CHECK_EQUAL(uri.toString(), "udp6://[2001:db8::1]:7777");
@@ -285,14 +285,14 @@ BOOST_AUTO_TEST_CASE(ParseTcp)
namespace ip = boost::asio::ip;
ip::tcp::endpoint endpoint4(ip::address_v4::from_string("192.0.2.1"), 7777);
ip::tcp::endpoint endpoint4(ip::make_address_v4("192.0.2.1"), 7777);
uri = FaceUri(endpoint4);
BOOST_CHECK_EQUAL(uri.toString(), "tcp4://192.0.2.1:7777");
uri = FaceUri(endpoint4, "wsclient");
BOOST_CHECK_EQUAL(uri.toString(), "wsclient://192.0.2.1:7777");
ip::tcp::endpoint endpoint6(ip::address_v6::from_string("2001:DB8::1"), 7777);
ip::tcp::endpoint endpoint6(ip::make_address_v6("2001:DB8::1"), 7777);
uri = FaceUri(endpoint6);
BOOST_CHECK_EQUAL(uri.toString(), "tcp6://[2001:db8::1]:7777");
@@ -553,7 +553,7 @@ BOOST_FIXTURE_TEST_CASE(CanonizeUdpDev, CanonizeFixture)
BOOST_AUTO_TEST_CASE(CanonizeEmptyCallback)
{
boost::asio::io_service io;
boost::asio::io_context io;
// unsupported scheme
FaceUri("null://").canonize(nullptr, nullptr, io, 1_ms);
@@ -21,11 +21,9 @@
#include "tests/unit/net/network-configuration-detector.hpp"
#include <boost/asio/io_service.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/basic_resolver.hpp>
#include <boost/asio/ip/udp.hpp>
#include <boost/range/iterator_range_core.hpp>
namespace ndn::tests {
@@ -50,31 +48,23 @@ NetworkConfigurationDetector::hasIpv6()
void
NetworkConfigurationDetector::detect()
{
using BoostResolver = boost::asio::ip::basic_resolver<boost::asio::ip::udp>;
boost::asio::io_context io;
boost::asio::ip::udp::resolver resolver(io);
boost::asio::io_service ioService;
BoostResolver resolver(ioService);
boost::system::error_code ec;
// The specified hostname must have both A and AAAA records
auto results = resolver.resolve("a.root-servers.net", "", ec);
// The specified hostname must contain both A and AAAA records
BoostResolver::query query("a.root-servers.net", "");
boost::system::error_code errorCode;
BoostResolver::iterator begin = resolver.resolve(query, errorCode);
if (errorCode) {
s_isInitialized = true;
return;
}
BoostResolver::iterator end;
for (const auto& i : boost::make_iterator_range(begin, end)) {
if (i.endpoint().address().is_v4()) {
s_hasIpv4 = true;
}
else if (i.endpoint().address().is_v6()) {
s_hasIpv6 = true;
if (!ec) {
for (const auto& i : results) {
if (i.endpoint().address().is_v4()) {
s_hasIpv4 = true;
}
else if (i.endpoint().address().is_v6()) {
s_hasIpv6 = true;
}
}
}
s_isInitialized = true;
}
+6 -5
View File
@@ -23,7 +23,8 @@
#include "tests/boost-test.hpp"
#include <boost/asio/io_service.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
namespace ndn::tests {
@@ -42,7 +43,7 @@ BOOST_AUTO_TEST_SUITE(TestNetworkMonitor)
BOOST_AUTO_TEST_CASE(DestructWithoutRun)
{
boost::asio::io_service io;
boost::asio::io_context io;
auto nm = make_unique<NetworkMonitor>(io);
nm.reset();
BOOST_CHECK(true); // if we got this far, the test passed
@@ -50,16 +51,16 @@ BOOST_AUTO_TEST_CASE(DestructWithoutRun)
BOOST_AUTO_TEST_CASE(DestructWhileEnumerating)
{
boost::asio::io_service io;
boost::asio::io_context io;
auto nm = make_unique<NetworkMonitor>(io);
NM_REQUIRE_CAP(ENUM);
nm->onInterfaceAdded.connect([&] (const shared_ptr<const NetworkInterface>&) {
io.post([&] { nm.reset(); });
boost::asio::post(io, [&] { nm.reset(); });
});
nm->onEnumerationCompleted.connect([&] {
// make sure the test case terminates even if we have zero interfaces
io.post([&] { nm.reset(); });
boost::asio::post(io, [&] { nm.reset(); });
});
io.run();
+4 -3
View File
@@ -24,6 +24,8 @@
#include "ndn-cxx/security/additional-description.hpp"
#include "ndn-cxx/util/signal/scoped-connection.hpp"
#include <boost/asio/post.hpp>
namespace ndn::tests {
using namespace ndn::security;
@@ -47,7 +49,7 @@ ValidatorFixtureBase::mockNetworkOperations()
{
signal::ScopedConnection conn = face.onSendInterest.connect([this] (const Interest& interest) {
if (processInterest) {
m_io.post([=] { processInterest(interest); });
boost::asio::post(m_io, [=] { processInterest(interest); });
}
});
advanceClocks(s_mockPeriod, s_mockTimes);
@@ -69,8 +71,7 @@ ValidatorFixtureBase::addSubCertificate(const Name& subIdentityName, const Ident
.appendVersion());
SignatureInfo info;
auto now = time::system_clock::now();
info.setValidityPeriod(ValidityPeriod(now, now + 90_days));
info.setValidityPeriod(ValidityPeriod::makeRelative(0_s, 90_days));
AdditionalDescription description;
description.set("type", "sub-certificate");
+4 -4
View File
@@ -39,8 +39,8 @@ BOOST_AUTO_TEST_CASE(ValidateData)
ValidatorNull validator;
validator.validate(data,
std::bind([] { BOOST_CHECK_MESSAGE(true, "Validation should succeed"); }),
std::bind([] { BOOST_CHECK_MESSAGE(false, "Validation should not have failed"); }));
[] (auto&&...) { BOOST_CHECK_MESSAGE(true, "Validation should succeed"); },
[] (auto&&...) { BOOST_CHECK_MESSAGE(false, "Validation should not have failed"); });
}
BOOST_AUTO_TEST_CASE(ValidateInterest)
@@ -51,8 +51,8 @@ BOOST_AUTO_TEST_CASE(ValidateInterest)
ValidatorNull validator;
validator.validate(interest,
std::bind([] { BOOST_CHECK_MESSAGE(true, "Validation should succeed"); }),
std::bind([] { BOOST_CHECK_MESSAGE(false, "Validation should not have failed"); }));
[] (auto&&...) { BOOST_CHECK_MESSAGE(true, "Validation should succeed"); },
[] (auto&&...) { BOOST_CHECK_MESSAGE(false, "Validation should not have failed"); });
}
BOOST_AUTO_TEST_SUITE_END() // TestValidatorNull
+1 -1
View File
@@ -279,7 +279,7 @@ BOOST_AUTO_TEST_CASE(BackrefMatcher)
{
auto backRef = make_shared<RegexBackrefManager>();
auto cm = make_shared<RegexBackrefMatcher>("(<a><b>)", backRef);
backRef->pushRef(static_pointer_cast<RegexMatcher>(cm));
backRef->pushRef(std::static_pointer_cast<RegexMatcher>(cm));
cm->compile();
bool res = cm->match(Name("/a/b/c"), 0, 2);
BOOST_CHECK_EQUAL(res, true);
+21 -13
View File
@@ -51,23 +51,31 @@ BOOST_AUTO_TEST_CASE(Events)
BOOST_CHECK_EQUAL(count2, 1);
});
EventId i = scheduler.schedule(1_s, [] { BOOST_ERROR("This event should not have been fired"); });
i.cancel();
EventId eid = scheduler.schedule(1_s, [] { BOOST_ERROR("This event should not have been fired"); });
eid.cancel();
scheduler.schedule(250_ms, [&] {
BOOST_CHECK_EQUAL(count1, 0);
++count2;
});
i = scheduler.schedule(50_ms, [&] { BOOST_ERROR("This event should not have been fired"); });
i.cancel();
eid = scheduler.schedule(50_ms, [&] { BOOST_ERROR("This event should not have been fired"); });
eid.cancel();
advanceClocks(25_ms, 1000_ms);
BOOST_CHECK_EQUAL(count1, 1);
BOOST_CHECK_EQUAL(count2, 1);
}
BOOST_AUTO_TEST_CASE(CallbackException)
BOOST_AUTO_TEST_CASE(NegativeDelay)
{
bool wasCallbackInvoked = false;
scheduler.schedule(-1_s, [&] { wasCallbackInvoked = true; });
advanceClocks(1_ns);
BOOST_CHECK(wasCallbackInvoked);
}
BOOST_AUTO_TEST_CASE(ThrowingCallback)
{
class MyException : public std::exception
{
@@ -79,12 +87,12 @@ BOOST_AUTO_TEST_CASE(CallbackException)
throw MyException{};
});
bool isCallbackInvoked = false;
scheduler.schedule(20_ms, [&isCallbackInvoked] { isCallbackInvoked = true; });
bool wasCallbackInvoked = false;
scheduler.schedule(20_ms, [&] { wasCallbackInvoked = true; });
BOOST_CHECK_THROW(this->advanceClocks(6_ms, 2), MyException);
this->advanceClocks(6_ms, 2);
BOOST_CHECK(isCallbackInvoked);
BOOST_CHECK(wasCallbackInvoked);
}
BOOST_AUTO_TEST_CASE(CancelEmptyEvent)
@@ -100,7 +108,7 @@ BOOST_AUTO_TEST_CASE(SelfCancel)
{
EventId selfEventId;
selfEventId = scheduler.schedule(100_ms, [&] { selfEventId.cancel(); });
BOOST_REQUIRE_NO_THROW(advanceClocks(100_ms, 10));
BOOST_CHECK_NO_THROW(advanceClocks(100_ms, 10));
}
class SelfRescheduleFixture : public SchedulerFixture
@@ -143,7 +151,7 @@ public:
scheduler.schedule(100_ms, [&] { ++count; });
}
public:
protected:
EventId selfEventId;
size_t count = 0;
};
@@ -151,21 +159,21 @@ public:
BOOST_FIXTURE_TEST_CASE(Reschedule, SelfRescheduleFixture)
{
selfEventId = scheduler.schedule(0_s, [this] { reschedule(); });
BOOST_REQUIRE_NO_THROW(advanceClocks(50_ms, 1000_ms));
advanceClocks(50_ms, 1000_ms);
BOOST_CHECK_EQUAL(count, 5);
}
BOOST_FIXTURE_TEST_CASE(Reschedule2, SelfRescheduleFixture)
{
selfEventId = scheduler.schedule(0_s, [this] { reschedule2(); });
BOOST_REQUIRE_NO_THROW(advanceClocks(50_ms, 1000_ms));
advanceClocks(50_ms, 1000_ms);
BOOST_CHECK_EQUAL(count, 5);
}
BOOST_FIXTURE_TEST_CASE(Reschedule3, SelfRescheduleFixture)
{
selfEventId = scheduler.schedule(0_s, [this] { reschedule3(); });
BOOST_REQUIRE_NO_THROW(advanceClocks(50_ms, 1000_ms));
advanceClocks(50_ms, 1000_ms);
BOOST_CHECK_EQUAL(count, 6);
}
-2
View File
@@ -140,8 +140,6 @@ def configure(conf):
if conf.env.WITH_TOOLS:
conf.check_boost(lib='program_options', mt=True, uselib_store='BOOST_TOOLS')
conf.env.append_unique('DEFINES_BOOST', ['BOOST_FILESYSTEM_NO_DEPRECATED'])
conf.check_compiler_flags()
# Loading "late" to prevent tests from being compiled with profiling flags