From 51832cb24a06310def336934c27bc2b03b3bea25 Mon Sep 17 00:00:00 2001 From: Sam Sutherland-Dee Date: Tue, 30 Sep 2025 16:29:00 +0100 Subject: [PATCH 1/3] Remove boost dependency --- .clang-format | 2 +- CMakeLists.txt | 10 +- README.md | 3 +- dockerfiles/dev.Dockerfile | 1 - licenses-binary/LICENSE-boost-asio.txt | 23 --- licenses-binary/LICENSE-boost-iostreams.txt | 23 --- licenses/LICENSE-boost-asio.txt | 23 --- licenses/LICENSE-boost-iostreams.txt | 23 --- src/CMakeLists.txt | 2 +- src/rmq/rmqa/CMakeLists.txt | 6 +- src/rmq/rmqa/rmqa_rabbitcontextimpl.cpp | 12 +- src/rmq/rmqa/rmqa_rabbitcontextoptions.h | 2 +- src/rmq/rmqamqp/CMakeLists.txt | 6 +- src/rmq/rmqio/CMakeLists.txt | 10 +- src/rmq/rmqio/rmqio_asioconnection.cpp | 87 ++++++----- src/rmq/rmqio/rmqio_asioconnection.h | 26 ++-- src/rmq/rmqio/rmqio_asioeventloop.cpp | 8 +- src/rmq/rmqio/rmqio_asioeventloop.h | 8 +- src/rmq/rmqio/rmqio_asioresolver.cpp | 77 +++++----- src/rmq/rmqio/rmqio_asioresolver.h | 19 ++- src/rmq/rmqio/rmqio_asiosocketwrapper.h | 19 ++- src/rmq/rmqio/rmqio_asiotimer.h | 141 +++++++----------- src/tests/CMakeLists.txt | 6 +- src/tests/rmqamqp/rmqamqp_connection.t.cpp | 17 ++- src/tests/rmqio/CMakeLists.txt | 8 +- src/tests/rmqio/rmqio_asioconnection.t.cpp | 19 ++- src/tests/rmqio/rmqio_asioresolver.t.cpp | 11 +- src/tests/rmqio/rmqio_asiotimer.t.cpp | 36 +++-- .../rmqtestutil_mocktimerfactory.cpp | 2 +- .../rmqtestutil/rmqtestutil_timeoverride.cpp | 4 - .../rmqtestutil/rmqtestutil_timeoverride.h | 34 ++--- vcpkg.json | 2 +- 32 files changed, 265 insertions(+), 405 deletions(-) delete mode 100644 licenses-binary/LICENSE-boost-asio.txt delete mode 100644 licenses-binary/LICENSE-boost-iostreams.txt delete mode 100644 licenses/LICENSE-boost-asio.txt delete mode 100644 licenses/LICENSE-boost-iostreams.txt diff --git a/.clang-format b/.clang-format index 0128c516..ab2b2696 100644 --- a/.clang-format +++ b/.clang-format @@ -36,7 +36,7 @@ Cpp11BracedListStyle: true DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false -ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +ForEachMacros: [ foreach, Q_FOREACH ] IndentWrappedFunctionNames: false KeepEmptyLinesAtTheStartOfBlocks: true MacroBlockBegin: '' diff --git a/CMakeLists.txt b/CMakeLists.txt index 33db7caf..4b17b565 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,11 +15,11 @@ endif() if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro") # _RWSTD_ALLOCATOR tells the solaris header to define a std::allocator - # which conforms better to the C++ standard, which is expected by Boost. Without - # this, the library does not build due to missing std::allocator<..>::rebind + # which conforms better to the C++ standard; without this, the library does not + # build due to missing std::allocator<..>::rebind # "-D_XOPEN_SOURCE=500" "-D__EXTENSIONS__" tells the solaris sys/socket.h to conform - # better to what boost asio expects (to have a msg_flags member) + # better to what Asio expects (to have a msg_flags member) target_compile_definitions(rmq PRIVATE _RWSTD_ALLOCATOR "-D_XOPEN_SOURCE=500" "-D__EXTENSIONS__") # Solaris doesn't pull these symbols in automatically @@ -28,8 +28,8 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro") set(PKG_LIBS "-lnsl -lsocket") elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "XL") - # The ibm/xl compiler does not appreciate this boost feature - target_compile_definitions(rmq PRIVATE BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) + # The ibm/xl compiler does not appreciate this Asio feature + target_compile_definitions(rmq PRIVATE ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) else() # In general the sunpro/xl warnings are not worth the bother set(CMAKE_COMPILE_WARNING_AS_ERROR ON) diff --git a/README.md b/README.md index dabb87c1..d7dacc86 100644 --- a/README.md +++ b/README.md @@ -66,12 +66,11 @@ graph TD; [rmqtestmocks](src/rmqtestmocks) | gmock types | Objects useful for testing applications using `rmqcpp` [rmqamqp](src/rmq/rmqamqp) | AMQP abstraction layer | All logic relating to amqp communication, framing, classes and state machines - connection, channel queue [rmqamqpt](src/rmq/rmqamqpt) | Low-level AMQP data types (from 0-9-1 spec) | Primitives of the AMQP standard, methods, frame, amqp types to C++ types mapping -[rmqio](src/rmq/rmqio) | IO abstraction layer | Raw socket connections management, reads/writes AMQP frames from/to the wire. Contains a set of async io interfaces, and an implementation using `boost::asio` +[rmqio](src/rmq/rmqio) | IO abstraction layer | Raw socket connections management, reads/writes AMQP frames from/to the wire. Contains a set of async io interfaces, and an implementation using `asio` ## Quick Start The quickest way to get started is to take a look at our integration tests and sample 'hello world' program, which is possible by following the Docker [Build](#building) steps and then: from the interactive shell window running `./build/examples/helloworld/rmqhelloworld_producer` - ## Usage ```cpp diff --git a/dockerfiles/dev.Dockerfile b/dockerfiles/dev.Dockerfile index d16354aa..341c37e7 100644 --- a/dockerfiles/dev.Dockerfile +++ b/dockerfiles/dev.Dockerfile @@ -8,7 +8,6 @@ RUN apt-get update && apt-get install -y \ gcc \ gdb \ git \ - libboost-dev \ libssl-dev \ net-tools \ netcat-traditional \ diff --git a/licenses-binary/LICENSE-boost-asio.txt b/licenses-binary/LICENSE-boost-asio.txt deleted file mode 100644 index 36b7cd93..00000000 --- a/licenses-binary/LICENSE-boost-asio.txt +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/licenses-binary/LICENSE-boost-iostreams.txt b/licenses-binary/LICENSE-boost-iostreams.txt deleted file mode 100644 index 36b7cd93..00000000 --- a/licenses-binary/LICENSE-boost-iostreams.txt +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/licenses/LICENSE-boost-asio.txt b/licenses/LICENSE-boost-asio.txt deleted file mode 100644 index 36b7cd93..00000000 --- a/licenses/LICENSE-boost-asio.txt +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/licenses/LICENSE-boost-iostreams.txt b/licenses/LICENSE-boost-iostreams.txt deleted file mode 100644 index 36b7cd93..00000000 --- a/licenses/LICENSE-boost-iostreams.txt +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f0518207..31c8a893 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,9 +1,9 @@ find_package(Threads REQUIRED) # CMake 3.26-rc3 Bug https://gitlab.kitware.com/cmake/cmake/-/issues/24505 find_package(ZLIB REQUIRED) -find_package(Boost REQUIRED) set(OPENSSL_USE_STATIC_LIBS TRUE) find_package(OpenSSL REQUIRED) find_package(GTest REQUIRED) +find_package(asio CONFIG REQUIRED) # BDE-required subpackages find_package(bal REQUIRED) diff --git a/src/rmq/rmqa/CMakeLists.txt b/src/rmq/rmqa/CMakeLists.txt index 26971d2c..33672283 100644 --- a/src/rmq/rmqa/CMakeLists.txt +++ b/src/rmq/rmqa/CMakeLists.txt @@ -33,11 +33,11 @@ target_link_libraries(rmqa PUBLIC ) if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro" ) # _RWSTD_ALLOCATOR tells the solaris header to define a std::allocator - # which conforms better to the C++ standard, which is expected by Boost. Without - # this, the library does not build due to missing std::allocator<..>::rebind + # which conforms better to the C++ standard; without this, the library does not + # build due to missing std::allocator<..>::rebind # "-D_XOPEN_SOURCE=500" "-D__EXTENSIONS__" tells the solaris sys/socket.h to conform - # better to what boost asio expects (to have a msg_flags member) + # better to what Asio expects (to have a msg_flags member) target_compile_definitions(rmqa PRIVATE _RWSTD_ALLOCATOR "-D_XOPEN_SOURCE=500" "-D__EXTENSIONS__") endif() diff --git a/src/rmq/rmqa/rmqa_rabbitcontextimpl.cpp b/src/rmq/rmqa/rmqa_rabbitcontextimpl.cpp index aa918ddf..8eb663b7 100644 --- a/src/rmq/rmqa/rmqa_rabbitcontextimpl.cpp +++ b/src/rmq/rmqa/rmqa_rabbitcontextimpl.cpp @@ -39,8 +39,6 @@ #include #include -#include - #include #include #include @@ -247,9 +245,13 @@ RabbitContextImpl::~RabbitContextImpl() << it->second.size() << " producers/consumers"; if (it->second.size() > 0) { - bsl::string channelsDebugInfo = - boost::algorithm::join(it->second, ", "); - + std::string channelsDebugInfo; + for (size_t i = 0; i < it->second.size(); ++i) { + if (i > 0) { + channelsDebugInfo += ", "; + } + channelsDebugInfo += it->second.at(i); + } logOutput << ": [" << channelsDebugInfo << "]. "; } } diff --git a/src/rmq/rmqa/rmqa_rabbitcontextoptions.h b/src/rmq/rmqa/rmqa_rabbitcontextoptions.h index 0001d2db..9ba6ab26 100644 --- a/src/rmq/rmqa/rmqa_rabbitcontextoptions.h +++ b/src/rmq/rmqa/rmqa_rabbitcontextoptions.h @@ -127,7 +127,7 @@ class RabbitContextOptions { RabbitContextOptions& useRabbitMQFieldValueEncoding(bool rabbitEncoding); /// \brief Shuffle endpoints rmq connects to. - /// By default, boost asio (libc) resolves and connects + /// By default, Asio (libc) resolves and connects /// to the node with longest matching subnet prefix /// causing disproportionately more connections with certain endpoints. /// Setting this option will shuffle resolver results. diff --git a/src/rmq/rmqamqp/CMakeLists.txt b/src/rmq/rmqamqp/CMakeLists.txt index 2301a639..1e29d27f 100644 --- a/src/rmq/rmqamqp/CMakeLists.txt +++ b/src/rmq/rmqamqp/CMakeLists.txt @@ -31,11 +31,11 @@ target_link_libraries(rmqamqp PUBLIC if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro" ) # _RWSTD_ALLOCATOR tells the solaris header to define a std::allocator - # which conforms better to the C++ standard, which is expected by Boost. Without - # this, the library does not build due to missing std::allocator<..>::rebind + # which conforms better to the C++ standard; without this, the library does not + # build due to missing std::allocator<..>::rebind # "-D_XOPEN_SOURCE=500" "-D__EXTENSIONS__" tells the solaris sys/socket.h to conform - # better to what boost asio expects (to have a msg_flags member) + # better to what Asio expects (to have a msg_flags member) target_compile_definitions(rmqamqp PRIVATE _RWSTD_ALLOCATOR "-D_XOPEN_SOURCE=500" "-D__EXTENSIONS__") endif() target_include_directories(rmqamqp PUBLIC .) diff --git a/src/rmq/rmqio/CMakeLists.txt b/src/rmq/rmqio/CMakeLists.txt index 31716c40..5bb6561f 100644 --- a/src/rmq/rmqio/CMakeLists.txt +++ b/src/rmq/rmqio/CMakeLists.txt @@ -29,22 +29,22 @@ target_link_libraries(rmqio PUBLIC bal rmqamqpt rmqt - Boost::boost + asio::asio ) if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro" ) # _RWSTD_ALLOCATOR tells the solaris header to define a std::allocator - # which conforms better to the C++ standard, which is expected by Boost. Without - # this, the library does not build due to missing std::allocator<..>::rebind + # which conforms better to the C++ standard; without this, the library does not + # build due to missing std::allocator<..>::rebind # "-D_XOPEN_SOURCE=500" "-D__EXTENSIONS__" tells the solaris sys/socket.h to conform - # better to what boost asio expects (to have a msg_flags member) + # better to what Asio expects (to have a msg_flags member) target_compile_definitions(rmqio PRIVATE _RWSTD_ALLOCATOR "-D_XOPEN_SOURCE=500" "-D__EXTENSIONS__") target_link_options(rmqio PUBLIC -lnsl -lsocket) endif() if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "XL") - target_compile_definitions(rmqio PRIVATE BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) + target_compile_definitions(rmqio PRIVATE ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) endif() target_include_directories(rmqio PUBLIC .) diff --git a/src/rmq/rmqio/rmqio_asioconnection.cpp b/src/rmq/rmqio/rmqio_asioconnection.cpp index cabf3661..b8a82970 100644 --- a/src/rmq/rmqio/rmqio_asioconnection.cpp +++ b/src/rmq/rmqio/rmqio_asioconnection.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include @@ -40,10 +40,10 @@ namespace { BALL_LOG_SET_NAMESPACE_CATEGORY("RMQIO.ASIOCONNECTION") -boost::asio::const_buffer +asio::const_buffer frame2buffer(const bsl::shared_ptr& frame) { - return boost::asio::const_buffer(frame->serialized(), frame->frameLength()); + return asio::const_buffer(frame->serialized(), frame->frameLength()); } bsl::size_t accumulateFun(bsl::size_t totalLen, @@ -73,8 +73,7 @@ bool prepareSocket(bsl::shared_ptr& socket) int newSocket; if ((newSocket = fcntl(s, F_DUPFD, 256)) != -1) { socket->lowest_layer().close(); - socket->lowest_layer().assign(boost::asio::ip::tcp::v4(), - newSocket); + socket->lowest_layer().assign(asio::ip::tcp::v4(), newSocket); } } BALL_LOG_DEBUG << "File descriptor is " @@ -82,24 +81,23 @@ bool prepareSocket(bsl::shared_ptr& socket) #endif BALL_LOG_DEBUG << "Turning on TCP_NODELAY & KEEP_ALIVE"; - boost::system::error_code ec; + asio::error_code ec; // Nagle must be disabled before the first send - socket->lowest_layer().set_option(boost::asio::ip::tcp::no_delay(true), ec); + socket->lowest_layer().set_option(asio::ip::tcp::no_delay(true), ec); if (ec) { BALL_LOG_ERROR << "Failed to set socket no_delay"; return false; } - ec = boost::system::error_code(); - socket->lowest_layer().set_option( - boost::asio::socket_base::keep_alive(true), ec); + ec = asio::error_code(); + socket->lowest_layer().set_option(asio::socket_base::keep_alive(true), ec); if (ec) { BALL_LOG_ERROR << "Failed to set socket keep_alive"; return false; } - ec = boost::system::error_code(); + ec = asio::error_code(); socket->lowest_layer().non_blocking(true, ec); if (ec) { BALL_LOG_ERROR << "Failed to set socket non-blocking"; @@ -135,14 +133,14 @@ void AsioConnection::startNextWrite() const bsl::vector >& framePtrs = d_writeQueue[0].second; - bsl::vector buffers; + bsl::vector buffers; buffers.reserve(framePtrs.size()); bsl::transform(framePtrs.cbegin(), framePtrs.cend(), bsl::back_inserter(buffers), &frame2buffer); - boost::asio::async_write( + asio::async_write( use_socket(*d_socket), buffers, bdlf::BindUtil::bind(&AsioConnection::handleWriteCb, @@ -173,10 +171,10 @@ bool AsioConnection::startRead() return false; } - boost::asio::async_read( + asio::async_read( use_socket(*d_socket), prepareBuffer(), - boost::asio::transfer_at_least(1), // read at least 1byte + asio::transfer_at_least(1), // read at least 1byte bdlf::BindUtil::bind(&AsioConnection::handleReadCb, AsioConnection::weak_from_this(), bdlf::PlaceHolders::_1, @@ -192,10 +190,10 @@ void AsioConnection::close(const DoneCallback& cb) { d_shutdown = cb; d_state = CLOSING; - boost::system::error_code ec; + asio::error_code ec; if (d_socket) { BALL_LOG_TRACE << "Shutting down socket"; - d_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); + d_socket->shutdown(asio::ip::tcp::socket::shutdown_both, ec); } if (ec) { BALL_LOG_WARN << "Failed to shutdown socket: " << ec; @@ -216,7 +214,7 @@ AsioConnection::AsioConnection( , d_frameDecoder(decoder) , d_shutdown() , d_state(CONNECTING) -, d_inbound(bsl::make_shared()) +, d_inbound(bsl::make_shared()) , d_writeQueue() { } @@ -234,7 +232,7 @@ AsioConnection::~AsioConnection() } template -void AsioConnection::handleWrite(boost::system::error_code error, +void AsioConnection::handleWrite(asio::error_code error, bsl::size_t bytes_transferred) { @@ -262,7 +260,7 @@ void AsioConnection::handleWrite(boost::system::error_code error, template void AsioConnection::handleWriteCb( const bsl::weak_ptr& weakSelf, - boost::system::error_code error, + asio::error_code error, bsl::size_t bytes_transferred, const bsl::shared_ptr&) { @@ -281,10 +279,10 @@ void AsioConnection::handleWriteCb( template void AsioConnection::handleReadCb( const bsl::weak_ptr& weakSelf, - boost::system::error_code error, // Result of operation. + asio::error_code error, // Result of operation. bsl::size_t bytes_transferred, // Number of bytes received. const bsl::shared_ptr&, - const bsl::shared_ptr&) + const bsl::shared_ptr&) { // Extend socket/buffer lifetime to the end of this completion handler @@ -299,7 +297,7 @@ void AsioConnection::handleReadCb( } template -void AsioConnection::handleRead(boost::system::error_code error, +void AsioConnection::handleRead(asio::error_code error, bsl::size_t bytes_transferred) { @@ -318,7 +316,7 @@ void AsioConnection::handleRead(boost::system::error_code error, template <> bool AsioConnection::handleSecureError( - boost::system::error_code) + asio::error_code) { d_socket->socket().async_shutdown(bdlf::BindUtil::bind( &AsioConnection::handleCloseCb, @@ -329,17 +327,17 @@ bool AsioConnection::handleSecureError( } template -bool AsioConnection::handleSecureError(boost::system::error_code) +bool AsioConnection::handleSecureError(asio::error_code) { return false; } template void AsioConnection::handleReadError( - boost::system::error_code error) + asio::error_code error) { switch (error.value()) { - case boost::asio::error::eof: + case asio::error::eof: if (d_state == CLOSING) { BALL_LOG_DEBUG << "Received EOF from broker (Already Closing)"; } @@ -347,7 +345,7 @@ void AsioConnection::handleReadError( BALL_LOG_DEBUG << "Received unexpected EOF from remote peer"; } break; - case boost::asio::error::operation_aborted: + case asio::error::operation_aborted: if (d_state == CLOSING) { BALL_LOG_DEBUG << "Callback Cancelled (operation aborted): " "graceful shutdown"; @@ -358,9 +356,9 @@ void AsioConnection::handleReadError( << d_state; } break; - case boost::asio::ssl::error::stream_truncated: // ungraceful TLS stream - // termination - if (error.category() == boost::asio::error::get_ssl_category()) { + case asio::ssl::error::stream_truncated: // ungraceful TLS stream + // termination + if (error.category() == asio::error::get_ssl_category()) { bsl::ostringstream tlsError; char buf[128] = {}; ERR_error_string_n(error.value(), buf, sizeof(buf)); @@ -370,7 +368,7 @@ void AsioConnection::handleReadError( } break; default: - if (error.category() == boost::asio::error::get_ssl_category()) { + if (error.category() == asio::error::get_ssl_category()) { bsl::ostringstream tlsError; tlsError << error.message() << ": "; @@ -394,14 +392,14 @@ void AsioConnection::handleReadError( } template -void AsioConnection::handleError(boost::system::error_code error) +void AsioConnection::handleError(asio::error_code error) { switch (error.value()) { - case boost::asio::error::eof: + case asio::error::eof: BALL_LOG_DEBUG << "Socket closed: " << error.message() << ". Current state: " << d_state; break; - case boost::asio::error::operation_aborted: + case asio::error::operation_aborted: BALL_LOG_DEBUG << "Socket closed: " << error.message() << ". Current state: " << d_state; break; @@ -423,7 +421,7 @@ bool AsioConnection::isConnected() const } template -const boost::asio::streambuf::mutable_buffers_type +const asio::streambuf::mutable_buffers_type AsioConnection::prepareBuffer() { return d_inbound->prepare(d_frameDecoder->maxFrameSize()); @@ -439,16 +437,15 @@ bool AsioConnection::doRead(bsl::size_t bytes_transferred) d_inbound->commit(bytes_transferred); - bsl::size_t bytes_decoded = 0; - boost::asio::streambuf::const_buffers_type bufs = d_inbound->data(); + bsl::size_t bytes_decoded = 0; + asio::streambuf::const_buffers_type bufs = d_inbound->data(); bsl::vector readFrames; - for (const boost::asio::const_buffer* it = - boost::asio::buffer_sequence_begin(bufs); - it != boost::asio::buffer_sequence_end(bufs); + for (const asio::const_buffer* it = asio::buffer_sequence_begin(bufs); + it != asio::buffer_sequence_end(bufs); ++it) { - const boost::asio::const_buffer& buffer = *it; - Decoder::ReturnCode rcode = d_frameDecoder->appendBytes( + const asio::const_buffer& buffer = *it; + Decoder::ReturnCode rcode = d_frameDecoder->appendBytes( &readFrames, buffer.data(), buffer.size()); if (rcode != Decoder::OK) { BALL_LOG_WARN << "Bad rcode from decoder: " << rcode; @@ -471,13 +468,13 @@ bool AsioConnection::doRead(bsl::size_t bytes_transferred) template void AsioConnection::handleCloseCb( const bsl::weak_ptr& weakSelf, - boost::system::error_code error, // Result of operation. + asio::error_code error, // Result of operation. const bsl::shared_ptr&) { // Extend socket lifetime to the end of this completion handler BALL_LOG_TRACE << "async_shutdown: " << error.message(); - if (error && error.value() != boost::asio::ssl::error::stream_truncated) { + if (error && error.value() != asio::ssl::error::stream_truncated) { BALL_LOG_INFO << "rcode with async_shutdown: " << error.message(); } diff --git a/src/rmq/rmqio/rmqio_asioconnection.h b/src/rmq/rmqio/rmqio_asioconnection.h index f5ba2b4f..07ee00c7 100644 --- a/src/rmq/rmqio/rmqio_asioconnection.h +++ b/src/rmq/rmqio/rmqio_asioconnection.h @@ -29,8 +29,7 @@ #include #include -#include -#include +#include namespace BloombergLP { namespace rmqio { @@ -60,36 +59,35 @@ class AsioConnection protected: static void handleWriteCb(const bsl::weak_ptr& weakSelf, - boost::system::error_code error, + asio::error_code error, bsl::size_t bytes_transferred, const bsl::shared_ptr& socketLifetime); - void handleWrite(boost::system::error_code error, - bsl::size_t bytes_transferred); + void handleWrite(asio::error_code error, bsl::size_t bytes_transferred); static void handleReadCb(const bsl::weak_ptr& weakSelf, - boost::system::error_code error, // Result of operation. + asio::error_code error, // Result of operation. bsl::size_t bytes_transferred, // Number of bytes received. const bsl::shared_ptr& socketLifetime, - const bsl::shared_ptr& bufferLifetime); + const bsl::shared_ptr& bufferLifetime); - void handleRead(boost::system::error_code error, // Result of operation. + void handleRead(asio::error_code error, // Result of operation. bsl::size_t bytes_transferred // Number of bytes received. ); bool doRead(bsl::size_t bytes_transferred); - void handleReadError(boost::system::error_code error); + void handleReadError(asio::error_code error); - bool handleSecureError(boost::system::error_code error); + bool handleSecureError(asio::error_code error); - void handleError(boost::system::error_code error); + void handleError(asio::error_code error); - const boost::asio::streambuf::mutable_buffers_type prepareBuffer(); + const asio::streambuf::mutable_buffers_type prepareBuffer(); static void handleCloseCb(const bsl::weak_ptr& weakSelf, - boost::system::error_code error, + asio::error_code error, const bsl::shared_ptr& socketLifetime); void doClose(ReturnCode e = Connection::DISCONNECTED_ERROR); @@ -106,7 +104,7 @@ class AsioConnection bslma::ManagedPtr d_frameDecoder; bsl::optional d_shutdown; State d_state; - bsl::shared_ptr d_inbound; + bsl::shared_ptr d_inbound; typedef bsl::pair > > diff --git a/src/rmq/rmqio/rmqio_asioeventloop.cpp b/src/rmq/rmqio/rmqio_asioeventloop.cpp index 823774b1..b39b22b7 100644 --- a/src/rmq/rmqio/rmqio_asioeventloop.cpp +++ b/src/rmq/rmqio/rmqio_asioeventloop.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include @@ -35,7 +35,7 @@ BALL_LOG_SET_NAMESPACE_CATEGORY("RMQIO.ASIOEVENTLOOP") AsioEventLoop::AsioEventLoop() : EventLoop() , d_context() -, d_workGuard(boost::asio::make_work_guard(d_context)) +, d_workGuard(asio::make_work_guard(d_context)) , d_resolver() , d_timerFactory() , d_mutex() @@ -110,12 +110,12 @@ void AsioEventLoop::onThreadStarted() void AsioEventLoop::postImpl(const Item& item) { - boost::asio::post(d_context, item); + asio::post(d_context, item); } void AsioEventLoop::dispatchImpl(const Item& item) { - boost::asio::dispatch(d_context, item); + asio::dispatch(d_context, item); } bsl::shared_ptr diff --git a/src/rmq/rmqio/rmqio_asioeventloop.h b/src/rmq/rmqio/rmqio_asioeventloop.h index e3a2dffe..4e1f8144 100644 --- a/src/rmq/rmqio/rmqio_asioeventloop.h +++ b/src/rmq/rmqio/rmqio_asioeventloop.h @@ -18,7 +18,7 @@ #include -#include +#include #include #include #include @@ -32,8 +32,8 @@ class Resolver; class TimerFactory; class AsioEventLoop : public EventLoop { - boost::asio::io_context d_context; - boost::asio::executor_work_guard + asio::io_context d_context; + asio::executor_work_guard d_workGuard; bsl::shared_ptr d_resolver; bsl::shared_ptr d_timerFactory; @@ -50,7 +50,7 @@ class AsioEventLoop : public EventLoop { bool waitForEventLoopExit(int64_t waitTimeSec) BSLS_KEYWORD_OVERRIDE BSLS_KEYWORD_FINAL; - boost::asio::io_context& context() { return d_context; } + asio::io_context& context() { return d_context; } bsl::shared_ptr resolver(bool shuffleConnectionEndpoints) BSLS_KEYWORD_OVERRIDE; diff --git a/src/rmq/rmqio/rmqio_asioresolver.cpp b/src/rmq/rmqio/rmqio_asioresolver.cpp index e986d054..c4e491f6 100644 --- a/src/rmq/rmqio/rmqio_asioresolver.cpp +++ b/src/rmq/rmqio/rmqio_asioresolver.cpp @@ -27,9 +27,6 @@ #include #include -#include -#include - #include #include #include @@ -47,7 +44,7 @@ namespace rmqio { namespace { BALL_LOG_SET_NAMESPACE_CATEGORY("RMQIO.ASIORESOLVER") -typedef bsl::function ConnectHandler; @@ -102,7 +99,7 @@ void logTlsConnectionAlert(const SSL* s, int where, int ret) } bool logCertVerificationFailure(bool preverified, - boost::asio::ssl::verify_context& ctx) + asio::ssl::verify_context& ctx) { if (!preverified) { char subject_name[256]; @@ -118,11 +115,11 @@ bool logCertVerificationFailure(bool preverified, return preverified; } -bsl::string augmentTlsError(const boost::system::error_code& ec) +bsl::string augmentTlsError(const asio::error_code& ec) { bsl::string err = ec.message(); - if (ec.category() == boost::asio::error::get_ssl_category()) { + if (ec.category() == asio::error::get_ssl_category()) { err += " (" + bsl::to_string(ERR_GET_LIB(ec.value())) + "," + bsl::to_string(ERR_GET_REASON(ec.value())) + ") "; @@ -134,7 +131,7 @@ bsl::string augmentTlsError(const boost::system::error_code& ec) return err; } -void handleTLSHandshake(boost::system::error_code error, +void handleTLSHandshake(asio::error_code error, const bsl::string& host, const Resolver::ErrorCallback& onFail, const ConnectHandler& afterHandshake, @@ -153,7 +150,7 @@ void handleTLSHandshake(boost::system::error_code error, void startTLSHandshake( const bsl::string& host, - boost::system::error_code error, + asio::error_code error, AsioResolver::results_type::iterator endpoint, const bsl::shared_ptr& socketWrapper, const Resolver::ErrorCallback& onFail, @@ -166,7 +163,7 @@ void startTLSHandshake( << ", starting TLS Handshake"; socketWrapper->socket().async_handshake( - boost::asio::ssl::stream_base::client, + asio::ssl::stream_base::client, bdlf::BindUtil::bind(&handleTLSHandshake, bdlf::PlaceHolders::_1, host, @@ -181,31 +178,30 @@ void startTLSHandshake( } } -bsl::shared_ptr +bsl::shared_ptr createSecureContext(const bsl::shared_ptr& params) { - bsl::shared_ptr result = - bsl::make_shared( - boost::asio::ssl::context::tls_client); + bsl::shared_ptr result = + bsl::make_shared(asio::ssl::context::tls_client); bool fail = false; - boost::system::error_code ec; - result->set_verify_mode(boost::asio::ssl::verify_peer, ec); + asio::error_code ec; + result->set_verify_mode(asio::ssl::verify_peer, ec); if (ec) { BALL_LOG_ERROR << "Error setting verify mode: " << ec; fail = true; ec.clear(); } - boost::asio::ssl::context::options tls_options( - boost::asio::ssl::context::default_workarounds | - boost::asio::ssl::context::single_dh_use); + asio::ssl::context::options tls_options( + asio::ssl::context::default_workarounds | + asio::ssl::context::single_dh_use); switch (params->method()) { case rmqt::SecurityParameters::TLS_1_2_OR_BETTER: - tls_options |= (boost::asio::ssl::context::no_sslv2 | - boost::asio::ssl::context::no_sslv3 | - boost::asio::ssl::context::no_tlsv1 | - boost::asio::ssl::context::no_tlsv1_1); + tls_options |= (asio::ssl::context::no_sslv2 | + asio::ssl::context::no_sslv3 | + asio::ssl::context::no_tlsv1 | + asio::ssl::context::no_tlsv1_1); break; } @@ -219,7 +215,7 @@ createSecureContext(const bsl::shared_ptr& params) switch (params->verification()) { case rmqt::SecurityParameters::MUTUAL: result->use_private_key_file( - params->clientKeyPath(), boost::asio::ssl::context::pem, ec); + params->clientKeyPath(), asio::ssl::context::pem, ec); if (ec) { BALL_LOG_ERROR << "Error using Client Key File: " << params->clientKeyPath() @@ -311,7 +307,7 @@ AsioResolver::asyncConnect(const bsl::string& host, d_resolver.async_resolve( host.c_str(), bsl::to_string(port).c_str(), - boost::asio::ip::resolver_query_base::numeric_service, + asio::ip::resolver_base::numeric_service, bdlf::BindUtil::bind( &AsioResolver::handleResolveCb, weak_from_this(), @@ -337,7 +333,7 @@ bsl::shared_ptr AsioResolver::asyncSecureConnect( const ErrorCallback& onFail) { bsl::shared_ptr > connection; - bsl::shared_ptr secureContext = + bsl::shared_ptr secureContext = createSecureContext(securityParameters); if (!secureContext) { BALL_LOG_ERROR << "Failed to setup TLS client with parameters: [" @@ -357,7 +353,7 @@ bsl::shared_ptr AsioResolver::asyncSecureConnect( d_resolver.async_resolve( host.c_str(), bsl::to_string(port).c_str(), - boost::asio::ip::resolver_query_base::numeric_service, + asio::ip::resolver_base::numeric_service, bdlf::BindUtil::bind( &AsioResolver::handleResolveCb, weak_from_this(), @@ -402,7 +398,7 @@ void AsioResolver::startConnect( onSuccess, onFail); - boost::asio::async_connect( + asio::async_connect( socket->lowest_layer(), resolverResults.begin(), resolverResults.end(), @@ -433,7 +429,7 @@ void AsioResolver::startConnect( return; } - boost::asio::async_connect( + asio::async_connect( *socket, resolverResults.begin(), resolverResults.end(), @@ -451,7 +447,7 @@ void AsioResolver::startConnect( template void AsioResolver::handleConnect( const bsl::string& host, - boost::system::error_code error, + asio::error_code error, AsioResolver::results_type::iterator endpoint, const bsl::weak_ptr >& weakConnection, const NewConnectionCallback& onSuccess, @@ -492,16 +488,17 @@ void AsioResolver::shuffleResolverResults( const bsl::string& host, const bsl::string& port) { - if (shuffleConnectionEndpoints && resolverResults.size()) { - typedef boost::asio::ip::basic_resolver_entry - entry_type; + if (shuffleConnectionEndpoints && !resolverResults.empty()) { + typedef asio::ip::basic_resolver_entry entry_type; // 1. copy endpoint entries to a vector to shuffle bsl::vector entries(resolverResults.size()); - bsl::copy( - resolverResults.begin(), resolverResults.end(), entries.begin()); + bsl::copy(resolverResults.begin(), resolverResults.end(), entries.begin()); - // 2. shuffle vector (c++ standard dependent) - boost::range::random_shuffle(entries, g); + // 2. Fisher-Yates shuffle using provided generator + for (bsl::ptrdiff_t i = static_cast(entries.size()) - 1; i > 0; --i) { + bsl::ptrdiff_t j = g(i + 1); // 0..i + bsl::swap(entries[static_cast(i)], entries[static_cast(j)]); + } // 3. re-create shuffled results_type resolverResults = AsioResolver::results_type::create( @@ -513,7 +510,7 @@ template void AsioResolver::handleResolve( const bsl::string& host, const bsl::string& port, - boost::system::error_code error, + asio::error_code error, AsioResolver::results_type resolverResults, const bsl::weak_ptr >& weakConnection, const bsl::weak_ptr& weakSocket, @@ -551,7 +548,7 @@ template void AsioResolver::handleConnectCb( bsl::weak_ptr weakSelf, const bsl::string& host, - boost::system::error_code error, + asio::error_code error, AsioResolver::results_type::iterator endpoint, const bsl::weak_ptr >& connection, const bsl::shared_ptr& socketLifetime, @@ -579,7 +576,7 @@ void AsioResolver::handleResolveCb( bsl::weak_ptr weakSelf, const bsl::string& host, const bsl::string& port, - boost::system::error_code error, + asio::error_code error, AsioResolver::results_type resolver_results, const bsl::weak_ptr >& weakConnection, const bsl::weak_ptr& weakSocket, diff --git a/src/rmq/rmqio/rmqio_asioresolver.h b/src/rmq/rmqio/rmqio_asioresolver.h index 31855d33..22c6860c 100644 --- a/src/rmq/rmqio/rmqio_asioresolver.h +++ b/src/rmq/rmqio/rmqio_asioresolver.h @@ -34,9 +34,8 @@ #include #include -#include -#include -#include +#include +#include #include @@ -99,7 +98,7 @@ class AsioResolver : public Resolver, const NewConnectionCallback& onSuccess, const ErrorCallback& onFail); - typedef boost::asio::ip::tcp::resolver::results_type results_type; + typedef asio::ip::tcp::resolver::results_type results_type; static void shuffleResolverResults(results_type& resolverResults, bool shuffleConnectionEndpoints, @@ -122,7 +121,7 @@ class AsioResolver : public Resolver, template void handleConnect( const bsl::string& host, - boost::system::error_code error, + asio::error_code error, AsioResolver::results_type::iterator endpoint, const bsl::weak_ptr >& weakConnection, const NewConnectionCallback& onSuccess, @@ -132,7 +131,7 @@ class AsioResolver : public Resolver, static void handleConnectCb( bsl::weak_ptr weakSelf, const bsl::string& host, - boost::system::error_code error, + asio::error_code error, AsioResolver::results_type::iterator endpoint, const bsl::weak_ptr >& weakConnection, const bsl::shared_ptr& socketLifetime, @@ -142,7 +141,7 @@ class AsioResolver : public Resolver, template static void handleHandshakeCb( bsl::weak_ptr weakSelf, - boost::system::error_code error, + asio::error_code error, const bsl::weak_ptr >& weakConnection, const bsl::shared_ptr& socketLifetime, const NewConnectionCallback& onSuccess, @@ -152,7 +151,7 @@ class AsioResolver : public Resolver, void handleResolve( const bsl::string& host, const bsl::string& port, - boost::system::error_code error, + asio::error_code error, AsioResolver::results_type resolverResults, const bsl::weak_ptr >& weakConnection, const bsl::weak_ptr& weakSocket, @@ -164,7 +163,7 @@ class AsioResolver : public Resolver, bsl::weak_ptr weakSelf, const bsl::string& host, const bsl::string& port, - boost::system::error_code error, + asio::error_code error, AsioResolver::results_type resolver_results, const bsl::weak_ptr >& weakConnection, const bsl::weak_ptr& weakSocket, @@ -177,7 +176,7 @@ class AsioResolver : public Resolver, } private: - boost::asio::ip::tcp::resolver d_resolver; + asio::ip::tcp::resolver d_resolver; bool d_shuffleConnectionEndpoints; }; diff --git a/src/rmq/rmqio/rmqio_asiosocketwrapper.h b/src/rmq/rmqio/rmqio_asiosocketwrapper.h index 76c0ed57..c7e74bf2 100644 --- a/src/rmq/rmqio/rmqio_asiosocketwrapper.h +++ b/src/rmq/rmqio/rmqio_asiosocketwrapper.h @@ -16,9 +16,8 @@ #ifndef INCLUDED_RMQIO_ASIOSOCKETWRAPPER #define INCLUDED_RMQIO_ASIOSOCKETWRAPPER -#include -#include -#include +#include +#include #include #include @@ -27,14 +26,14 @@ namespace BloombergLP { namespace rmqio { -typedef boost::asio::ip::tcp::socket AsioSocket; -typedef boost::asio::ssl::stream AsioSSLSocket; +typedef asio::ip::tcp::socket AsioSocket; +typedef asio::ssl::stream AsioSSLSocket; class AsioSecureSocketWrapper { public: AsioSecureSocketWrapper( AsioSSLSocket::executor_type executor, - const bsl::shared_ptr& context) + const bsl::shared_ptr& context) : d_context(context) , d_socket(bsl::make_shared(executor, bsl::ref(*d_context))) { @@ -42,7 +41,7 @@ class AsioSecureSocketWrapper { void close() { - boost::system::error_code ec; + asio::error_code ec; d_socket->lowest_layer().close(ec); if (ec) { @@ -56,12 +55,12 @@ class AsioSecureSocketWrapper { { return d_socket->lowest_layer(); } - void shutdown(int /*not in ssl api*/, boost::system::error_code& ec) + void shutdown(int /*not in ssl api*/, asio::error_code& ec) { // This will cause the receive loop to terminate with short read err, // this is the TLS equivalent of EOF d_socket->lowest_layer().shutdown( - boost::asio::ip::tcp::socket::shutdown_receive, ec); + asio::ip::tcp::socket::shutdown_receive, ec); if (ec) { BALL_LOG_SET_CATEGORY("RMQIO.ASIOSOCKETWRAPPER"); BALL_LOG_WARN << "Failed to Shutdown TLS cleanly: " << ec.message(); @@ -73,7 +72,7 @@ class AsioSecureSocketWrapper { AsioSSLSocket& socket() { return *d_socket; } private: - bsl::shared_ptr d_context; + bsl::shared_ptr d_context; bsl::shared_ptr d_socket; }; diff --git a/src/rmq/rmqio/rmqio_asiotimer.h b/src/rmq/rmqio/rmqio_asiotimer.h index b649b157..b0c60ebe 100644 --- a/src/rmq/rmqio/rmqio_asiotimer.h +++ b/src/rmq/rmqio/rmqio_asiotimer.h @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include @@ -31,7 +31,7 @@ namespace BloombergLP { namespace rmqio { -//@PURPOSE: Timer implementation using ASIO deadline_timer +//@PURPOSE: Timer implementation using ASIO steady_timer // //@CLASSES: // rmqio::AsioTimerFactory: Provides a factory for creating AsioTimers @@ -39,48 +39,38 @@ namespace rmqio { // rmqio::AsioTimer: Provides a class for scheduling a cancellable // callback to be executed after a given timeout -template > -class basic_AsioTimer +class AsioTimer : public Timer, - public bsl::enable_shared_from_this > { + public bsl::enable_shared_from_this { public: - basic_AsioTimer(boost::asio::io_context& context, - const bsls::TimeInterval& timeout); - basic_AsioTimer(boost::asio::io_context& context, - const Timer::Callback& callback); - virtual ~basic_AsioTimer() BSLS_KEYWORD_OVERRIDE; + AsioTimer(asio::io_context& context, const bsls::TimeInterval& timeout); + AsioTimer(asio::io_context& context, const Timer::Callback& callback); + virtual ~AsioTimer() BSLS_KEYWORD_OVERRIDE; virtual void reset(const bsls::TimeInterval& timeout) BSLS_KEYWORD_OVERRIDE; virtual void cancel() BSLS_KEYWORD_OVERRIDE; virtual void resetCallback(const Callback& callback) BSLS_KEYWORD_OVERRIDE; virtual void start(const Timer::Callback& callback) BSLS_KEYWORD_OVERRIDE; private: - basic_AsioTimer(basic_AsioTimer&) BSLS_KEYWORD_DELETED; - basic_AsioTimer& operator=(const basic_AsioTimer&) BSLS_KEYWORD_DELETED; - - static void - handler_internal(bsl::weak_ptr > timer, - const Timer::Callback callback, - const boost::system::error_code& error); - void handler(const Timer::Callback& callback, - const boost::system::error_code& error); + AsioTimer(AsioTimer&) BSLS_KEYWORD_DELETED; + AsioTimer& operator=(const AsioTimer&) BSLS_KEYWORD_DELETED; + + static void handler_internal(bsl::weak_ptr timer, + const Timer::Callback callback, + const asio::error_code& error); + void handler(const Timer::Callback& callback, const asio::error_code& error); void startTimer(); - boost::asio::basic_deadline_timer d_timer; + asio::steady_timer d_timer; Timer::Callback d_callback; bsls::TimeInterval d_timeout; BALL_LOG_SET_CLASS_CATEGORY("RMQIO.ASIOTIMER"); }; -typedef basic_AsioTimer<> AsioTimer; - -template > -class basic_AsioTimerFactory : public TimerFactory { +class AsioTimerFactory : public TimerFactory { public: - basic_AsioTimerFactory(rmqio::AsioEventLoop& eventLoop); - virtual ~basic_AsioTimerFactory() BSLS_KEYWORD_OVERRIDE {} + AsioTimerFactory(rmqio::AsioEventLoop& eventLoop); + virtual ~AsioTimerFactory() BSLS_KEYWORD_OVERRIDE {} virtual bsl::shared_ptr createWithTimeout(const bsls::TimeInterval& timeout) BSLS_KEYWORD_OVERRIDE; @@ -93,11 +83,11 @@ class basic_AsioTimerFactory : public TimerFactory { BALL_LOG_SET_CLASS_CATEGORY("RMQIO.ASIOTIMERFACTORY"); }; -typedef basic_AsioTimerFactory<> AsioTimerFactory; - -template -basic_AsioTimer::basic_AsioTimer(boost::asio::io_context& io_context, - const bsls::TimeInterval& timeout) +//================ +// AsioTimer impl +//================ +inline AsioTimer::AsioTimer(asio::io_context& io_context, + const bsls::TimeInterval& timeout) : Timer() , d_timer(io_context) , d_callback() @@ -105,9 +95,8 @@ basic_AsioTimer::basic_AsioTimer(boost::asio::io_context& io_context, { } -template -basic_AsioTimer::basic_AsioTimer(boost::asio::io_context& io_context, - const Timer::Callback& callback) +inline AsioTimer::AsioTimer(asio::io_context& io_context, + const Timer::Callback& callback) : Timer() , d_timer(io_context) , d_callback(callback) @@ -115,13 +104,9 @@ basic_AsioTimer::basic_AsioTimer(boost::asio::io_context& io_context, { } -template -basic_AsioTimer::~basic_AsioTimer() -{ -} +inline AsioTimer::~AsioTimer() {} -template -void basic_AsioTimer::reset(const bsls::TimeInterval& timeout) +inline void AsioTimer::reset(const bsls::TimeInterval& timeout) { if (!d_callback) { BALL_LOG_ERROR << "reset() called before start()"; @@ -131,46 +116,37 @@ void basic_AsioTimer::reset(const bsls::TimeInterval& timeout) startTimer(); } -template -void basic_AsioTimer::cancel() -{ - d_timer.cancel(); -} +inline void AsioTimer::cancel() { d_timer.cancel(); } -template -void basic_AsioTimer::resetCallback(const Callback& callback) +inline void AsioTimer::resetCallback(const Callback& callback) { d_callback = callback; } -template -void basic_AsioTimer::start(const Timer::Callback& callback) +inline void AsioTimer::start(const Timer::Callback& callback) { d_callback = callback; startTimer(); } -template -void basic_AsioTimer::handler_internal( - bsl::weak_ptr > timer, - const Timer::Callback callback, - const boost::system::error_code& error) +inline void AsioTimer::handler_internal(bsl::weak_ptr timer, + const Timer::Callback callback, + const asio::error_code& error) { - bsl::shared_ptr > t = timer.lock(); + bsl::shared_ptr t = timer.lock(); if (t) { t->handler(callback, error); } } -template -void basic_AsioTimer::handler(const Timer::Callback& callback, - const boost::system::error_code& error) +inline void AsioTimer::handler(const Timer::Callback& callback, + const asio::error_code& error) { - if (!error && d_timer.expires_at() <= TT::now()) { + if (!error) { callback(Timer::EXPIRE); } else { - if (error != boost::asio::error::operation_aborted) { + if (error != asio::error::operation_aborted) { BALL_LOG_ERROR << "Unexpected error code: " << error; } // Cancelled @@ -178,39 +154,36 @@ void basic_AsioTimer::handler(const Timer::Callback& callback, } } -template -void basic_AsioTimer::startTimer() +inline void AsioTimer::startTimer() { - d_timer.expires_from_now( - boost::posix_time::milliseconds(d_timeout.totalMilliseconds())); - d_timer.async_wait( - bdlf::BindUtil::bind(&basic_AsioTimer::handler_internal, - this->weak_from_this(), - d_callback, - bdlf::PlaceHolders::_1)); + using namespace std::chrono; + d_timer.expires_after(milliseconds(d_timeout.totalMilliseconds())); + d_timer.async_wait(bdlf::BindUtil::bind(&AsioTimer::handler_internal, + this->weak_from_this(), + d_callback, + bdlf::PlaceHolders::_1)); } -template -basic_AsioTimerFactory::basic_AsioTimerFactory( - rmqio::AsioEventLoop& eventLoop) +//========================= +// AsioTimerFactory impl +//========================= +inline AsioTimerFactory::AsioTimerFactory(rmqio::AsioEventLoop& eventLoop) : d_eventLoop(eventLoop) { } -template -bsl::shared_ptr basic_AsioTimerFactory::createWithTimeout( - const bsls::TimeInterval& timeout) +inline bsl::shared_ptr +AsioTimerFactory::createWithTimeout(const bsls::TimeInterval& timeout) { - return bsl::make_shared >( - bsl::ref(d_eventLoop.context()), timeout); + return bsl::make_shared(bsl::ref(d_eventLoop.context()), + timeout); } -template -bsl::shared_ptr basic_AsioTimerFactory::createWithCallback( - const Timer::Callback& callback) +inline bsl::shared_ptr +AsioTimerFactory::createWithCallback(const Timer::Callback& callback) { - return bsl::make_shared >( - bsl::ref(d_eventLoop.context()), callback); + return bsl::make_shared(bsl::ref(d_eventLoop.context()), + callback); } } // namespace rmqio diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 22d280d6..cc3d7e95 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,10 +1,10 @@ if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro" ) # _RWSTD_ALLOCATOR tells the solaris header to define a std::allocator - # which conforms better to the C++ standard, which is expected by Boost. Without - # this, the library does not build due to missing std::allocator<..>::rebind + # which conforms better to the C++ standard; without this, the library does not + # build due to missing std::allocator<..>::rebind # "-D_XOPEN_SOURCE=500" "-D__EXTENSIONS__" tells the solaris sys/socket.h to conform - # better to what boost asio expects (to have a msg_flags member) + # better to what Asio expects (to have a msg_flags member) add_compile_options(_RWSTD_ALLOCATOR "-D_XOPEN_SOURCE=500" "-D__EXTENSIONS__") endif() diff --git a/src/tests/rmqamqp/rmqamqp_connection.t.cpp b/src/tests/rmqamqp/rmqamqp_connection.t.cpp index 97621f5c..c320ed31 100644 --- a/src/tests/rmqamqp/rmqamqp_connection.t.cpp +++ b/src/tests/rmqamqp/rmqamqp_connection.t.cpp @@ -50,6 +50,7 @@ #include #include #include +#include using namespace BloombergLP; using namespace rmqamqp; @@ -102,7 +103,7 @@ class MockConnection : public rmqio::Connection { public: MockConnection(const rmqio::Connection::Callbacks& callbacks, ReplayFrame& replayFrame, - boost::asio::io_context& eventLoop) + asio::io_context& eventLoop) : d_replayFrame(replayFrame) , d_connectionCallbacks(callbacks) , d_eventLoop(eventLoop) @@ -147,7 +148,7 @@ class MockConnection : public rmqio::Connection { BSLS_ASSERT_OPT(rc == Frame::OK); - boost::asio::post( + asio::post( d_eventLoop, bdlf::BindUtil::bind(d_connectionCallbacks.onRead, decoded)); } @@ -157,7 +158,7 @@ class MockConnection : public rmqio::Connection { { BALL_LOG_TRACE << "MockConnection close"; - boost::asio::post(d_eventLoop, + asio::post(d_eventLoop, bdlf::BindUtil::bind(cb, GRACEFUL_DISCONNECT)); } @@ -177,7 +178,7 @@ class MockConnection : public rmqio::Connection { rmqamqpt::Method( rmqamqpt::ConnectionMethod(rmqamqpt::ConnectionCloseOk()))); - boost::asio::post(d_eventLoop, callback); + asio::post(d_eventLoop, callback); if (!closeOk) { feedNextFrame(); @@ -195,7 +196,7 @@ class MockConnection : public rmqio::Connection { ReplayFrame& d_replayFrame; rmqio::Connection::Callbacks d_connectionCallbacks; - boost::asio::io_context& d_eventLoop; + asio::io_context& d_eventLoop; }; class MockHeartbeatManager : public rmqamqp::HeartbeatManager { @@ -303,7 +304,7 @@ ACTION_P3(ConnectMockConnection, mockConnectPtrPtr, replayFrame, eventLoop) ON_CALL(**mockConnectPtrPtr, isConnected()).WillByDefault(Return(true)); - boost::asio::post(eventLoop.get(), arg4); + asio::post(eventLoop.get(), arg4); return *mockConnectPtrPtr; } @@ -388,7 +389,7 @@ class ConnectionTests : public ::testing::Test { bsl::vector > d_vhostTag; - boost::asio::io_context d_eventLoop; + asio::io_context d_eventLoop; ConnectionTests() : d_replayFrame() @@ -1232,6 +1233,8 @@ TEST_F(ConnectionTests, PublishReconnectTimeMetric) d_eventLoop.run(); d_eventLoop.restart(); + EXPECT_THAT(d_replayFrame.getLength(), Eq(0)); + EXPECT_CALL(*d_channelFactory, createReceiveChannel(_, _, _, _, _, _, _, _, _)) .WillOnce(DoAll(ReceiveChannelCreated(bsl::ref(d_channelFactory)), diff --git a/src/tests/rmqio/CMakeLists.txt b/src/tests/rmqio/CMakeLists.txt index fedd3c40..4ad09616 100644 --- a/src/tests/rmqio/CMakeLists.txt +++ b/src/tests/rmqio/CMakeLists.txt @@ -28,16 +28,16 @@ target_link_libraries(rmqio_tests PUBLIC if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro" ) # _RWSTD_ALLOCATOR tells the solaris header to define a std::allocator - # which conforms better to the C++ standard, which is expected by Boost. Without - # this, the library does not build due to missing std::allocator<..>::rebind + # which conforms better to the C++ standard; without this, the library does not + # build due to missing std::allocator<..>::rebind # "-D_XOPEN_SOURCE=500" "-D__EXTENSIONS__" tells the solaris sys/socket.h to conform - # better to what boost asio expects (to have a msg_flags member) + # better to what Asio expects (to have a msg_flags member) target_compile_definitions(rmqio_tests PRIVATE _RWSTD_ALLOCATOR "-D_XOPEN_SOURCE=500" "-D__EXTENSIONS__") endif() if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "XL") - target_compile_definitions(rmqio_tests PRIVATE BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) + target_compile_definitions(rmqio_tests PRIVATE ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) endif() add_test(NAME rmqio_tests COMMAND rmqio_tests) diff --git a/src/tests/rmqio/rmqio_asioconnection.t.cpp b/src/tests/rmqio/rmqio_asioconnection.t.cpp index 0be53a4f..6ec2de75 100644 --- a/src/tests/rmqio/rmqio_asioconnection.t.cpp +++ b/src/tests/rmqio/rmqio_asioconnection.t.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include @@ -77,7 +77,7 @@ class TestableAsioConnection : public AsioConnection { TestableAsioConnection(const Connection::Callbacks& cb, bslma::ManagedPtr decoder) : AsioConnection( - bsl::shared_ptr(), + bsl::shared_ptr(), cb, bsl::ref(decoder)) { @@ -90,12 +90,12 @@ class TestableAsioConnection : public AsioConnection { } void proxyDoClose(Connection::ReturnCode rc) { doClose(rc); } - void proxyHandleReadError(const boost::system::error_code& error) + void proxyHandleReadError(const asio::error_code& error) { handleReadError(error); } - void proxyHandleError(const boost::system::error_code& error) + void proxyHandleError(const asio::error_code& error) { handleError(error); } @@ -161,8 +161,7 @@ TEST_F(TestConnection, Breathing) EXPECT_THAT(d_connection.get(), Ne(static_cast(NULL))); } -// test handle error with success throws -// boost::system::errc::make_error_code(boost::system::errc::success), + TEST_F(TestConnection, OneFrameRead) { EXPECT_THAT(d_callbacks.consumeCount, Eq(0)); @@ -257,8 +256,8 @@ TEST_F(TestConnection, SomeGoodFramesSomeBad) TEST_F(TestConnection, SocketSnap) { - d_connection->proxyHandleReadError(boost::asio::error::make_error_code( - boost::asio::error::connection_reset)); + d_connection->proxyHandleReadError(asio::error::make_error_code( + asio::error::connection_reset)); EXPECT_THAT(d_callbacks.consumeCount, Eq(0)); EXPECT_THAT(d_callbacks.errorCount, Eq(1)); } @@ -266,7 +265,7 @@ TEST_F(TestConnection, SocketSnap) TEST_F(TestConnection, SocketClosed) { d_connection->proxyHandleReadError( - boost::asio::error::make_error_code(boost::asio::error::eof)); + asio::error::make_error_code(asio::error::eof)); EXPECT_THAT(d_callbacks.consumeCount, Eq(0)); EXPECT_THAT(d_callbacks.errorCount, Eq(1)); } @@ -286,7 +285,7 @@ class AsioConnectionTests : public Test { bdlf::PlaceHolders::_1); } - boost::asio::io_context d_eventLoop; + asio::io_context d_eventLoop; TestConnection::Callbacks d_mockCallbacks; Connection::Callbacks d_callbacks; }; diff --git a/src/tests/rmqio/rmqio_asioresolver.t.cpp b/src/tests/rmqio/rmqio_asioresolver.t.cpp index ad14d5e5..d74c3b0f 100644 --- a/src/tests/rmqio/rmqio_asioresolver.t.cpp +++ b/src/tests/rmqio/rmqio_asioresolver.t.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -91,14 +92,13 @@ TEST_F(ResolverTests, ShufflesResolverResults) { std::string host = "host"; std::string port = "port"; - typedef boost::asio::ip::basic_resolver_entry - entry_type; + typedef asio::ip::basic_resolver_entry entry_type; bsl::vector entries; for (int i = 0; i < 5; i++) { bsl::string ip = bsl::to_string(i) + ".0.0.0"; entry_type::endpoint_type endpoint( - boost::asio::ip::make_address(std::string(ip)), 1); + asio::ip::make_address(std::string(ip)), 1); entries.push_back(entry_type(endpoint, host, port)); } AsioResolver::results_type resolverResults = @@ -133,14 +133,13 @@ TEST_F(ResolverTests, NoShuffleDoesNotReorderResolverResults) { std::string host = "host"; std::string port = "port"; - typedef boost::asio::ip::basic_resolver_entry - entry_type; + typedef asio::ip::basic_resolver_entry entry_type; bsl::vector entries; for (int i = 0; i < 5; i++) { bsl::string ip = bsl::to_string(i) + ".0.0.0"; entry_type::endpoint_type endpoint( - boost::asio::ip::make_address(std::string(ip)), 1); + asio::ip::make_address(std::string(ip)), 1); entries.push_back(entry_type(endpoint, host, port)); } AsioResolver::results_type resolverResults = diff --git a/src/tests/rmqio/rmqio_asiotimer.t.cpp b/src/tests/rmqio/rmqio_asiotimer.t.cpp index cfa1bd8a..8dfe6554 100644 --- a/src/tests/rmqio/rmqio_asiotimer.t.cpp +++ b/src/tests/rmqio/rmqio_asiotimer.t.cpp @@ -17,25 +17,21 @@ #include -#include - #include -#include #include #include #include #include +#include using namespace BloombergLP; using namespace rmqio; using namespace ::testing; namespace { -typedef rmqio::basic_AsioTimer - FakeAsioTimer; -} // namespace +using namespace std::chrono_literals; +} class MockCallback { public: @@ -47,7 +43,7 @@ class AsioTimerTests : public Test { MockCallback d_mockCallback; Timer::Callback d_callback; AsioEventLoop d_io; - bsl::shared_ptr d_timer; + bsl::shared_ptr d_timer; AsioTimerTests() : d_mockCallback() @@ -55,8 +51,8 @@ class AsioTimerTests : public Test { &d_mockCallback, bdlf::PlaceHolders::_1)) , d_io() - , d_timer(bsl::make_shared(bsl::ref(d_io.context()), - bsls::TimeInterval(10))) + , d_timer(bsl::make_shared(bsl::ref(d_io.context()), + bsls::TimeInterval(10))) // 10ms { } }; @@ -70,8 +66,8 @@ TEST_F(AsioTimerTests, CallbackWhenExpires) { EXPECT_CALL(d_mockCallback, callback(Timer::EXPIRE)).Times(1); d_timer->start(d_callback); - rmqtestutil::TimeOverride::step_time(boost::posix_time::seconds(10)); - EXPECT_THAT(d_io.context().run_one(), Eq(1)); + // Run the event loop for sufficient time for 10s timer to expire + EXPECT_EQ(d_io.context().run_for(std::chrono::seconds(10)), 1); } TEST_F(AsioTimerTests, Cancel) @@ -79,7 +75,7 @@ TEST_F(AsioTimerTests, Cancel) EXPECT_CALL(d_mockCallback, callback(Timer::CANCEL)).Times(1); d_timer->start(d_callback); d_timer->cancel(); - EXPECT_THAT(d_io.context().poll_one(), Eq(1)); + EXPECT_EQ(d_io.context().poll_one(), 1); } TEST_F(AsioTimerTests, Reset) @@ -91,9 +87,10 @@ TEST_F(AsioTimerTests, Reset) } d_timer->start(d_callback); d_timer->reset(bsls::TimeInterval(10)); - rmqtestutil::TimeOverride::step_time(boost::posix_time::seconds(10)); - EXPECT_THAT(d_io.context().run_one(), Eq(1)); - EXPECT_THAT(d_io.context().run_one(), Eq(1)); + // First poll handles the cancellation from reset + EXPECT_EQ(d_io.context().poll_one(), 1); + // Then allow the timer to expire + EXPECT_GT(d_io.context().run_for(std::chrono::milliseconds(50)), 0); } TEST_F(AsioTimerTests, ResetCallsCancelImmediately) @@ -101,16 +98,17 @@ TEST_F(AsioTimerTests, ResetCallsCancelImmediately) EXPECT_CALL(d_mockCallback, callback(Timer::CANCEL)).Times(1); d_timer->start(d_callback); d_timer->reset(bsls::TimeInterval(10)); - EXPECT_THAT(d_io.context().poll_one(), Eq(1)); + EXPECT_EQ(d_io.context().poll_one(), 1); } TEST_F(AsioTimerTests, CancelIsSilentlyIgnoredOnDestruction) { { - bsl::shared_ptr timer = bsl::make_shared( + bsl::shared_ptr timer = bsl::make_shared( bsl::ref(d_io.context()), bsls::TimeInterval(10)); timer->start(d_callback); } EXPECT_CALL(d_mockCallback, callback(Timer::CANCEL)).Times(0); - EXPECT_THAT(d_io.context().run_one(), Eq(1)); + // Drain any posted handlers + d_io.context().poll(); } diff --git a/src/tests/rmqtestutil/rmqtestutil_mocktimerfactory.cpp b/src/tests/rmqtestutil/rmqtestutil_mocktimerfactory.cpp index f9d99f69..22fc745b 100644 --- a/src/tests/rmqtestutil/rmqtestutil_mocktimerfactory.cpp +++ b/src/tests/rmqtestutil/rmqtestutil_mocktimerfactory.cpp @@ -34,7 +34,7 @@ MockTimerFactory::~MockTimerFactory() { cancel(); } void MockTimerFactory::cancel() { - // Invoke every timer with cancel as per boost spec + // Invoke every timer with cancel as per timer semantics for (bsl::list::iterator it = d_timerCallbacks.begin(); it != d_timerCallbacks.end(); ++it) { diff --git a/src/tests/rmqtestutil/rmqtestutil_timeoverride.cpp b/src/tests/rmqtestutil/rmqtestutil_timeoverride.cpp index 94885ed0..ce8c7304 100644 --- a/src/tests/rmqtestutil/rmqtestutil_timeoverride.cpp +++ b/src/tests/rmqtestutil/rmqtestutil_timeoverride.cpp @@ -17,9 +17,5 @@ namespace BloombergLP { namespace rmqtestutil { - -TimeOverride::duration_type TimeOverride::d_timeOffset = - boost::posix_time::seconds(0); - } } // namespace BloombergLP diff --git a/src/tests/rmqtestutil/rmqtestutil_timeoverride.h b/src/tests/rmqtestutil/rmqtestutil_timeoverride.h index b41d0d1a..65ff2303 100644 --- a/src/tests/rmqtestutil/rmqtestutil_timeoverride.h +++ b/src/tests/rmqtestutil/rmqtestutil_timeoverride.h @@ -16,38 +16,32 @@ #ifndef INCLUDED_RMQTESTUTIL_TIMEOVERRIDE #define INCLUDED_RMQTESTUTIL_TIMEOVERRIDE -#include +#include -//@PURPOSE: Provides TimeOverride class extended from -// boost::asio::deadline_timer::traits_type -// +//@PURPOSE: Provides TimeOverride class for tests without Boost.Asio //@CLASSES: -// rmqtestutil::TimeOverride: Steps time in testing to trigger handler waiting -// on deadline_timer +// rmqtestutil::TimeOverride: Steps time in testing to simulate time passage namespace BloombergLP { namespace rmqtestutil { -class TimeOverride : public boost::asio::deadline_timer::traits_type { +class TimeOverride { public: - static time_type now() - { - return add(boost::asio::deadline_timer::traits_type::now(), - d_timeOffset); - } + using clock = std::chrono::steady_clock; + using duration_type = clock::duration; + using time_type = clock::time_point; + + static time_type now() { return clock::now() + d_timeOffset; } static void step_time(duration_type t) { d_timeOffset += t; } - static boost::posix_time::time_duration to_posix_duration(duration_type d) - { - // This is the secret sauce to ensure that boost::asio keeps calling - // `now()` and responds to our adjustments via `step_time` - return d < boost::posix_time::milliseconds(1) - ? d - : boost::posix_time::milliseconds(1); - } + + // For compatibility with previous interface; unused in current tests. + static duration_type to_posix_duration(duration_type d) { return d; } static duration_type d_timeOffset; }; +inline TimeOverride::duration_type TimeOverride::d_timeOffset{std::chrono::seconds(0)}; + } // namespace rmqtestutil } // namespace BloombergLP diff --git a/vcpkg.json b/vcpkg.json index cbb159bc..82c21982 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -3,7 +3,7 @@ "name": "rmqcpp", "version": "1.0.0", "dependencies": [ - "boost-asio", + "asio", "openssl", "gtest", "bde" From e55a4419fe494a1c5222dc5462594973b82675a8 Mon Sep 17 00:00:00 2001 From: Sam Sutherland-Dee Date: Tue, 30 Sep 2025 16:33:34 +0100 Subject: [PATCH 2/3] Add libasio-dev to dev Dockerfile. --- dockerfiles/dev.Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dockerfiles/dev.Dockerfile b/dockerfiles/dev.Dockerfile index 341c37e7..7da65ff7 100644 --- a/dockerfiles/dev.Dockerfile +++ b/dockerfiles/dev.Dockerfile @@ -5,9 +5,10 @@ RUN apt-get update && apt-get install -y \ clang-format \ cmake \ curl \ - gcc \ + gcc \ gdb \ git \ + libasio-dev \ libssl-dev \ net-tools \ netcat-traditional \ From 0a50091a28c7f99a5063887dc5758273ab93d4db Mon Sep 17 00:00:00 2001 From: Sam Sutherland-Dee Date: Tue, 30 Sep 2025 17:05:39 +0100 Subject: [PATCH 3/3] Fix unit test. --- src/tests/rmqio/rmqio_asiotimer.t.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/rmqio/rmqio_asiotimer.t.cpp b/src/tests/rmqio/rmqio_asiotimer.t.cpp index 8dfe6554..2afb132f 100644 --- a/src/tests/rmqio/rmqio_asiotimer.t.cpp +++ b/src/tests/rmqio/rmqio_asiotimer.t.cpp @@ -90,7 +90,7 @@ TEST_F(AsioTimerTests, Reset) // First poll handles the cancellation from reset EXPECT_EQ(d_io.context().poll_one(), 1); // Then allow the timer to expire - EXPECT_GT(d_io.context().run_for(std::chrono::milliseconds(50)), 0); + EXPECT_GT(d_io.context().run_for(std::chrono::seconds(10)), 0); } TEST_F(AsioTimerTests, ResetCallsCancelImmediately)