From 2f46d6543e55fd1ed1b3cbdb09e183238eb7537e Mon Sep 17 00:00:00 2001 From: Davide Pesavento Date: Thu, 9 Nov 2023 23:40:01 -0500 Subject: [PATCH] Avoid deprecated Boost.Asio interfaces Change-Id: I00d285893ff61619f49dff8a8a55d0d0e2c309a7 --- .waf-tools/default-compiler-flags.py | 6 +- docs/examples.rst | 12 +- docs/release-notes/release-notes-0.2.0.rst | 2 +- examples/consumer-with-timer.cpp | 16 +- ndn-cxx/detail/asio-fwd.hpp | 5 - ndn-cxx/detail/common.hpp | 4 - ndn-cxx/detail/tag-host.hpp | 2 +- ndn-cxx/encoding/encoder.cpp | 2 +- ndn-cxx/face.cpp | 147 ++++++------ ndn-cxx/face.hpp | 135 +++++------ ndn-cxx/impl/face-impl.hpp | 45 ++-- ndn-cxx/ims/in-memory-storage-fifo.cpp | 10 +- ndn-cxx/ims/in-memory-storage-fifo.hpp | 5 +- ndn-cxx/ims/in-memory-storage-lfu.cpp | 12 +- ndn-cxx/ims/in-memory-storage-lfu.hpp | 8 +- ndn-cxx/ims/in-memory-storage-lru.cpp | 11 +- ndn-cxx/ims/in-memory-storage-lru.hpp | 5 +- ndn-cxx/ims/in-memory-storage-persistent.cpp | 42 ---- ndn-cxx/ims/in-memory-storage-persistent.hpp | 26 ++- ndn-cxx/ims/in-memory-storage.cpp | 4 +- ndn-cxx/ims/in-memory-storage.hpp | 2 +- ndn-cxx/mgmt/dispatcher.cpp | 2 +- ndn-cxx/net/dns.cpp | 83 ++----- ndn-cxx/net/dns.hpp | 42 +--- ndn-cxx/net/face-uri.cpp | 22 +- ndn-cxx/net/face-uri.hpp | 4 +- ndn-cxx/net/impl/netlink-socket.cpp | 6 +- ndn-cxx/net/impl/netlink-socket.hpp | 6 +- .../net/impl/network-monitor-impl-netlink.cpp | 2 +- .../net/impl/network-monitor-impl-netlink.hpp | 2 +- .../net/impl/network-monitor-impl-noop.hpp | 2 +- ndn-cxx/net/impl/network-monitor-impl-osx.cpp | 10 +- ndn-cxx/net/impl/network-monitor-impl-osx.hpp | 2 +- ndn-cxx/net/network-monitor.cpp | 4 +- ndn-cxx/net/network-monitor.hpp | 4 +- .../security/certificate-bundle-fetcher.cpp | 2 +- .../certificate-fetcher-direct-fetch.cpp | 4 +- .../certificate-fetcher-from-network.cpp | 2 +- .../validation-policy-command-interest.cpp | 2 +- .../validation-policy-signed-interest.cpp | 2 +- .../detail/stream-transport-impl.hpp | 10 +- .../stream-transport-with-resolver-impl.hpp | 25 +- ndn-cxx/transport/tcp-transport.cpp | 10 +- ndn-cxx/transport/tcp-transport.hpp | 12 +- ndn-cxx/transport/transport.cpp | 6 +- ndn-cxx/transport/transport.hpp | 8 +- ndn-cxx/transport/unix-transport.cpp | 6 +- ndn-cxx/transport/unix-transport.hpp | 12 +- ndn-cxx/util/dummy-client-face.cpp | 32 +-- ndn-cxx/util/dummy-client-face.hpp | 14 +- ndn-cxx/util/notification-subscriber.cpp | 2 +- ndn-cxx/util/scheduler.cpp | 31 +-- ndn-cxx/util/scheduler.hpp | 9 +- ndn-cxx/util/segment-fetcher.cpp | 7 +- tests/benchmarks/scheduler-bench.cpp | 6 +- tests/integration/face.cpp | 8 +- tests/integration/network-monitor.cpp | 4 +- tests/unit/encoding/block.t.cpp | 4 +- tests/unit/face.t.cpp | 216 +++++++++--------- tests/unit/io-fixture.hpp | 4 +- tests/unit/net/dns.t.cpp | 73 +++--- tests/unit/net/face-uri.t.cpp | 12 +- .../net/network-configuration-detector.cpp | 38 ++- tests/unit/net/network-monitor.t.cpp | 11 +- tests/unit/security/validator-fixture.cpp | 7 +- tests/unit/security/validator-null.t.cpp | 8 +- tests/unit/util/regex.t.cpp | 2 +- tests/unit/util/scheduler.t.cpp | 34 +-- wscript | 2 - 69 files changed, 605 insertions(+), 712 deletions(-) delete mode 100644 ndn-cxx/ims/in-memory-storage-persistent.cpp diff --git a/.waf-tools/default-compiler-flags.py b/.waf-tools/default-compiler-flags.py index 4aa9e9b1..bee50724 100644 --- a/.waf-tools/default-compiler-flags.py +++ b/.waf-tools/default-compiler-flags.py @@ -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""" diff --git a/docs/examples.rst b/docs/examples.rst index a2a0a0cb..cdc2df20 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -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 -`_ 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 +`__ +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 diff --git a/docs/release-notes/release-notes-0.2.0.rst b/docs/release-notes/release-notes-0.2.0.rst index 89d7c08c..52bb4e4e 100644 --- a/docs/release-notes/release-notes-0.2.0.rst +++ b/docs/release-notes/release-notes-0.2.0.rst @@ -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. diff --git a/examples/consumer-with-timer.cpp b/examples/consumer-with-timer.cpp index 87abfa99..32a14eb3 100644 --- a/examples/consumer-with-timer.cpp +++ b/examples/consumer-with-timer.cpp @@ -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 #include -#include +#include #include // 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 diff --git a/ndn-cxx/detail/asio-fwd.hpp b/ndn-cxx/detail/asio-fwd.hpp index a33b1220..64b8ab3d 100644 --- a/ndn-cxx/detail/asio-fwd.hpp +++ b/ndn-cxx/detail/asio-fwd.hpp @@ -22,13 +22,8 @@ #ifndef NDN_CXX_DETAIL_ASIO_FWD_HPP #define NDN_CXX_DETAIL_ASIO_FWD_HPP -#include - namespace boost::asio { - class io_context; -using io_service = io_context; - } // namespace boost::asio #endif // NDN_CXX_DETAIL_ASIO_FWD_HPP diff --git a/ndn-cxx/detail/common.hpp b/ndn-cxx/detail/common.hpp index 9071d8c0..abc6bf0c 100644 --- a/ndn-cxx/detail/common.hpp +++ b/ndn-cxx/detail/common.hpp @@ -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; diff --git a/ndn-cxx/detail/tag-host.hpp b/ndn-cxx/detail/tag-host.hpp index 4bf59a3e..05b3c41a 100644 --- a/ndn-cxx/detail/tag-host.hpp +++ b/ndn-cxx/detail/tag-host.hpp @@ -73,7 +73,7 @@ TagHost::getTag() const static_assert(std::is_convertible_v, "T must inherit from ndn::Tag"); if (auto it = m_tags.find(T::getTypeId()); it != m_tags.end()) { - return static_pointer_cast(it->second); + return std::static_pointer_cast(it->second); } return nullptr; } diff --git a/ndn-cxx/encoding/encoder.cpp b/ndn-cxx/encoding/encoder.cpp index 883d2726..3c53352f 100644 --- a/ndn-cxx/encoding/encoder.cpp +++ b/ndn-cxx/encoding/encoder.cpp @@ -34,7 +34,7 @@ Encoder::Encoder(size_t totalReserve, size_t reserveFromBack) } Encoder::Encoder(const Block& block) - : m_buffer(const_pointer_cast(block.getBuffer())) + : m_buffer(std::const_pointer_cast(block.getBuffer())) , m_begin(m_buffer->begin() + (block.begin() - m_buffer->begin())) , m_end(m_buffer->begin() + (block.end() - m_buffer->begin())) { diff --git a/ndn-cxx/face.cpp b/ndn-cxx/face.cpp index f4d685c3..bc590f06 100644 --- a/ndn-cxx/face.cpp +++ b/ndn-cxx/face.cpp @@ -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 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) - : m_internalIoService(make_unique()) - , m_ioService(*m_internalIoService) + : m_internalIoCtx(make_unique()) + , m_ioCtx(*m_internalIoCtx) , m_internalKeyChain(make_unique()) { 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()) { construct(nullptr, *m_internalKeyChain); } Face::Face(const std::string& host, const std::string& port) - : m_internalIoService(make_unique()) - , m_ioService(*m_internalIoService) + : m_internalIoCtx(make_unique()) + , m_ioCtx(*m_internalIoCtx) , m_internalKeyChain(make_unique()) { construct(make_shared(host, port), *m_internalKeyChain); } Face::Face(shared_ptr transport, KeyChain& keyChain) - : m_internalIoService(make_unique()) - , m_ioService(*m_internalIoService) + : m_internalIoCtx(make_unique()) + , m_ioCtx(*m_internalIoCtx) { construct(std::move(transport), keyChain); } -Face::Face(shared_ptr transport, boost::asio::io_service& ioService) - : m_ioService(ioService) +Face::Face(shared_ptr transport, boost::asio::io_context& ioCtx) + : m_ioCtx(ioCtx) , m_internalKeyChain(make_unique()) { construct(std::move(transport), *m_internalKeyChain); } -Face::Face(shared_ptr transport, boost::asio::io_service& ioService, KeyChain& keyChain) - : m_ioService(ioService) +Face::Face(shared_ptr transport, boost::asio::io_context& ioCtx, KeyChain& keyChain) + : m_ioCtx(ioCtx) { construct(std::move(transport), keyChain); } -shared_ptr -Face::makeDefaultTransport() +static shared_ptr +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, 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); 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(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(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 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& 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& weakImpl, detail: InterestFilterHandle::InterestFilterHandle(weak_ptr 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); } }) diff --git a/ndn-cxx/face.hpp b/ndn-cxx/face.hpp index b9153989..a5a1b465 100644 --- a/ndn-cxx/face.hpp +++ b/ndn-cxx/face.hpp @@ -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 = 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, 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) * * @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, boost::asio::io_service& ioService); + Face(shared_ptr 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, 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, boost::asio::io_service& ioService, KeyChain& keyChain); + Face(shared_ptr 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& 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 - 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 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 m_internalIoCtx; + /// The io_context used by this Face. + boost::asio::io_context& m_ioCtx; shared_ptr m_transport; diff --git a/ndn-cxx/impl/face-impl.hpp b/ndn-cxx/impl/face-impl.hpp index 54b1ffe1..df1fabd6 100644 --- a/ndn-cxx/impl/face-impl.hpp +++ b/ndn-cxx/impl/face-impl.hpp @@ -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 +#include + +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 { 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 m_interestFilterTable; detail::RecordContainer m_registeredPrefixTable; - unique_ptr m_ioServiceWork; // if thread needs to be preserved + using IoContextWorkGuard = boost::asio::executor_work_guard; + unique_ptr m_workGuard; friend Face; }; diff --git a/ndn-cxx/ims/in-memory-storage-fifo.cpp b/ndn-cxx/ims/in-memory-storage-fifo.cpp index 976170bd..c3c2e79e 100644 --- a/ndn-cxx/ims/in-memory-storage-fifo.cpp +++ b/ndn-cxx/ims/in-memory-storage-fifo.cpp @@ -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().empty()) { - CleanupIndex::index::type::iterator it = m_cleanupIndex.get().begin(); + auto it = m_cleanupIndex.get().begin(); eraseImpl((*it)->getFullName()); m_cleanupIndex.get().erase(it); return true; @@ -56,7 +56,7 @@ InMemoryStorageFifo::evictItem() void InMemoryStorageFifo::beforeErase(InMemoryStorageEntry* entry) { - CleanupIndex::index::type::iterator it = m_cleanupIndex.get().find(entry); + auto it = m_cleanupIndex.get().find(entry); if (it != m_cleanupIndex.get().end()) m_cleanupIndex.get().erase(it); } diff --git a/ndn-cxx/ims/in-memory-storage-fifo.hpp b/ndn-cxx/ims/in-memory-storage-fifo.hpp index cc59acfe..96193d54 100644 --- a/ndn-cxx/ims/in-memory-storage-fifo.hpp +++ b/ndn-cxx/ims/in-memory-storage-fifo.hpp @@ -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 diff --git a/ndn-cxx/ims/in-memory-storage-lfu.cpp b/ndn-cxx/ims/in-memory-storage-lfu.cpp index 2e5e3339..cb725306 100644 --- a/ndn-cxx/ims/in-memory-storage-lfu.cpp +++ b/ndn-cxx/ims/in-memory-storage-lfu.cpp @@ -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().empty()) { - CleanupIndex::index::type::iterator it = m_cleanupIndex.get().begin(); + auto it = m_cleanupIndex.get().begin(); eraseImpl(((*it).entry)->getFullName()); m_cleanupIndex.get().erase(it); return true; @@ -59,7 +59,7 @@ InMemoryStorageLfu::evictItem() void InMemoryStorageLfu::beforeErase(InMemoryStorageEntry* entry) { - CleanupIndex::index::type::iterator it = m_cleanupIndex.get().find(entry); + auto it = m_cleanupIndex.get().find(entry); if (it != m_cleanupIndex.get().end()) m_cleanupIndex.get().erase(it); } @@ -67,7 +67,7 @@ InMemoryStorageLfu::beforeErase(InMemoryStorageEntry* entry) void InMemoryStorageLfu::afterAccess(InMemoryStorageEntry* entry) { - CleanupIndex::index::type::iterator it = m_cleanupIndex.get().find(entry); + auto it = m_cleanupIndex.get().find(entry); m_cleanupIndex.get().modify(it, &incrementFrequency); } diff --git a/ndn-cxx/ims/in-memory-storage-lfu.hpp b/ndn-cxx/ims/in-memory-storage-lfu.hpp index cc8e7dc0..ec72c6e1 100644 --- a/ndn-cxx/ims/in-memory-storage-lfu.hpp +++ b/ndn-cxx/ims/in-memory-storage-lfu.hpp @@ -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 diff --git a/ndn-cxx/ims/in-memory-storage-lru.cpp b/ndn-cxx/ims/in-memory-storage-lru.cpp index f80f854f..40b4d924 100644 --- a/ndn-cxx/ims/in-memory-storage-lru.cpp +++ b/ndn-cxx/ims/in-memory-storage-lru.cpp @@ -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().empty()) { - CleanupIndex::index::type::iterator it = m_cleanupIndex.get().begin(); + auto it = m_cleanupIndex.get().begin(); eraseImpl((*it)->getFullName()); m_cleanupIndex.get().erase(it); return true; @@ -58,7 +57,7 @@ InMemoryStorageLru::evictItem() void InMemoryStorageLru::beforeErase(InMemoryStorageEntry* entry) { - CleanupIndex::index::type::iterator it = m_cleanupIndex.get().find(entry); + auto it = m_cleanupIndex.get().find(entry); if (it != m_cleanupIndex.get().end()) m_cleanupIndex.get().erase(it); } diff --git a/ndn-cxx/ims/in-memory-storage-lru.hpp b/ndn-cxx/ims/in-memory-storage-lru.hpp index 9f0decfa..7dd5f29f 100644 --- a/ndn-cxx/ims/in-memory-storage-lru.hpp +++ b/ndn-cxx/ims/in-memory-storage-lru.hpp @@ -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 diff --git a/ndn-cxx/ims/in-memory-storage-persistent.cpp b/ndn-cxx/ims/in-memory-storage-persistent.cpp deleted file mode 100644 index bd3c1952..00000000 --- a/ndn-cxx/ims/in-memory-storage-persistent.cpp +++ /dev/null @@ -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 - * . - * - * 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 diff --git a/ndn-cxx/ims/in-memory-storage-persistent.hpp b/ndn-cxx/ims/in-memory-storage-persistent.hpp index 67104343..f6cdca38 100644 --- a/ndn-cxx/ims/in-memory-storage-persistent.hpp +++ b/ndn-cxx/ims/in-memory-storage-persistent.hpp @@ -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 diff --git a/ndn-cxx/ims/in-memory-storage.cpp b/ndn-cxx/ims/in-memory-storage.cpp index 36ccb08d..c4ea1cf2 100644 --- a/ndn-cxx/ims/in-memory-storage.cpp +++ b/ndn-cxx/ims/in-memory-storage.cpp @@ -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(ioService); + m_scheduler = make_unique(ioCtx); init(); } diff --git a/ndn-cxx/ims/in-memory-storage.hpp b/ndn-cxx/ims/in-memory-storage.hpp index 30965421..de4acde4 100644 --- a/ndn-cxx/ims/in-memory-storage.hpp +++ b/ndn-cxx/ims/in-memory-storage.hpp @@ -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::max()); /** @note Please make sure to implement it to free m_freeEntries and evict diff --git a/ndn-cxx/mgmt/dispatcher.cpp b/ndn-cxx/mgmt/dispatcher.cpp index a1926428..b42fa362 100644 --- a/ndn-cxx/mgmt/dispatcher.cpp +++ b/ndn-cxx/mgmt/dispatcher.cpp @@ -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) { } diff --git a/ndn-cxx/net/dns.cpp b/ndn-cxx/net/dns.cpp index 70d0d8ae..36abaf00 100644 --- a/ndn-cxx/net/dns.cpp +++ b/ndn-cxx/net/dns.cpp @@ -22,7 +22,6 @@ #include "ndn-cxx/net/dns.hpp" #include "ndn-cxx/util/scheduler.hpp" -#include #include #include @@ -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(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& self) + const boost::asio::ip::udp::resolver::results_type& results, + const shared_ptr& 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(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(ioCtx, addressSelector); + resolver->asyncResolve(host, onSuccess, onError, timeout, resolver); + // resolver will be destroyed when async operation finishes or ioCtx stops } } // namespace ndn::dns diff --git a/ndn-cxx/net/dns.hpp b/ndn-cxx/net/dns.hpp index 4859d98b..482484d5 100644 --- a/ndn-cxx/net/dns.hpp +++ b/ndn-cxx/net/dns.hpp @@ -29,13 +29,12 @@ namespace ndn::dns { -using IpAddress = boost::asio::ip::address; -using AddressSelector = std::function; +using AddressSelector = std::function; 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; +using SuccessCallback = std::function; using ErrorCallback = std::function; -/** \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; * - 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 diff --git a/ndn-cxx/net/face-uri.cpp b/ndn-cxx/net/face-uri.cpp index da5905f0..93cbec46 100644 --- a/ndn-cxx/net/face-uri.cpp +++ b/ndn-cxx/net/face-uri.cpp @@ -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 @@ -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); 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, 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 - checkAddress(const dns::IpAddress&) const + checkAddress(const boost::asio::ip::address&) const { return {true, ""}; } @@ -425,7 +425,7 @@ public: protected: std::pair - 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) { diff --git a/ndn-cxx/net/face-uri.hpp b/ndn-cxx/net/face-uri.hpp index 2adbc380..c486dc0e 100644 --- a/ndn-cxx/net/face-uri.hpp +++ b/ndn-cxx/net/face-uri.hpp @@ -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: diff --git a/ndn-cxx/net/impl/netlink-socket.cpp b/ndn-cxx/net/impl/netlink-socket.cpp index 0c266373..bfcd4d83 100644 --- a/ndn-cxx/net/impl/netlink-socket.cpp +++ b/ndn-cxx/net/impl/netlink-socket.cpp @@ -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(io)) , m_pid(0) , m_seqNum(static_cast(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; diff --git a/ndn-cxx/net/impl/netlink-socket.hpp b/ndn-cxx/net/impl/netlink-socket.hpp index 34a5e9ed..481c633f 100644 --- a/ndn-cxx/net/impl/netlink-socket.hpp +++ b/ndn-cxx/net/impl/netlink-socket.hpp @@ -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(); diff --git a/ndn-cxx/net/impl/network-monitor-impl-netlink.cpp b/ndn-cxx/net/impl/network-monitor-impl-netlink.cpp index ca1d7495..ec751766 100644 --- a/ndn-cxx/net/impl/network-monitor-impl-netlink.cpp +++ b/ndn-cxx/net/impl/network-monitor-impl-netlink.cpp @@ -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) { diff --git a/ndn-cxx/net/impl/network-monitor-impl-netlink.hpp b/ndn-cxx/net/impl/network-monitor-impl-netlink.hpp index 64616a6c..f181546b 100644 --- a/ndn-cxx/net/impl/network-monitor-impl-netlink.hpp +++ b/ndn-cxx/net/impl/network-monitor-impl-netlink.hpp @@ -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 diff --git a/ndn-cxx/net/impl/network-monitor-impl-noop.hpp b/ndn-cxx/net/impl/network-monitor-impl-noop.hpp index f2f2c416..51c45505 100644 --- a/ndn-cxx/net/impl/network-monitor-impl-noop.hpp +++ b/ndn-cxx/net/impl/network-monitor-impl-noop.hpp @@ -32,7 +32,7 @@ class NetworkMonitorImplNoop final : public NetworkMonitorImpl { public: explicit - NetworkMonitorImplNoop(boost::asio::io_service&) + NetworkMonitorImplNoop(boost::asio::io_context&) { } diff --git a/ndn-cxx/net/impl/network-monitor-impl-osx.cpp b/ndn-cxx/net/impl/network-monitor-impl-osx.cpp index 44378d58..ab32dc44 100644 --- a/ndn-cxx/net/impl/network-monitor-impl-osx.cpp +++ b/ndn-cxx/net/impl/network-monitor-impl-osx.cpp @@ -62,9 +62,9 @@ #include // for IFT_* constants #include // for struct sockaddr_in{,6} -#include +#include #include -#include +#include #include #include @@ -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; } diff --git a/ndn-cxx/net/impl/network-monitor-impl-osx.hpp b/ndn-cxx/net/impl/network-monitor-impl-osx.hpp index f1866cab..fb3301ab 100644 --- a/ndn-cxx/net/impl/network-monitor-impl-osx.hpp +++ b/ndn-cxx/net/impl/network-monitor-impl-osx.hpp @@ -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; diff --git a/ndn-cxx/net/network-monitor.cpp b/ndn-cxx/net/network-monitor.cpp index 79e601f8..6d2c3654 100644 --- a/ndn-cxx/net/network-monitor.cpp +++ b/ndn-cxx/net/network-monitor.cpp @@ -42,7 +42,7 @@ namespace ndn::net { NDN_LOG_INIT(ndn.NetworkMonitor); static unique_ptr -makeNetworkMonitorImpl(boost::asio::io_service& io) +makeNetworkMonitorImpl(boost::asio::io_context& io) { try { return make_unique(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)) { } diff --git a/ndn-cxx/net/network-monitor.hpp b/ndn-cxx/net/network-monitor.hpp index f45c4d53..1dcce41c 100644 --- a/ndn-cxx/net/network-monitor.hpp +++ b/ndn-cxx/net/network-monitor.hpp @@ -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 diff --git a/ndn-cxx/security/certificate-bundle-fetcher.cpp b/ndn-cxx/security/certificate-bundle-fetcher.cpp index 1179bf04..36bc4bca 100644 --- a/ndn-cxx/security/certificate-bundle-fetcher.cpp +++ b/ndn-cxx/security/certificate-bundle-fetcher.cpp @@ -67,7 +67,7 @@ CertificateBundleFetcher::doFetch(const shared_ptr& certRequ const shared_ptr& state, const ValidationContinuation& continueValidation) { - auto dataValidationState = dynamic_pointer_cast(state); + auto dataValidationState = std::dynamic_pointer_cast(state); if (dataValidationState == nullptr) { return m_inner->fetch(certRequest, state, continueValidation); } diff --git a/ndn-cxx/security/certificate-fetcher-direct-fetch.cpp b/ndn-cxx/security/certificate-fetcher-direct-fetch.cpp index c7df4f26..38710370 100644 --- a/ndn-cxx/security/certificate-fetcher-direct-fetch.cpp +++ b/ndn-cxx/security/certificate-fetcher-direct-fetch.cpp @@ -45,7 +45,7 @@ CertificateFetcherDirectFetch::doFetch(const shared_ptr& key const ValidationContinuation& continueValidation) { uint64_t incomingFaceId = 0; - auto interestState = dynamic_pointer_cast(state); + auto interestState = std::dynamic_pointer_cast(state); if (interestState != nullptr) { auto incomingFaceIdTag = interestState->getOriginalInterest().getTag(); if (incomingFaceIdTag != nullptr) { @@ -53,7 +53,7 @@ CertificateFetcherDirectFetch::doFetch(const shared_ptr& key } } else { - auto dataState = dynamic_pointer_cast(state); + auto dataState = std::dynamic_pointer_cast(state); auto incomingFaceIdTag = dataState->getOriginalData().getTag(); if (incomingFaceIdTag != nullptr) { incomingFaceId = incomingFaceIdTag->get(); diff --git a/ndn-cxx/security/certificate-fetcher-from-network.cpp b/ndn-cxx/security/certificate-fetcher-from-network.cpp index 0861c0d8..8ec9113c 100644 --- a/ndn-cxx/security/certificate-fetcher-from-network.cpp +++ b/ndn-cxx/security/certificate-fetcher-from-network.cpp @@ -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()) { } diff --git a/ndn-cxx/security/validation-policy-command-interest.cpp b/ndn-cxx/security/validation-policy-command-interest.cpp index ddae489d..b2fbe8ff 100644 --- a/ndn-cxx/security/validation-policy-command-interest.cpp +++ b/ndn-cxx/security/validation-policy-command-interest.cpp @@ -146,7 +146,7 @@ ValidationPolicyCommandInterest::checkTimestamp(const shared_ptr(state); + auto interestState = std::dynamic_pointer_cast(state); BOOST_ASSERT(interestState != nullptr); interestState->afterSuccess.connect([=] (const Interest&) { insertNewRecord(keyName, timestamp); }); return true; diff --git a/ndn-cxx/security/validation-policy-signed-interest.cpp b/ndn-cxx/security/validation-policy-signed-interest.cpp index 58f5779b..e56d3a81 100644 --- a/ndn-cxx/security/validation-policy-signed-interest.cpp +++ b/ndn-cxx/security/validation-policy-signed-interest.cpp @@ -129,7 +129,7 @@ ValidationPolicySignedInterest::checkIncomingInterest(const shared_ptr(state); + auto interestState = std::dynamic_pointer_cast(state); BOOST_ASSERT(interestState != nullptr); interestState->afterSuccess.connect([=] (const Interest&) { insertRecord(keyName, timestamp, seqNum, nonce); diff --git a/ndn-cxx/transport/detail/stream-transport-impl.hpp b/ndn-cxx/transport/detail/stream-transport-impl.hpp index 0ee10359..ff105391 100644 --- a/ndn-cxx/transport/detail/stream-transport-impl.hpp +++ b/ndn-cxx/transport/detail/stream-transport-impl.hpp @@ -44,10 +44,10 @@ public: using Impl = StreamTransportImpl; using TransmissionQueue = std::queue>; - 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); diff --git a/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp b/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp index 2ca01e49..dec886a0 100644 --- a/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp +++ b/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp @@ -33,13 +33,13 @@ template class StreamTransportWithResolverImpl : public StreamTransportImpl { public: - StreamTransportWithResolverImpl(BaseTransport& transport, boost::asio::io_service& ioService) - : StreamTransportImpl(transport, ioService) + StreamTransportWithResolverImpl(BaseTransport& transport, boost::asio::io_context& ioCtx) + : StreamTransportImpl(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(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(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&) { 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 shared_from_base() { - return static_pointer_cast(this->shared_from_this()); + return std::static_pointer_cast(this->shared_from_this()); } }; diff --git a/ndn-cxx/transport/tcp-transport.cpp b/ndn-cxx/transport/tcp-transport.cpp index 20360efc..79f53fa6 100644 --- a/ndn-cxx/transport/tcp-transport.cpp +++ b/ndn-cxx/transport/tcp-transport.cpp @@ -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(*this, ioService); + Transport::connect(ioCtx, std::move(receiveCallback)); + m_impl = make_shared(*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 diff --git a/ndn-cxx/transport/tcp-transport.hpp b/ndn-cxx/transport/tcp-transport.hpp index a40ba0f0..042fe0b2 100644 --- a/ndn-cxx/transport/tcp-transport.hpp +++ b/ndn-cxx/transport/tcp-transport.hpp @@ -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 create(const std::string& uri); diff --git a/ndn-cxx/transport/transport.cpp b/ndn-cxx/transport/transport.cpp index a78e36fe..1b7c7745 100644 --- a/ndn-cxx/transport/transport.cpp +++ b/ndn-cxx/transport/transport.cpp @@ -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); } diff --git a/ndn-cxx/transport/transport.hpp b/ndn-cxx/transport/transport.hpp index 2ef4b3d3..b6ccdb4d 100644 --- a/ndn-cxx/transport/transport.hpp +++ b/ndn-cxx/transport/transport.hpp @@ -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: diff --git a/ndn-cxx/transport/unix-transport.cpp b/ndn-cxx/transport/unix-transport.cpp index 110423a0..33f39190 100644 --- a/ndn-cxx/transport/unix-transport.cpp +++ b/ndn-cxx/transport/unix-transport.cpp @@ -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(*this, ioService); + Transport::connect(ioCtx, std::move(receiveCallback)); + m_impl = make_shared(*this, ioCtx); } m_impl->connect(boost::asio::local::stream_protocol::endpoint(m_unixSocket)); diff --git a/ndn-cxx/transport/unix-transport.hpp b/ndn-cxx/transport/unix-transport.hpp index 4a31a59a..91c2f71f 100644 --- a/ndn-cxx/transport/unix-transport.hpp +++ b/ndn-cxx/transport/unix-transport.hpp @@ -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 create(const std::string& uri); diff --git a/ndn-cxx/util/dummy-client-face.cpp b/ndn-cxx/util/dummy-client-face.cpp index 1f278e59..06981b9e 100644 --- a/ndn-cxx/util/dummy-client-face.cpp +++ b/ndn-cxx/util/dummy-client-face.cpp @@ -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 +#include +#include 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(), ioService) +DummyClientFace::DummyClientFace(boost::asio::io_context& ioCtx, const Options& options) + : Face(make_shared(), ioCtx) , m_internalKeyChain(make_unique()) , m_keyChain(*m_internalKeyChain) { this->construct(options); } -DummyClientFace::DummyClientFace(boost::asio::io_service& ioService, KeyChain& keyChain, const Options& options) - : Face(make_shared(), ioService, keyChain) +DummyClientFace::DummyClientFace(boost::asio::io_context& ioCtx, KeyChain& keyChain, const Options& options) + : Face(make_shared(), ioCtx, keyChain) , m_keyChain(keyChain) { this->construct(options); @@ -116,7 +118,7 @@ DummyClientFace::~DummyClientFace() void DummyClientFace::construct(const Options& options) { - static_pointer_cast(getTransport())->onSendBlock.connect([this] (Block packet) { + static_cast(getTransport()).onSendBlock.connect([this] (Block packet) { packet.encode(); lp::Packet lpPacket(packet); auto frag = lpPacket.get(); @@ -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 = make_shared(name); + auto data = make_shared(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(lpPacket, interest); addFieldFromTag(lpPacket, interest); - static_pointer_cast(getTransport())->receive(lpPacket.wireEncode()); + static_cast(getTransport()).receive(lpPacket.wireEncode()); } void @@ -253,7 +255,7 @@ DummyClientFace::receive(const Data& data) addFieldFromTag(lpPacket, data); addFieldFromTag(lpPacket, data); - static_pointer_cast(getTransport())->receive(lpPacket.wireEncode()); + static_cast(getTransport()).receive(lpPacket.wireEncode()); } void @@ -267,7 +269,7 @@ DummyClientFace::receive(const lp::Nack& nack) addFieldFromTag(lpPacket, nack); addFieldFromTag(lpPacket, nack); - static_pointer_cast(getTransport())->receive(lpPacket.wireEncode()); + static_cast(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); } } diff --git a/ndn-cxx/util/dummy-client-face.hpp b/ndn-cxx/util/dummy-client-face.hpp index bc92c7ee..6583e367 100644 --- a/ndn-cxx/util/dummy-client-face.hpp +++ b/ndn-cxx/util/dummy-client-face.hpp @@ -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. diff --git a/ndn-cxx/util/notification-subscriber.cpp b/ndn-cxx/util/notification-subscriber.cpp index 4a13240c..ac934d1b 100644 --- a/ndn-cxx/util/notification-subscriber.cpp +++ b/ndn-cxx/util/notification-subscriber.cpp @@ -40,7 +40,7 @@ NotificationSubscriberBase::NotificationSubscriberBase(Face& face, const Name& p , m_lastSequenceNum(std::numeric_limits::max()) , m_lastNackSequenceNum(std::numeric_limits::max()) , m_attempts(1) - , m_scheduler(face.getIoService()) + , m_scheduler(face.getIoContext()) , m_interestLifetime(interestLifetime) { } diff --git a/ndn-cxx/util/scheduler.cpp b/ndn-cxx/util/scheduler.cpp index fae2a846..8b58e837 100644 --- a/ndn-cxx/util/scheduler.cpp +++ b/ndn-cxx/util/scheduler.cpp @@ -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& a, const shared_ptr& b) const noexcept { - return a->expireTime < b->expireTime; + return a->expiry < b->expiry; } -Scheduler::Scheduler(boost::asio::io_service& ioService) - : m_timer(make_unique(ioService)) +Scheduler::Scheduler(boost::asio::io_context& ioCtx) + : m_timer(make_unique(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 info = *head; - if (info->expireTime > now) { + if (info->expiry > now) { break; } diff --git a/ndn-cxx/util/scheduler.hpp b/ndn-cxx/util/scheduler.hpp index e82b1517..bdf598d0 100644 --- a/ndn-cxx/util/scheduler.hpp +++ b/ndn-cxx/util/scheduler.hpp @@ -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; -/** \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 diff --git a/ndn-cxx/util/segment-fetcher.cpp b/ndn-cxx/util/segment-fetcher.cpp index b570a7b1..11cc339c 100644 --- a/ndn-cxx/util/segment-fetcher.cpp +++ b/ndn-cxx/util/segment-fetcher.cpp @@ -27,7 +27,8 @@ #include "ndn-cxx/lp/nack.hpp" #include "ndn-cxx/lp/nack-header.hpp" -#include +#include +#include #include #include @@ -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(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 diff --git a/tests/benchmarks/scheduler-bench.cpp b/tests/benchmarks/scheduler-bench.cpp index 46af278b..e1e3433d 100644 --- a/tests/benchmarks/scheduler-bench.cpp +++ b/tests/benchmarks/scheduler-bench.cpp @@ -25,14 +25,14 @@ #include "ndn-cxx/util/scheduler.hpp" #include "tests/benchmarks/timed-execute.hpp" -#include +#include #include 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; diff --git a/tests/integration/face.cpp b/tests/integration/face.cpp index 7bd24085..a759e35f 100644 --- a/tests/integration/face.cpp +++ b/tests/integration/face.cpp @@ -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(TransportType::create(""), face.getIoService(), m_keyChain); + face2 = make_unique(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: diff --git a/tests/integration/network-monitor.cpp b/tests/integration/network-monitor.cpp index cf6d8bdf..ff4d9329 100644 --- a/tests/integration/network-monitor.cpp +++ b/tests/integration/network-monitor.cpp @@ -30,7 +30,7 @@ #include "ndn-cxx/util/string-helper.hpp" #include "ndn-cxx/util/time.hpp" -#include +#include #include namespace ndn::tests { @@ -48,7 +48,7 @@ logEvent(const shared_ptr& 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; diff --git a/tests/unit/encoding/block.t.cpp b/tests/unit/encoding/block.t.cpp index c93a3076..b4f2cf84 100644 --- a/tests/unit/encoding/block.t.cpp +++ b/tests/unit/encoding/block.t.cpp @@ -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(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) diff --git a/tests/unit/face.t.cpp b/tests/unit/face.t.cpp index f369d6f4..78d7c679 100644 --- a/tests/unit/face.t.cpp +++ b/tests/unit/face.t.cpp @@ -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(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(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(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) // 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?"), - 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", "<>?"), + // 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", "<>?"), - 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) // // 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) // 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()).getTransport() != nullptr); - BOOST_CHECK(Face(shared_ptr(), m_io).getTransport() != nullptr); - BOOST_CHECK(Face(shared_ptr(), m_io, m_keyChain).getTransport() != nullptr); + BOOST_CHECK_NO_THROW(Face(shared_ptr())); + BOOST_CHECK_NO_THROW(Face(shared_ptr(), m_io)); + BOOST_CHECK_NO_THROW(Face(shared_ptr(), m_io, m_keyChain)); auto transport = make_shared("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; BOOST_FIXTURE_TEST_CASE(NoConfig, WithEnvAndConfig) // fixture configures test HOME and PIB/TPM path { shared_ptr face; - BOOST_REQUIRE_NO_THROW(face = make_shared()); - BOOST_CHECK(dynamic_pointer_cast(face->getTransport()) != nullptr); + BOOST_CHECK_NO_THROW(face = make_shared()); + BOOST_CHECK(dynamic_cast(&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; - BOOST_REQUIRE_NO_THROW(face = make_shared()); - BOOST_CHECK(dynamic_pointer_cast(face->getTransport()) != nullptr); + BOOST_CHECK_NO_THROW(face = make_shared()); + BOOST_CHECK(dynamic_cast(&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; - BOOST_REQUIRE_NO_THROW(face = make_shared()); - BOOST_CHECK(dynamic_pointer_cast(face->getTransport()) != nullptr); + BOOST_CHECK_NO_THROW(face = make_shared()); + BOOST_CHECK(dynamic_cast(&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; - BOOST_REQUIRE_NO_THROW(face = make_shared()); - BOOST_CHECK(dynamic_pointer_cast(face->getTransport()) != nullptr); + BOOST_CHECK_NO_THROW(face = make_shared()); + BOOST_CHECK(dynamic_cast(&face->getTransport()) != nullptr); } BOOST_FIXTURE_TEST_CASE(ExplicitTransport, WithEnvAndConfig) @@ -967,8 +969,8 @@ BOOST_FIXTURE_TEST_CASE(ExplicitTransport, WithEnvAndConfig) auto transport = make_shared("unix://some/path"); shared_ptr face; - BOOST_REQUIRE_NO_THROW(face = make_shared(transport)); - BOOST_CHECK(dynamic_pointer_cast(face->getTransport()) != nullptr); + BOOST_CHECK_NO_THROW(face = make_shared(transport)); + BOOST_CHECK(dynamic_cast(&face->getTransport()) != nullptr); } BOOST_AUTO_TEST_SUITE_END() // Transport diff --git a/tests/unit/io-fixture.hpp b/tests/unit/io-fixture.hpp index 191b889d..762dd6c0 100644 --- a/tests/unit/io-fixture.hpp +++ b/tests/unit/io-fixture.hpp @@ -24,7 +24,7 @@ #include "tests/unit/clock-fixture.hpp" -#include +#include namespace ndn::tests { @@ -41,7 +41,7 @@ private: } protected: - boost::asio::io_service m_io; + boost::asio::io_context m_io; }; } // namespace ndn::tests diff --git a/tests/unit/net/dns.t.cpp b/tests/unit/net/dns.t.cpp index ac734dd1..17c5438b 100644 --- a/tests/unit/net/dns.t.cpp +++ b/tests/unit/net/dns.t.cpp @@ -24,20 +24,19 @@ #include "tests/boost-test.hpp" #include "tests/unit/net/network-configuration-detector.hpp" -#include +#include 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 diff --git a/tests/unit/net/face-uri.t.cpp b/tests/unit/net/face-uri.t.cpp index 78e712ab..36883bfd 100644 --- a/tests/unit/net/face-uri.t.cpp +++ b/tests/unit/net/face-uri.t.cpp @@ -94,7 +94,7 @@ protected: shared_ptr 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); diff --git a/tests/unit/net/network-configuration-detector.cpp b/tests/unit/net/network-configuration-detector.cpp index f8a88164..44cae399 100644 --- a/tests/unit/net/network-configuration-detector.cpp +++ b/tests/unit/net/network-configuration-detector.cpp @@ -21,11 +21,9 @@ #include "tests/unit/net/network-configuration-detector.hpp" -#include +#include #include -#include #include -#include namespace ndn::tests { @@ -50,31 +48,23 @@ NetworkConfigurationDetector::hasIpv6() void NetworkConfigurationDetector::detect() { - using BoostResolver = boost::asio::ip::basic_resolver; + 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; } diff --git a/tests/unit/net/network-monitor.t.cpp b/tests/unit/net/network-monitor.t.cpp index 45152585..50c04c75 100644 --- a/tests/unit/net/network-monitor.t.cpp +++ b/tests/unit/net/network-monitor.t.cpp @@ -23,7 +23,8 @@ #include "tests/boost-test.hpp" -#include +#include +#include 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(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(io); NM_REQUIRE_CAP(ENUM); nm->onInterfaceAdded.connect([&] (const shared_ptr&) { - 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(); diff --git a/tests/unit/security/validator-fixture.cpp b/tests/unit/security/validator-fixture.cpp index 41497bfc..ff198a30 100644 --- a/tests/unit/security/validator-fixture.cpp +++ b/tests/unit/security/validator-fixture.cpp @@ -24,6 +24,8 @@ #include "ndn-cxx/security/additional-description.hpp" #include "ndn-cxx/util/signal/scoped-connection.hpp" +#include + 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"); diff --git a/tests/unit/security/validator-null.t.cpp b/tests/unit/security/validator-null.t.cpp index ebae9004..05dd270f 100644 --- a/tests/unit/security/validator-null.t.cpp +++ b/tests/unit/security/validator-null.t.cpp @@ -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 diff --git a/tests/unit/util/regex.t.cpp b/tests/unit/util/regex.t.cpp index d09688e2..07ec293e 100644 --- a/tests/unit/util/regex.t.cpp +++ b/tests/unit/util/regex.t.cpp @@ -279,7 +279,7 @@ BOOST_AUTO_TEST_CASE(BackrefMatcher) { auto backRef = make_shared(); auto cm = make_shared("()", backRef); - backRef->pushRef(static_pointer_cast(cm)); + backRef->pushRef(std::static_pointer_cast(cm)); cm->compile(); bool res = cm->match(Name("/a/b/c"), 0, 2); BOOST_CHECK_EQUAL(res, true); diff --git a/tests/unit/util/scheduler.t.cpp b/tests/unit/util/scheduler.t.cpp index e5c99e57..88c43131 100644 --- a/tests/unit/util/scheduler.t.cpp +++ b/tests/unit/util/scheduler.t.cpp @@ -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); } diff --git a/wscript b/wscript index 5eb2681e..a55e4831 100644 --- a/wscript +++ b/wscript @@ -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