From 285120684c3bb8fb1f700529b2346926e34d99c6 Mon Sep 17 00:00:00 2001 From: Bart Date: Tue, 26 Aug 2025 16:00:00 -0400 Subject: [PATCH 1/4] refactor: Replace 'on: pull_request: paths' by 'changed-files' action (#5728) This PR moves the list of files from the `paths:` section in the `on: pull_request` into a separate job. --- .github/scripts/strategy-matrix/generate.py | 12 ++-- .github/workflows/on-pr.yml | 77 ++++++++++++++------- .github/workflows/on-trigger.yml | 16 +++-- 3 files changed, 68 insertions(+), 37 deletions(-) diff --git a/.github/scripts/strategy-matrix/generate.py b/.github/scripts/strategy-matrix/generate.py index 652cb8871f..9743d5a4e3 100644 --- a/.github/scripts/strategy-matrix/generate.py +++ b/.github/scripts/strategy-matrix/generate.py @@ -38,7 +38,7 @@ def generate_strategy_matrix(all: bool, architecture: list[dict], os: list[dict] # - Bookworm using GCC 13: Release and Unity on linux/arm64, set # the reference fee to 500. # - Bookworm using GCC 15: Debug and no Unity on linux/amd64, enable - # code coverage. + # code coverage (which will be done below). # - Bookworm using Clang 16: Debug and no Unity on linux/arm64, # enable voidstar. # - Bookworm using Clang 17: Release and no Unity on linux/amd64, @@ -51,9 +51,6 @@ def generate_strategy_matrix(all: bool, architecture: list[dict], os: list[dict] cmake_args = f'-DUNIT_TEST_REFERENCE_FEE=500 {cmake_args}' skip = False if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-15' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64': - cmake_args = f'-Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0 {cmake_args}' - cmake_target = 'coverage' - build_only = True skip = False if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-16' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/arm64': cmake_args = f'-Dvoidstar=ON {cmake_args}' @@ -127,6 +124,13 @@ def generate_strategy_matrix(all: bool, architecture: list[dict], os: list[dict] if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-20' and architecture['platform'] == 'linux/arm64': continue + # Enable code coverage for Debian Bookworm using GCC 15 in Debug and no + # Unity on linux/amd64 + if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-15' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64': + cmake_args = f'-Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0 {cmake_args}' + cmake_target = 'coverage' + build_only = True + # Generate a unique name for the configuration, e.g. macos-arm64-debug # or debian-bookworm-gcc-12-amd64-release-unity. config_name = os['distro_name'] diff --git a/.github/workflows/on-pr.yml b/.github/workflows/on-pr.yml index e626222865..02048efa64 100644 --- a/.github/workflows/on-pr.yml +++ b/.github/workflows/on-pr.yml @@ -6,29 +6,6 @@ name: PR on: pull_request: - paths: - - ".github/actions/build-deps/**" - - ".github/actions/build-test/**" - - ".github/scripts/levelization/**" - - ".github/scripts/strategy-matrix/**" - - ".github/workflows/build-test.yml" - - ".github/workflows/check-format.yml" - - ".github/workflows/check-levelization.yml" - - ".github/workflows/notify-clio.yml" - - ".github/workflows/on-pr.yml" - # Keep the list of paths below in sync with those in the `on-trigger.yml` - # file. - - "cmake/**" - - "conan/**" - - "external/**" - - "include/**" - - "src/**" - - "tests/**" - - ".clang-format" - - ".codecov.yml" - - ".pre-commit-config.yaml" - - "CMakeLists.txt" - - "conanfile.py" types: - opened - reopened @@ -57,18 +34,66 @@ jobs: - name: No-op run: true - check-format: + # This job checks whether any files have changed that should cause the next + # jobs to run. We do it this way rather than using `paths` in the `on:` + # section, because all required checks must pass, even for changes that do not + # modify anything that affects those checks. We would therefore like to make + # the checks required only if the job runs, but GitHub does not support that + # directly. By always executing the workflow on new commits and by using the + # changed-files action below, we ensure that Github considers any skipped jobs + # to have passed, and in turn the required checks as well. + any-changed: needs: should-run + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Determine changed files + id: changes + uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 + with: + files: | + # These paths are unique to `on-pr.yml`. + .github/scripts/levelization/** + .github/workflows/check-format.yml + .github/workflows/check-levelization.yml + .github/workflows/notify-clio.yml + .github/workflows/on-pr.yml + .clang-format + .pre-commit-config.yaml + + # Keep the paths below in sync with those in `on-trigger.yml`. + .github/actions/build-deps/** + .github/actions/build-test/** + .github/scripts/strategy-matrix/** + .github/workflows/build-test.yml + .codecov.yml + cmake/** + conan/** + external/** + include/** + src/** + tests/** + CMakeLists.txt + conanfile.py + outputs: + changed: ${{ steps.changes.outputs.any_changed }} + + check-format: + needs: any-changed + if: needs.any-changed.outputs.changed == 'true' uses: ./.github/workflows/check-format.yml check-levelization: - needs: should-run + needs: any-changed + if: needs.any-changed.outputs.changed == 'true' uses: ./.github/workflows/check-levelization.yml # This job works around the limitation that GitHub Actions does not support # using environment variables as inputs for reusable workflows. generate-outputs: - needs: should-run + needs: any-changed + if: needs.any-changed.outputs.changed == 'true' runs-on: ubuntu-latest steps: - name: No-op diff --git a/.github/workflows/on-trigger.yml b/.github/workflows/on-trigger.yml index 55e93b9866..b4c940ae4e 100644 --- a/.github/workflows/on-trigger.yml +++ b/.github/workflows/on-trigger.yml @@ -13,31 +13,33 @@ on: - release - master paths: + # These paths are unique to `on-trigger.yml`. + - ".github/workflows/check-missing-commits.yml" + - ".github/workflows/on-trigger.yml" + - ".github/workflows/publish-docs.yml" + + # Keep the paths below in sync with those in `on-pr.yml`. - ".github/actions/build-deps/**" - ".github/actions/build-test/**" - ".github/scripts/strategy-matrix/**" - ".github/workflows/build-test.yml" - - ".github/workflows/check-missing-commits.yml" - - ".github/workflows/on-trigger.yml" - - ".github/workflows/publish-docs.yml" - # Keep the list of paths below in sync with those in `on-pr.yml`. + - ".codecov.yml" - "cmake/**" - "conan/**" - "external/**" - "include/**" - "src/**" - "tests/**" - - ".clang-format" - - ".codecov.yml" - - ".pre-commit-config.yaml" - "CMakeLists.txt" - "conanfile.py" + # Run at 06:32 UTC on every day of the week from Monday through Friday. This # will force all dependencies to be rebuilt, which is useful to verify that # all dependencies can be built successfully. Only the dependencies that # are actually missing from the remote will be uploaded. schedule: - cron: "32 6 * * 1-5" + # Run when manually triggered via the GitHub UI or API. If `force_upload` is # true, then the dependencies that were missing (`force_rebuild` is false) or # rebuilt (`force_rebuild` is true) will be uploaded, overwriting existing From 92431a42387c6e5c9944b3514b0d0c1b30b29ced Mon Sep 17 00:00:00 2001 From: Bart Date: Tue, 26 Aug 2025 17:12:37 -0400 Subject: [PATCH 2/4] chore: Add support for merge_group event (#5734) This change adds support for the merge_group CI event, which will allow us to enable merge queues. --- .github/workflows/on-pr.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/on-pr.yml b/.github/workflows/on-pr.yml index 02048efa64..a5f1d60c42 100644 --- a/.github/workflows/on-pr.yml +++ b/.github/workflows/on-pr.yml @@ -5,6 +5,9 @@ name: PR on: + merge_group: + types: + - checks_requested pull_request: types: - opened From 808c86663c79159812389b325ac52db3323c5f28 Mon Sep 17 00:00:00 2001 From: Bart Date: Tue, 26 Aug 2025 19:07:23 -0400 Subject: [PATCH 3/4] fix: Add codecov token to trigger workflow (#5736) This change adds the Codecov token to the on-trigger workflow. --- .github/workflows/on-trigger.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/on-trigger.yml b/.github/workflows/on-trigger.yml index b4c940ae4e..7732b814ad 100644 --- a/.github/workflows/on-trigger.yml +++ b/.github/workflows/on-trigger.yml @@ -113,5 +113,6 @@ jobs: os: ${{ matrix.os }} strategy_matrix: "all" secrets: + codecov_token: ${{ secrets.CODECOV_TOKEN }} conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }} conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }} From 1506e65558818ea73a2233d2a55c1d1441d5fb10 Mon Sep 17 00:00:00 2001 From: Alex Kremer Date: Wed, 27 Aug 2025 10:34:50 +0100 Subject: [PATCH 4/4] refactor: Update to Boost 1.88 (#5570) This updates Boost to 1.88, which is needed because Clio wants to move to 1.88 as that fixes several ASAN false positives around coroutine usage. In order for Clio to move to newer boost, libXRPL needs to move too. Hence the changes in this PR. A lot has changed between 1.83 and 1.88 so there are lots of changes in the diff, especially in regards to Boost.Asio and coroutines in particular. --- cmake/RippledSettings.cmake | 2 +- cmake/deps/Boost.cmake | 1 + conanfile.py | 5 +- include/xrpl/basics/ResolverAsio.h | 4 +- include/xrpl/beast/asio/io_latency_probe.h | 39 ++++--- include/xrpl/beast/test/yield_to.h | 26 +++-- include/xrpl/json/json_reader.h | 2 +- include/xrpl/net/AutoSocket.h | 4 +- include/xrpl/net/HTTPClient.h | 8 +- include/xrpl/net/HTTPClientSSLContext.h | 8 +- include/xrpl/server/Server.h | 6 +- include/xrpl/server/Session.h | 6 +- include/xrpl/server/detail/BaseHTTPPeer.h | 20 ++-- include/xrpl/server/detail/BasePeer.h | 4 +- include/xrpl/server/detail/BaseWSPeer.h | 27 +++-- include/xrpl/server/detail/Door.h | 17 +-- include/xrpl/server/detail/PlainHTTPPeer.h | 4 +- include/xrpl/server/detail/SSLHTTPPeer.h | 6 +- include/xrpl/server/detail/ServerImpl.h | 28 +++-- include/xrpl/server/detail/Spawn.h | 108 ++++++++++++++++++ include/xrpl/server/detail/io_list.h | 2 +- src/libxrpl/basics/ResolverAsio.cpp | 87 +++++++++----- src/libxrpl/beast/insight/StatsDCollector.cpp | 105 ++++++++++------- src/libxrpl/beast/net/IPAddressV4.cpp | 8 +- src/libxrpl/beast/net/IPAddressV6.cpp | 6 +- src/libxrpl/beast/net/IPEndpoint.cpp | 4 +- src/libxrpl/net/HTTPClient.cpp | 68 ++++++----- src/libxrpl/server/Port.cpp | 3 +- src/test/app/DNS_test.cpp | 9 +- src/test/app/LedgerReplay_test.cpp | 2 +- src/test/app/ValidatorSite_test.cpp | 2 +- src/test/beast/IPEndpoint_test.cpp | 35 +++--- .../beast/beast_io_latency_probe_test.cpp | 23 ++-- src/test/jtx/TrustedPublisherServer.h | 4 +- src/test/jtx/impl/JSONRPCClient.cpp | 2 +- src/test/jtx/impl/WSClient.cpp | 55 ++++++--- src/test/overlay/compression_test.cpp | 2 +- src/test/overlay/reduce_relay_test.cpp | 2 +- src/test/overlay/short_read_test.cpp | 28 +++-- src/test/overlay/tx_reduce_relay_test.cpp | 8 +- src/test/rpc/ValidatorRPC_test.cpp | 4 +- src/test/server/ServerStatus_test.cpp | 23 ++-- src/test/server/Server_test.cpp | 29 ++--- .../app/ledger/detail/TimeoutCounter.cpp | 2 +- src/xrpld/app/ledger/detail/TimeoutCounter.h | 2 +- src/xrpld/app/main/Application.cpp | 60 +++++----- src/xrpld/app/main/Application.h | 4 +- src/xrpld/app/main/BasicApp.cpp | 6 +- src/xrpld/app/main/BasicApp.h | 16 +-- src/xrpld/app/main/Main.cpp | 12 +- src/xrpld/app/misc/NetworkOPs.cpp | 38 +++--- src/xrpld/app/misc/NetworkOPs.h | 2 +- src/xrpld/app/misc/detail/ValidatorSite.cpp | 8 +- src/xrpld/app/misc/detail/WorkBase.h | 69 ++++++----- src/xrpld/app/misc/detail/WorkFile.h | 23 ++-- src/xrpld/app/misc/detail/WorkPlain.h | 4 +- src/xrpld/app/misc/detail/WorkSSL.cpp | 10 +- src/xrpld/app/misc/detail/WorkSSL.h | 2 +- src/xrpld/overlay/detail/ConnectAttempt.cpp | 105 +++++++++++------ src/xrpld/overlay/detail/ConnectAttempt.h | 4 +- src/xrpld/overlay/detail/Handshake.cpp | 4 +- src/xrpld/overlay/detail/OverlayImpl.cpp | 29 ++--- src/xrpld/overlay/detail/OverlayImpl.h | 11 +- src/xrpld/overlay/detail/PeerImp.cpp | 36 ++++-- src/xrpld/overlay/detail/PeerImp.h | 2 +- src/xrpld/overlay/detail/PeerSet.cpp | 2 +- src/xrpld/overlay/detail/ZeroCopyStream.h | 4 +- src/xrpld/overlay/make_Overlay.h | 4 +- src/xrpld/peerfinder/detail/Checker.h | 20 ++-- .../peerfinder/detail/PeerfinderManager.cpp | 21 ++-- src/xrpld/peerfinder/make_Manager.h | 4 +- src/xrpld/rpc/RPCCall.h | 4 +- src/xrpld/rpc/RPCSub.h | 6 +- src/xrpld/rpc/ServerHandler.h | 6 +- src/xrpld/rpc/detail/RPCCall.cpp | 6 +- src/xrpld/rpc/detail/RPCSub.cpp | 12 +- src/xrpld/rpc/detail/ServerHandler.cpp | 11 +- src/xrpld/rpc/handlers/Subscribe.cpp | 2 +- 78 files changed, 871 insertions(+), 516 deletions(-) create mode 100644 include/xrpl/server/detail/Spawn.h diff --git a/cmake/RippledSettings.cmake b/cmake/RippledSettings.cmake index 9dc8609f58..9f59d9e9eb 100644 --- a/cmake/RippledSettings.cmake +++ b/cmake/RippledSettings.cmake @@ -118,7 +118,7 @@ option(beast_no_unit_test_inline "Prevents unit test definitions from being inserted into global table" OFF) option(single_io_service_thread - "Restricts the number of threads calling io_service::run to one. \ + "Restricts the number of threads calling io_context::run to one. \ This can be useful when debugging." OFF) option(boost_show_deprecated diff --git a/cmake/deps/Boost.cmake b/cmake/deps/Boost.cmake index 031202f4d2..bde40c0ce5 100644 --- a/cmake/deps/Boost.cmake +++ b/cmake/deps/Boost.cmake @@ -30,6 +30,7 @@ target_link_libraries(ripple_boost Boost::date_time Boost::filesystem Boost::json + Boost::process Boost::program_options Boost::regex Boost::system diff --git a/conanfile.py b/conanfile.py index da99836157..01f61c5d4e 100644 --- a/conanfile.py +++ b/conanfile.py @@ -100,11 +100,13 @@ class Xrpl(ConanFile): def configure(self): if self.settings.compiler == 'apple-clang': self.options['boost'].visibility = 'global' + if self.settings.compiler in ['clang', 'gcc']: + self.options['boost'].without_cobalt = True def requirements(self): # Conan 2 requires transitive headers to be specified transitive_headers_opt = {'transitive_headers': True} if conan_version.split('.')[0] == '2' else {} - self.requires('boost/1.86.0', force=True, **transitive_headers_opt) + self.requires('boost/1.88.0', force=True, **transitive_headers_opt) self.requires('date/3.0.4', **transitive_headers_opt) self.requires('lz4/1.10.0', force=True) self.requires('protobuf/3.21.12', force=True) @@ -175,6 +177,7 @@ class Xrpl(ConanFile): 'boost::filesystem', 'boost::json', 'boost::program_options', + 'boost::process', 'boost::regex', 'boost::system', 'boost::thread', diff --git a/include/xrpl/basics/ResolverAsio.h b/include/xrpl/basics/ResolverAsio.h index 49700d2b24..94688de650 100644 --- a/include/xrpl/basics/ResolverAsio.h +++ b/include/xrpl/basics/ResolverAsio.h @@ -23,7 +23,7 @@ #include #include -#include +#include namespace ripple { @@ -33,7 +33,7 @@ public: explicit ResolverAsio() = default; static std::unique_ptr - New(boost::asio::io_service&, beast::Journal); + New(boost::asio::io_context&, beast::Journal); }; } // namespace ripple diff --git a/include/xrpl/beast/asio/io_latency_probe.h b/include/xrpl/beast/asio/io_latency_probe.h index 966b4686ae..37f75cf649 100644 --- a/include/xrpl/beast/asio/io_latency_probe.h +++ b/include/xrpl/beast/asio/io_latency_probe.h @@ -23,7 +23,8 @@ #include #include -#include +#include +#include #include #include @@ -32,7 +33,7 @@ namespace beast { -/** Measures handler latency on an io_service queue. */ +/** Measures handler latency on an io_context queue. */ template class io_latency_probe { @@ -44,12 +45,12 @@ private: std::condition_variable_any m_cond; std::size_t m_count; duration const m_period; - boost::asio::io_service& m_ios; + boost::asio::io_context& m_ios; boost::asio::basic_waitable_timer m_timer; bool m_cancel; public: - io_latency_probe(duration const& period, boost::asio::io_service& ios) + io_latency_probe(duration const& period, boost::asio::io_context& ios) : m_count(1) , m_period(period) , m_ios(ios) @@ -64,16 +65,16 @@ public: cancel(lock, true); } - /** Return the io_service associated with the latency probe. */ + /** Return the io_context associated with the latency probe. */ /** @{ */ - boost::asio::io_service& - get_io_service() + boost::asio::io_context& + get_io_context() { return m_ios; } - boost::asio::io_service const& - get_io_service() const + boost::asio::io_context const& + get_io_context() const { return m_ios; } @@ -109,8 +110,10 @@ public: std::lock_guard lock(m_mutex); if (m_cancel) throw std::logic_error("io_latency_probe is canceled"); - m_ios.post(sample_op( - std::forward(handler), Clock::now(), false, this)); + boost::asio::post( + m_ios, + sample_op( + std::forward(handler), Clock::now(), false, this)); } /** Initiate continuous i/o latency sampling. @@ -124,8 +127,10 @@ public: std::lock_guard lock(m_mutex); if (m_cancel) throw std::logic_error("io_latency_probe is canceled"); - m_ios.post(sample_op( - std::forward(handler), Clock::now(), true, this)); + boost::asio::post( + m_ios, + sample_op( + std::forward(handler), Clock::now(), true, this)); } private: @@ -236,12 +241,13 @@ private: // The latency is too high to maintain the desired // period so don't bother with a timer. // - m_probe->m_ios.post( + boost::asio::post( + m_probe->m_ios, sample_op(m_handler, now, m_repeat, m_probe)); } else { - m_probe->m_timer.expires_from_now(when - now); + m_probe->m_timer.expires_after(when - now); m_probe->m_timer.async_wait( sample_op(m_handler, now, m_repeat, m_probe)); } @@ -254,7 +260,8 @@ private: if (!m_probe) return; typename Clock::time_point const now(Clock::now()); - m_probe->m_ios.post( + boost::asio::post( + m_probe->m_ios, sample_op(m_handler, now, m_repeat, m_probe)); } }; diff --git a/include/xrpl/beast/test/yield_to.h b/include/xrpl/beast/test/yield_to.h index 27a3a2db20..a222e8627e 100644 --- a/include/xrpl/beast/test/yield_to.h +++ b/include/xrpl/beast/test/yield_to.h @@ -8,9 +8,11 @@ #ifndef BEAST_TEST_YIELD_TO_HPP #define BEAST_TEST_YIELD_TO_HPP -#include +#include +#include #include #include +#include #include #include @@ -29,10 +31,12 @@ namespace test { class enable_yield_to { protected: - boost::asio::io_service ios_; + boost::asio::io_context ios_; private: - boost::optional work_; + boost::optional> + work_; std::vector threads_; std::mutex m_; std::condition_variable cv_; @@ -42,7 +46,8 @@ public: /// The type of yield context passed to functions. using yield_context = boost::asio::yield_context; - explicit enable_yield_to(std::size_t concurrency = 1) : work_(ios_) + explicit enable_yield_to(std::size_t concurrency = 1) + : work_(boost::asio::make_work_guard(ios_)) { threads_.reserve(concurrency); while (concurrency--) @@ -56,9 +61,9 @@ public: t.join(); } - /// Return the `io_service` associated with the object - boost::asio::io_service& - get_io_service() + /// Return the `io_context` associated with the object + boost::asio::io_context& + get_io_context() { return ios_; } @@ -111,13 +116,18 @@ enable_yield_to::spawn(F0&& f, FN&&... fn) { boost::asio::spawn( ios_, + boost::allocator_arg, + boost::context::fixedsize_stack(2 * 1024 * 1024), [&](yield_context yield) { f(yield); std::lock_guard lock{m_}; if (--running_ == 0) cv_.notify_all(); }, - boost::coroutines::attributes(2 * 1024 * 1024)); + [](std::exception_ptr e) { + if (e) + std::rethrow_exception(e); + }); spawn(fn...); } diff --git a/include/xrpl/json/json_reader.h b/include/xrpl/json/json_reader.h index 81866819a5..8eceee1f1c 100644 --- a/include/xrpl/json/json_reader.h +++ b/include/xrpl/json/json_reader.h @@ -217,7 +217,7 @@ Reader::parse(Value& root, BufferSequence const& bs) std::string s; s.reserve(buffer_size(bs)); for (auto const& b : bs) - s.append(buffer_cast(b), buffer_size(b)); + s.append(static_cast(b.data()), buffer_size(b)); return parse(s, root); } diff --git a/include/xrpl/net/AutoSocket.h b/include/xrpl/net/AutoSocket.h index d06787340b..5f82854039 100644 --- a/include/xrpl/net/AutoSocket.h +++ b/include/xrpl/net/AutoSocket.h @@ -47,7 +47,7 @@ public: public: AutoSocket( - boost::asio::io_service& s, + boost::asio::io_context& s, boost::asio::ssl::context& c, bool secureOnly, bool plainOnly) @@ -58,7 +58,7 @@ public: mSocket = std::make_unique(s, c); } - AutoSocket(boost::asio::io_service& s, boost::asio::ssl::context& c) + AutoSocket(boost::asio::io_context& s, boost::asio::ssl::context& c) : AutoSocket(s, c, false, false) { } diff --git a/include/xrpl/net/HTTPClient.h b/include/xrpl/net/HTTPClient.h index ef295e8e5a..b5043cd024 100644 --- a/include/xrpl/net/HTTPClient.h +++ b/include/xrpl/net/HTTPClient.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -51,7 +51,7 @@ public: static void get(bool bSSL, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, std::deque deqSites, unsigned short const port, std::string const& strPath, @@ -65,7 +65,7 @@ public: static void get(bool bSSL, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, std::string strSite, unsigned short const port, std::string const& strPath, @@ -80,7 +80,7 @@ public: static void request( bool bSSL, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, std::string strSite, unsigned short const port, std::function< diff --git a/include/xrpl/net/HTTPClientSSLContext.h b/include/xrpl/net/HTTPClientSSLContext.h index 2f7d6c005e..f5dd1e54c6 100644 --- a/include/xrpl/net/HTTPClientSSLContext.h +++ b/include/xrpl/net/HTTPClientSSLContext.h @@ -153,7 +153,7 @@ public: { strm.set_verify_callback( std::bind( - &rfc2818_verify, + &rfc6125_verify, host, std::placeholders::_1, std::placeholders::_2, @@ -167,7 +167,7 @@ public: /** * @brief callback invoked for name verification - just passes through - * to the asio rfc2818 implementation. + * to the asio `host_name_verification` (rfc6125) implementation. * * @param domain hostname expected * @param preverified passed by implementation @@ -175,13 +175,13 @@ public: * @param j journal for logging */ static bool - rfc2818_verify( + rfc6125_verify( std::string const& domain, bool preverified, boost::asio::ssl::verify_context& ctx, beast::Journal j) { - if (boost::asio::ssl::rfc2818_verification(domain)(preverified, ctx)) + if (boost::asio::ssl::host_name_verification(domain)(preverified, ctx)) return true; JLOG(j.warn()) << "Outbound SSL connection to " << domain diff --git a/include/xrpl/server/Server.h b/include/xrpl/server/Server.h index 232d1c381b..a8f9c7f8af 100644 --- a/include/xrpl/server/Server.h +++ b/include/xrpl/server/Server.h @@ -25,7 +25,7 @@ #include #include -#include +#include namespace ripple { @@ -34,10 +34,10 @@ template std::unique_ptr make_Server( Handler& handler, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, beast::Journal journal) { - return std::make_unique>(handler, io_service, journal); + return std::make_unique>(handler, io_context, journal); } } // namespace ripple diff --git a/include/xrpl/server/Session.h b/include/xrpl/server/Session.h index 196f8c78c2..586172a5da 100644 --- a/include/xrpl/server/Session.h +++ b/include/xrpl/server/Session.h @@ -88,9 +88,7 @@ public: ++iter) { typename BufferSequence::value_type const& buffer(*iter); - write( - boost::asio::buffer_cast(buffer), - boost::asio::buffer_size(buffer)); + write(buffer.data(), boost::asio::buffer_size(buffer)); } } @@ -104,7 +102,7 @@ public: /** Detach the session. This holds the session open so that the response can be sent - asynchronously. Calls to io_service::run made by the server + asynchronously. Calls to io_context::run made by the server will not return until all detached sessions are closed. */ virtual std::shared_ptr diff --git a/include/xrpl/server/detail/BaseHTTPPeer.h b/include/xrpl/server/detail/BaseHTTPPeer.h index b065a97cf0..b7f471bdee 100644 --- a/include/xrpl/server/detail/BaseHTTPPeer.h +++ b/include/xrpl/server/detail/BaseHTTPPeer.h @@ -24,11 +24,13 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -215,8 +217,8 @@ BaseHTTPPeer::BaseHTTPPeer( ConstBufferSequence const& buffers) : port_(port) , handler_(handler) - , work_(executor) - , strand_(executor) + , work_(boost::asio::make_work_guard(executor)) + , strand_(boost::asio::make_strand(executor)) , remote_address_(remote_address) , journal_(journal) { @@ -356,7 +358,7 @@ BaseHTTPPeer::on_write( return; if (graceful_) return do_close(); - boost::asio::spawn( + util::spawn( strand_, std::bind( &BaseHTTPPeer::do_read, @@ -375,7 +377,7 @@ BaseHTTPPeer::do_writer( { auto const p = impl().shared_from_this(); resume = std::function([this, p, writer, keep_alive]() { - boost::asio::spawn( + util::spawn( strand_, std::bind( &BaseHTTPPeer::do_writer, @@ -406,7 +408,7 @@ BaseHTTPPeer::do_writer( if (!keep_alive) return do_close(); - boost::asio::spawn( + util::spawn( strand_, std::bind( &BaseHTTPPeer::do_read, @@ -448,14 +450,14 @@ BaseHTTPPeer::write( std::shared_ptr const& writer, bool keep_alive) { - boost::asio::spawn(bind_executor( + util::spawn( strand_, std::bind( &BaseHTTPPeer::do_writer, impl().shared_from_this(), writer, keep_alive, - std::placeholders::_1))); + std::placeholders::_1)); } // DEPRECATED @@ -490,12 +492,12 @@ BaseHTTPPeer::complete() } // keep-alive - boost::asio::spawn(bind_executor( + util::spawn( strand_, std::bind( &BaseHTTPPeer::do_read, impl().shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1)); } // DEPRECATED diff --git a/include/xrpl/server/detail/BasePeer.h b/include/xrpl/server/detail/BasePeer.h index 35975efafb..30de63e6ff 100644 --- a/include/xrpl/server/detail/BasePeer.h +++ b/include/xrpl/server/detail/BasePeer.h @@ -91,8 +91,8 @@ BasePeer::BasePeer( return "##" + std::to_string(++id) + " "; }()) , j_(sink_) - , work_(executor) - , strand_(executor) + , work_(boost::asio::make_work_guard(executor)) + , strand_(boost::asio::make_strand(executor)) { } diff --git a/include/xrpl/server/detail/BaseWSPeer.h b/include/xrpl/server/detail/BaseWSPeer.h index 027b0cbf7c..391c5c337e 100644 --- a/include/xrpl/server/detail/BaseWSPeer.h +++ b/include/xrpl/server/detail/BaseWSPeer.h @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -420,11 +421,17 @@ BaseWSPeer::start_timer() // Max seconds without completing a message static constexpr std::chrono::seconds timeout{30}; static constexpr std::chrono::seconds timeoutLocal{3}; - error_code ec; - timer_.expires_from_now( - remote_endpoint().address().is_loopback() ? timeoutLocal : timeout, ec); - if (ec) - return fail(ec, "start_timer"); + + try + { + timer_.expires_after( + remote_endpoint().address().is_loopback() ? timeoutLocal : timeout); + } + catch (boost::system::system_error const& e) + { + return fail(e.code(), "start_timer"); + } + timer_.async_wait(bind_executor( strand_, std::bind( @@ -438,8 +445,14 @@ template void BaseWSPeer::cancel_timer() { - error_code ec; - timer_.cancel(ec); + try + { + timer_.cancel(); + } + catch (boost::system::system_error const&) + { + // ignored + } } template diff --git a/include/xrpl/server/detail/Door.h b/include/xrpl/server/detail/Door.h index 88e19db8cd..7906af2a52 100644 --- a/include/xrpl/server/detail/Door.h +++ b/include/xrpl/server/detail/Door.h @@ -69,7 +69,7 @@ private: stream_type stream_; socket_type& socket_; endpoint_type remote_address_; - boost::asio::io_context::strand strand_; + boost::asio::strand strand_; beast::Journal const j_; public: @@ -95,7 +95,7 @@ private: Handler& handler_; boost::asio::io_context& ioc_; acceptor_type acceptor_; - boost::asio::io_context::strand strand_; + boost::asio::strand strand_; bool ssl_; bool plain_; @@ -155,7 +155,7 @@ Door::Detector::Detector( , stream_(std::move(stream)) , socket_(stream_.socket()) , remote_address_(remote_address) - , strand_(ioc_) + , strand_(boost::asio::make_strand(ioc_)) , j_(j) { } @@ -164,7 +164,7 @@ template void Door::Detector::run() { - boost::asio::spawn( + util::spawn( strand_, std::bind( &Detector::do_detect, @@ -269,7 +269,7 @@ Door::reOpen() Throw(); } - acceptor_.listen(boost::asio::socket_base::max_connections, ec); + acceptor_.listen(boost::asio::socket_base::max_listen_connections, ec); if (ec) { JLOG(j_.error()) << "Listen on port '" << port_.name @@ -291,7 +291,7 @@ Door::Door( , handler_(handler) , ioc_(io_context) , acceptor_(io_context) - , strand_(io_context) + , strand_(boost::asio::make_strand(io_context)) , ssl_( port_.protocol.count("https") > 0 || port_.protocol.count("wss") > 0 || port_.protocol.count("wss2") > 0 || @@ -307,7 +307,7 @@ template void Door::run() { - boost::asio::spawn( + util::spawn( strand_, std::bind( &Door::do_accept, @@ -320,7 +320,8 @@ void Door::close() { if (!strand_.running_in_this_thread()) - return strand_.post( + return boost::asio::post( + strand_, std::bind(&Door::close, this->shared_from_this())); error_code ec; acceptor_.close(ec); diff --git a/include/xrpl/server/detail/PlainHTTPPeer.h b/include/xrpl/server/detail/PlainHTTPPeer.h index ee31c78cad..f6f8e5b010 100644 --- a/include/xrpl/server/detail/PlainHTTPPeer.h +++ b/include/xrpl/server/detail/PlainHTTPPeer.h @@ -105,7 +105,7 @@ PlainHTTPPeer::run() { if (!this->handler_.onAccept(this->session(), this->remote_address_)) { - boost::asio::spawn( + util::spawn( this->strand_, std::bind(&PlainHTTPPeer::do_close, this->shared_from_this())); return; @@ -114,7 +114,7 @@ PlainHTTPPeer::run() if (!socket_.is_open()) return; - boost::asio::spawn( + util::spawn( this->strand_, std::bind( &PlainHTTPPeer::do_read, diff --git a/include/xrpl/server/detail/SSLHTTPPeer.h b/include/xrpl/server/detail/SSLHTTPPeer.h index fac4b866d3..8564263114 100644 --- a/include/xrpl/server/detail/SSLHTTPPeer.h +++ b/include/xrpl/server/detail/SSLHTTPPeer.h @@ -115,14 +115,14 @@ SSLHTTPPeer::run() { if (!this->handler_.onAccept(this->session(), this->remote_address_)) { - boost::asio::spawn( + util::spawn( this->strand_, std::bind(&SSLHTTPPeer::do_close, this->shared_from_this())); return; } if (!socket_.is_open()) return; - boost::asio::spawn( + util::spawn( this->strand_, std::bind( &SSLHTTPPeer::do_handshake, @@ -164,7 +164,7 @@ SSLHTTPPeer::do_handshake(yield_context do_yield) this->port().protocol.count("https") > 0; if (http) { - boost::asio::spawn( + util::spawn( this->strand_, std::bind( &SSLHTTPPeer::do_read, diff --git a/include/xrpl/server/detail/ServerImpl.h b/include/xrpl/server/detail/ServerImpl.h index fd0b082b46..4090aa0a6b 100644 --- a/include/xrpl/server/detail/ServerImpl.h +++ b/include/xrpl/server/detail/ServerImpl.h @@ -26,6 +26,8 @@ #include #include +#include +#include #include #include @@ -85,9 +87,11 @@ private: Handler& handler_; beast::Journal const j_; - boost::asio::io_service& io_service_; - boost::asio::io_service::strand strand_; - std::optional work_; + boost::asio::io_context& io_context_; + boost::asio::strand strand_; + std::optional> + work_; std::mutex m_; std::vector ports_; @@ -100,7 +104,7 @@ private: public: ServerImpl( Handler& handler, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, beast::Journal journal); ~ServerImpl(); @@ -123,10 +127,10 @@ public: return ios_; } - boost::asio::io_service& - get_io_service() + boost::asio::io_context& + get_io_context() { - return io_service_; + return io_context_; } bool @@ -140,13 +144,13 @@ private: template ServerImpl::ServerImpl( Handler& handler, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, beast::Journal journal) : handler_(handler) , j_(journal) - , io_service_(io_service) - , strand_(io_service_) - , work_(io_service_) + , io_context_(io_context) + , strand_(boost::asio::make_strand(io_context_)) + , work_(std::in_place, boost::asio::make_work_guard(io_context_)) { } @@ -173,7 +177,7 @@ ServerImpl::ports(std::vector const& ports) ports_.push_back(port); auto& internalPort = ports_.back(); if (auto sp = ios_.emplace>( - handler_, io_service_, internalPort, j_)) + handler_, io_context_, internalPort, j_)) { list_.push_back(sp); diff --git a/include/xrpl/server/detail/Spawn.h b/include/xrpl/server/detail/Spawn.h new file mode 100644 index 0000000000..56f173dec3 --- /dev/null +++ b/include/xrpl/server/detail/Spawn.h @@ -0,0 +1,108 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright(c) 2025 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_SERVER_SPAWN_H_INCLUDED +#define RIPPLE_SERVER_SPAWN_H_INCLUDED + +#include + +#include +#include + +#include +#include + +namespace ripple::util { +namespace impl { + +template +concept IsStrand = std::same_as< + std::decay_t, + boost::asio::strand::inner_executor_type>>; + +/** + * @brief A completion handler that restores `boost::asio::spawn`'s behaviour + * from Boost 1.83 + * + * This is intended to be passed as the third argument to `boost::asio::spawn` + * so that exceptions are not ignored but propagated to `io_context.run()` call + * site. + * + * @param ePtr The exception that was caught on the coroutine + */ +inline constexpr auto kPROPAGATE_EXCEPTIONS = [](std::exception_ptr ePtr) { + if (ePtr) + { + try + { + std::rethrow_exception(ePtr); + } + catch (std::exception const& e) + { + JLOG(debugLog().warn()) << "Spawn exception: " << e.what(); + throw; + } + catch (...) + { + JLOG(debugLog().warn()) << "Spawn exception: Unknown"; + throw; + } + } +}; + +} // namespace impl + +/** + * @brief Spawns a coroutine using `boost::asio::spawn` + * + * @note This uses kPROPAGATE_EXCEPTIONS to force asio to propagate exceptions + * through `io_context` + * @note Since implicit strand was removed from boost::asio::spawn this helper + * function adds the strand back + * + * @tparam Ctx The type of the context/strand + * @tparam F The type of the function to execute + * @param ctx The execution context + * @param func The function to execute. Must return `void` + */ +template + requires std::is_invocable_r_v +void +spawn(Ctx&& ctx, F&& func) +{ + if constexpr (impl::IsStrand) + { + boost::asio::spawn( + std::forward(ctx), + std::forward(func), + impl::kPROPAGATE_EXCEPTIONS); + } + else + { + boost::asio::spawn( + boost::asio::make_strand( + boost::asio::get_associated_executor(std::forward(ctx))), + std::forward(func), + impl::kPROPAGATE_EXCEPTIONS); + } +} + +} // namespace ripple::util + +#endif diff --git a/include/xrpl/server/detail/io_list.h b/include/xrpl/server/detail/io_list.h index fba8b28f87..6292794864 100644 --- a/include/xrpl/server/detail/io_list.h +++ b/include/xrpl/server/detail/io_list.h @@ -166,7 +166,7 @@ public: May be called concurrently. Preconditions: - No call to io_service::run on any io_service + No call to io_context::run on any io_context used by work objects associated with this io_list exists in the caller's call stack. */ diff --git a/src/libxrpl/basics/ResolverAsio.cpp b/src/libxrpl/basics/ResolverAsio.cpp index fde27189e7..1b52465a80 100644 --- a/src/libxrpl/basics/ResolverAsio.cpp +++ b/src/libxrpl/basics/ResolverAsio.cpp @@ -25,8 +25,9 @@ #include #include +#include #include -#include +#include #include #include @@ -124,8 +125,8 @@ public: beast::Journal m_journal; - boost::asio::io_service& m_io_service; - boost::asio::io_service::strand m_strand; + boost::asio::io_context& m_io_context; + boost::asio::strand m_strand; boost::asio::ip::tcp::resolver m_resolver; std::condition_variable m_cv; @@ -155,12 +156,12 @@ public: std::deque m_work; ResolverAsioImpl( - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, beast::Journal journal) : m_journal(journal) - , m_io_service(io_service) - , m_strand(io_service) - , m_resolver(io_service) + , m_io_context(io_context) + , m_strand(boost::asio::make_strand(io_context)) + , m_resolver(io_context) , m_asyncHandlersCompleted(true) , m_stop_called(false) , m_stopped(true) @@ -216,8 +217,14 @@ public: { if (m_stop_called.exchange(true) == false) { - m_io_service.dispatch(m_strand.wrap(std::bind( - &ResolverAsioImpl::do_stop, this, CompletionCounter(this)))); + boost::asio::dispatch( + m_io_context, + boost::asio::bind_executor( + m_strand, + std::bind( + &ResolverAsioImpl::do_stop, + this, + CompletionCounter(this)))); JLOG(m_journal.debug()) << "Queued a stop request"; } @@ -248,12 +255,16 @@ public: // TODO NIKB use rvalue references to construct and move // reducing cost. - m_io_service.dispatch(m_strand.wrap(std::bind( - &ResolverAsioImpl::do_resolve, - this, - names, - handler, - CompletionCounter(this)))); + boost::asio::dispatch( + m_io_context, + boost::asio::bind_executor( + m_strand, + std::bind( + &ResolverAsioImpl::do_resolve, + this, + names, + handler, + CompletionCounter(this)))); } //------------------------------------------------------------------------- @@ -279,19 +290,20 @@ public: std::string name, boost::system::error_code const& ec, HandlerType handler, - boost::asio::ip::tcp::resolver::iterator iter, + boost::asio::ip::tcp::resolver::results_type results, CompletionCounter) { if (ec == boost::asio::error::operation_aborted) return; std::vector addresses; + auto iter = results.begin(); // If we get an error message back, we don't return any // results that we may have gotten. if (!ec) { - while (iter != boost::asio::ip::tcp::resolver::iterator()) + while (iter != results.end()) { addresses.push_back( beast::IPAddressConversion::from_asio(*iter)); @@ -301,8 +313,14 @@ public: handler(name, addresses); - m_io_service.post(m_strand.wrap(std::bind( - &ResolverAsioImpl::do_work, this, CompletionCounter(this)))); + boost::asio::post( + m_io_context, + boost::asio::bind_executor( + m_strand, + std::bind( + &ResolverAsioImpl::do_work, + this, + CompletionCounter(this)))); } HostAndPort @@ -383,16 +401,21 @@ public: { JLOG(m_journal.error()) << "Unable to parse '" << name << "'"; - m_io_service.post(m_strand.wrap(std::bind( - &ResolverAsioImpl::do_work, this, CompletionCounter(this)))); + boost::asio::post( + m_io_context, + boost::asio::bind_executor( + m_strand, + std::bind( + &ResolverAsioImpl::do_work, + this, + CompletionCounter(this)))); return; } - boost::asio::ip::tcp::resolver::query query(host, port); - m_resolver.async_resolve( - query, + host, + port, std::bind( &ResolverAsioImpl::do_finish, this, @@ -423,10 +446,14 @@ public: if (m_work.size() > 0) { - m_io_service.post(m_strand.wrap(std::bind( - &ResolverAsioImpl::do_work, - this, - CompletionCounter(this)))); + boost::asio::post( + m_io_context, + boost::asio::bind_executor( + m_strand, + std::bind( + &ResolverAsioImpl::do_work, + this, + CompletionCounter(this)))); } } } @@ -435,9 +462,9 @@ public: //----------------------------------------------------------------------------- std::unique_ptr -ResolverAsio::New(boost::asio::io_service& io_service, beast::Journal journal) +ResolverAsio::New(boost::asio::io_context& io_context, beast::Journal journal) { - return std::make_unique(io_service, journal); + return std::make_unique(io_context, journal); } //----------------------------------------------------------------------------- diff --git a/src/libxrpl/beast/insight/StatsDCollector.cpp b/src/libxrpl/beast/insight/StatsDCollector.cpp index b0e00c3cfd..7a3929e0d5 100644 --- a/src/libxrpl/beast/insight/StatsDCollector.cpp +++ b/src/libxrpl/beast/insight/StatsDCollector.cpp @@ -30,9 +30,11 @@ #include #include +#include #include #include -#include +#include +#include #include #include #include @@ -238,9 +240,11 @@ private: Journal m_journal; IP::Endpoint m_address; std::string m_prefix; - boost::asio::io_service m_io_service; - std::optional m_work; - boost::asio::io_service::strand m_strand; + boost::asio::io_context m_io_context; + std::optional> + m_work; + boost::asio::strand m_strand; boost::asio::basic_waitable_timer m_timer; boost::asio::ip::udp::socket m_socket; std::deque m_data; @@ -264,18 +268,24 @@ public: : m_journal(journal) , m_address(address) , m_prefix(prefix) - , m_work(std::ref(m_io_service)) - , m_strand(m_io_service) - , m_timer(m_io_service) - , m_socket(m_io_service) + , m_work(boost::asio::make_work_guard(m_io_context)) + , m_strand(boost::asio::make_strand(m_io_context)) + , m_timer(m_io_context) + , m_socket(m_io_context) , m_thread(&StatsDCollectorImp::run, this) { } ~StatsDCollectorImp() override { - boost::system::error_code ec; - m_timer.cancel(ec); + try + { + m_timer.cancel(); + } + catch (boost::system::system_error const&) + { + // ignored + } m_work.reset(); m_thread.join(); @@ -334,10 +344,10 @@ public: //-------------------------------------------------------------------------- - boost::asio::io_service& - get_io_service() + boost::asio::io_context& + get_io_context() { - return m_io_service; + return m_io_context; } std::string const& @@ -355,8 +365,14 @@ public: void post_buffer(std::string&& buffer) { - m_io_service.dispatch(m_strand.wrap(std::bind( - &StatsDCollectorImp::do_post_buffer, this, std::move(buffer)))); + boost::asio::dispatch( + m_io_context, + boost::asio::bind_executor( + m_strand, + std::bind( + &StatsDCollectorImp::do_post_buffer, + this, + std::move(buffer)))); } // The keepAlive parameter makes sure the buffers sent to @@ -386,8 +402,7 @@ public: for (auto const& buffer : buffers) { std::string const s( - boost::asio::buffer_cast(buffer), - boost::asio::buffer_size(buffer)); + buffer.data(), boost::asio::buffer_size(buffer)); std::cerr << s; } std::cerr << '\n'; @@ -456,7 +471,7 @@ public: set_timer() { using namespace std::chrono_literals; - m_timer.expires_from_now(1s); + m_timer.expires_after(1s); m_timer.async_wait(std::bind( &StatsDCollectorImp::on_timer, this, std::placeholders::_1)); } @@ -498,13 +513,13 @@ public: set_timer(); - m_io_service.run(); + m_io_context.run(); m_socket.shutdown(boost::asio::ip::udp::socket::shutdown_send, ec); m_socket.close(); - m_io_service.poll(); + m_io_context.poll(); } }; @@ -547,10 +562,12 @@ StatsDCounterImpl::~StatsDCounterImpl() void StatsDCounterImpl::increment(CounterImpl::value_type amount) { - m_impl->get_io_service().dispatch(std::bind( - &StatsDCounterImpl::do_increment, - std::static_pointer_cast(shared_from_this()), - amount)); + boost::asio::dispatch( + m_impl->get_io_context(), + std::bind( + &StatsDCounterImpl::do_increment, + std::static_pointer_cast(shared_from_this()), + amount)); } void @@ -592,10 +609,12 @@ StatsDEventImpl::StatsDEventImpl( void StatsDEventImpl::notify(EventImpl::value_type const& value) { - m_impl->get_io_service().dispatch(std::bind( - &StatsDEventImpl::do_notify, - std::static_pointer_cast(shared_from_this()), - value)); + boost::asio::dispatch( + m_impl->get_io_context(), + std::bind( + &StatsDEventImpl::do_notify, + std::static_pointer_cast(shared_from_this()), + value)); } void @@ -625,19 +644,23 @@ StatsDGaugeImpl::~StatsDGaugeImpl() void StatsDGaugeImpl::set(GaugeImpl::value_type value) { - m_impl->get_io_service().dispatch(std::bind( - &StatsDGaugeImpl::do_set, - std::static_pointer_cast(shared_from_this()), - value)); + boost::asio::dispatch( + m_impl->get_io_context(), + std::bind( + &StatsDGaugeImpl::do_set, + std::static_pointer_cast(shared_from_this()), + value)); } void StatsDGaugeImpl::increment(GaugeImpl::difference_type amount) { - m_impl->get_io_service().dispatch(std::bind( - &StatsDGaugeImpl::do_increment, - std::static_pointer_cast(shared_from_this()), - amount)); + boost::asio::dispatch( + m_impl->get_io_context(), + std::bind( + &StatsDGaugeImpl::do_increment, + std::static_pointer_cast(shared_from_this()), + amount)); } void @@ -713,10 +736,12 @@ StatsDMeterImpl::~StatsDMeterImpl() void StatsDMeterImpl::increment(MeterImpl::value_type amount) { - m_impl->get_io_service().dispatch(std::bind( - &StatsDMeterImpl::do_increment, - std::static_pointer_cast(shared_from_this()), - amount)); + boost::asio::dispatch( + m_impl->get_io_context(), + std::bind( + &StatsDMeterImpl::do_increment, + std::static_pointer_cast(shared_from_this()), + amount)); } void diff --git a/src/libxrpl/beast/net/IPAddressV4.cpp b/src/libxrpl/beast/net/IPAddressV4.cpp index 29455024f6..22162c2bbe 100644 --- a/src/libxrpl/beast/net/IPAddressV4.cpp +++ b/src/libxrpl/beast/net/IPAddressV4.cpp @@ -25,11 +25,11 @@ namespace IP { bool is_private(AddressV4 const& addr) { - return ((addr.to_ulong() & 0xff000000) == + return ((addr.to_uint() & 0xff000000) == 0x0a000000) || // Prefix /8, 10. #.#.# - ((addr.to_ulong() & 0xfff00000) == + ((addr.to_uint() & 0xfff00000) == 0xac100000) || // Prefix /12 172. 16.#.# - 172.31.#.# - ((addr.to_ulong() & 0xffff0000) == + ((addr.to_uint() & 0xffff0000) == 0xc0a80000) || // Prefix /16 192.168.#.# addr.is_loopback(); } @@ -44,7 +44,7 @@ char get_class(AddressV4 const& addr) { static char const* table = "AAAABBCD"; - return table[(addr.to_ulong() & 0xE0000000) >> 29]; + return table[(addr.to_uint() & 0xE0000000) >> 29]; } } // namespace IP diff --git a/src/libxrpl/beast/net/IPAddressV6.cpp b/src/libxrpl/beast/net/IPAddressV6.cpp index f90a6d066b..d1b86ba9bd 100644 --- a/src/libxrpl/beast/net/IPAddressV6.cpp +++ b/src/libxrpl/beast/net/IPAddressV6.cpp @@ -20,6 +20,8 @@ #include #include +#include + namespace beast { namespace IP { @@ -28,7 +30,9 @@ is_private(AddressV6 const& addr) { return ( (addr.to_bytes()[0] & 0xfd) || // TODO fc00::/8 too ? - (addr.is_v4_mapped() && is_private(addr.to_v4()))); + (addr.is_v4_mapped() && + is_private(boost::asio::ip::make_address_v4( + boost::asio::ip::v4_mapped, addr)))); } bool diff --git a/src/libxrpl/beast/net/IPEndpoint.cpp b/src/libxrpl/beast/net/IPEndpoint.cpp index ffe664498c..f1ffc23e82 100644 --- a/src/libxrpl/beast/net/IPEndpoint.cpp +++ b/src/libxrpl/beast/net/IPEndpoint.cpp @@ -21,6 +21,8 @@ #include #include +#include +#include #include #include @@ -167,7 +169,7 @@ operator>>(std::istream& is, Endpoint& endpoint) } boost::system::error_code ec; - auto addr = Address::from_string(addrStr, ec); + auto addr = boost::asio::ip::make_address(addrStr, ec); if (ec) { is.setstate(std::ios_base::failbit); diff --git a/src/libxrpl/net/HTTPClient.cpp b/src/libxrpl/net/HTTPClient.cpp index f7d540750a..964be32dd8 100644 --- a/src/libxrpl/net/HTTPClient.cpp +++ b/src/libxrpl/net/HTTPClient.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -55,16 +56,16 @@ class HTTPClientImp : public std::enable_shared_from_this, { public: HTTPClientImp( - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, unsigned short const port, std::size_t maxResponseSize, beast::Journal& j) - : mSocket(io_service, httpClientSSLContext->context()) - , mResolver(io_service) + : mSocket(io_context, httpClientSSLContext->context()) + , mResolver(io_context) , mHeader(maxClientHeaderBytes) , mPort(port) , maxResponseSize_(maxResponseSize) - , mDeadline(io_service) + , mDeadline(io_context) , j_(j) { } @@ -146,18 +147,21 @@ public: { JLOG(j_.trace()) << "Fetch: " << mDeqSites[0]; - auto query = std::make_shared( + auto query = std::make_shared( mDeqSites[0], std::to_string(mPort), boost::asio::ip::resolver_query_base::numeric_service); mQuery = query; - mDeadline.expires_from_now(mTimeout, mShutdown); - - JLOG(j_.trace()) << "expires_from_now: " << mShutdown.message(); - - if (!mShutdown) + try { + mDeadline.expires_after(mTimeout); + } + catch (boost::system::system_error const& e) + { + mShutdown = e.code(); + + JLOG(j_.trace()) << "expires_after: " << mShutdown.message(); mDeadline.async_wait(std::bind( &HTTPClientImp::handleDeadline, shared_from_this(), @@ -169,7 +173,9 @@ public: JLOG(j_.trace()) << "Resolving: " << mDeqSites[0]; mResolver.async_resolve( - *mQuery, + mQuery->host, + mQuery->port, + mQuery->flags, std::bind( &HTTPClientImp::handleResolve, shared_from_this(), @@ -233,7 +239,7 @@ public: void handleResolve( boost::system::error_code const& ecResult, - boost::asio::ip::tcp::resolver::iterator itrEndpoint) + boost::asio::ip::tcp::resolver::results_type result) { if (!mShutdown) { @@ -255,7 +261,7 @@ public: boost::asio::async_connect( mSocket.lowest_layer(), - itrEndpoint, + result, std::bind( &HTTPClientImp::handleConnect, shared_from_this(), @@ -475,13 +481,15 @@ public: std::string const& strData = "") { boost::system::error_code ecCancel; - - (void)mDeadline.cancel(ecCancel); - - if (ecCancel) + try { - JLOG(j_.trace()) << "invokeComplete: Deadline cancel error: " - << ecCancel.message(); + mDeadline.cancel(); + } + catch (boost::system::system_error const& e) + { + JLOG(j_.trace()) + << "invokeComplete: Deadline cancel error: " << e.what(); + ecCancel = e.code(); } JLOG(j_.debug()) << "invokeComplete: Deadline popping: " @@ -515,7 +523,15 @@ private: bool mSSL; AutoSocket mSocket; boost::asio::ip::tcp::resolver mResolver; - std::shared_ptr mQuery; + + struct Query + { + std::string host; + std::string port; + boost::asio::ip::resolver_query_base::flags flags; + }; + std::shared_ptr mQuery; + boost::asio::streambuf mRequest; boost::asio::streambuf mHeader; boost::asio::streambuf mResponse; @@ -546,7 +562,7 @@ private: void HTTPClient::get( bool bSSL, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, std::deque deqSites, unsigned short const port, std::string const& strPath, @@ -559,14 +575,14 @@ HTTPClient::get( beast::Journal& j) { auto client = - std::make_shared(io_service, port, responseMax, j); + std::make_shared(io_context, port, responseMax, j); client->get(bSSL, deqSites, strPath, timeout, complete); } void HTTPClient::get( bool bSSL, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, std::string strSite, unsigned short const port, std::string const& strPath, @@ -581,14 +597,14 @@ HTTPClient::get( std::deque deqSites(1, strSite); auto client = - std::make_shared(io_service, port, responseMax, j); + std::make_shared(io_context, port, responseMax, j); client->get(bSSL, deqSites, strPath, timeout, complete); } void HTTPClient::request( bool bSSL, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, std::string strSite, unsigned short const port, std::function @@ -604,7 +620,7 @@ HTTPClient::request( std::deque deqSites(1, strSite); auto client = - std::make_shared(io_service, port, responseMax, j); + std::make_shared(io_context, port, responseMax, j); client->request(bSSL, deqSites, setRequest, timeout, complete); } diff --git a/src/libxrpl/server/Port.cpp b/src/libxrpl/server/Port.cpp index 95709fc298..be86a77a9f 100644 --- a/src/libxrpl/server/Port.cpp +++ b/src/libxrpl/server/Port.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -219,7 +220,7 @@ parse_Port(ParsedPort& port, Section const& section, std::ostream& log) { try { - port.ip = boost::asio::ip::address::from_string(*optResult); + port.ip = boost::asio::ip::make_address(*optResult); } catch (std::exception const&) { diff --git a/src/test/app/DNS_test.cpp b/src/test/app/DNS_test.cpp index 28a143e93d..c4e476de9f 100644 --- a/src/test/app/DNS_test.cpp +++ b/src/test/app/DNS_test.cpp @@ -63,7 +63,7 @@ public: pUrl_.domain, pUrl_.path, port_, - env_.app().getIOService(), + env_.app().getIOContext(), env_.journal, env_.app().config(), lastEndpoint, @@ -80,10 +80,11 @@ public: isMultipleEndpoints() { using boost::asio::ip::tcp; - tcp::resolver resolver(env_.app().getIOService()); + tcp::resolver resolver(env_.app().getIOContext()); std::string port = pUrl_.port ? std::to_string(*pUrl_.port) : "443"; - tcp::resolver::iterator it = resolver.resolve(pUrl_.domain, port); - tcp::resolver::iterator end; + auto results = resolver.resolve(pUrl_.domain, port); + auto it = results.begin(); + auto end = results.end(); int n = 0; for (; it != end; ++it) ++n; diff --git a/src/test/app/LedgerReplay_test.cpp b/src/test/app/LedgerReplay_test.cpp index 76ab5b3218..88d944d789 100644 --- a/src/test/app/LedgerReplay_test.cpp +++ b/src/test/app/LedgerReplay_test.cpp @@ -1107,7 +1107,7 @@ struct LedgerReplayer_test : public beast::unit_test::suite return false; beast::IP::Address addr = - boost::asio::ip::address::from_string("172.1.1.100"); + boost::asio::ip::make_address("172.1.1.100"); jtx::Env serverEnv(*this); serverEnv.app().config().LEDGER_REPLAY = server; auto http_resp = ripple::makeResponse( diff --git a/src/test/app/ValidatorSite_test.cpp b/src/test/app/ValidatorSite_test.cpp index 7a7511e6f0..579cd79a5a 100644 --- a/src/test/app/ValidatorSite_test.cpp +++ b/src/test/app/ValidatorSite_test.cpp @@ -205,7 +205,7 @@ private: NetClock::time_point const expires2 = effective2 + cfg.expiresFromNow; item.server = make_TrustedPublisherServer( - env.app().getIOService(), + env.app().getIOContext(), item.list, expires, {{effective2, expires2}}, diff --git a/src/test/beast/IPEndpoint_test.cpp b/src/test/beast/IPEndpoint_test.cpp index aed6d715d4..a99dccf5a0 100644 --- a/src/test/beast/IPEndpoint_test.cpp +++ b/src/test/beast/IPEndpoint_test.cpp @@ -45,13 +45,13 @@ public: std::string const& normal = "") { boost::system::error_code ec; - Address const result{Address::from_string(s, ec)}; + Address const result{boost::asio::ip::make_address(s, ec)}; if (!BEAST_EXPECTS(!ec, ec.message())) return; if (!BEAST_EXPECTS(result.is_v4(), s + " not v4")) return; if (!BEAST_EXPECTS( - result.to_v4().to_ulong() == value, s + " value mismatch")) + result.to_v4().to_uint() == value, s + " value mismatch")) return; BEAST_EXPECTS( result.to_string() == (normal.empty() ? s : normal), @@ -62,7 +62,7 @@ public: failParseAddr(std::string const& s) { boost::system::error_code ec; - auto a = Address::from_string(s, ec); + auto a = boost::asio::ip::make_address(s, ec); BEAST_EXPECTS(ec, s + " parses as " + a.to_string()); } @@ -71,24 +71,24 @@ public: { testcase("AddressV4"); - BEAST_EXPECT(AddressV4{}.to_ulong() == 0); + BEAST_EXPECT(AddressV4{}.to_uint() == 0); BEAST_EXPECT(is_unspecified(AddressV4{})); - BEAST_EXPECT(AddressV4{0x01020304}.to_ulong() == 0x01020304); + BEAST_EXPECT(AddressV4{0x01020304}.to_uint() == 0x01020304); { AddressV4::bytes_type d = {{1, 2, 3, 4}}; - BEAST_EXPECT(AddressV4{d}.to_ulong() == 0x01020304); + BEAST_EXPECT(AddressV4{d}.to_uint() == 0x01020304); unexpected(is_unspecified(AddressV4{d})); } AddressV4 const v1{1}; - BEAST_EXPECT(AddressV4{v1}.to_ulong() == 1); + BEAST_EXPECT(AddressV4{v1}.to_uint() == 1); { AddressV4 v; v = v1; - BEAST_EXPECT(v.to_ulong() == v1.to_ulong()); + BEAST_EXPECT(v.to_uint() == v1.to_uint()); } { @@ -99,7 +99,7 @@ public: d[2] = 3; d[3] = 4; v = AddressV4{d}; - BEAST_EXPECT(v.to_ulong() == 0x01020304); + BEAST_EXPECT(v.to_uint() == 0x01020304); } BEAST_EXPECT(AddressV4(0x01020304).to_string() == "1.2.3.4"); @@ -161,7 +161,7 @@ public: testcase("Address"); boost::system::error_code ec; - Address result{Address::from_string("1.2.3.4", ec)}; + Address result{boost::asio::ip::make_address("1.2.3.4", ec)}; AddressV4::bytes_type d = {{1, 2, 3, 4}}; BEAST_EXPECT(!ec); BEAST_EXPECT(result.is_v4() && result.to_v4() == AddressV4{d}); @@ -263,7 +263,10 @@ public: BEAST_EXPECT(is_loopback(ep)); BEAST_EXPECT(to_string(ep) == "127.0.0.1:80"); // same address as v4 mapped in ipv6 - ep = Endpoint(AddressV6::v4_mapped(AddressV4{d}), 80); + ep = Endpoint( + boost::asio::ip::make_address_v6( + boost::asio::ip::v4_mapped, AddressV4{d}), + 80); BEAST_EXPECT(!is_unspecified(ep)); BEAST_EXPECT(!is_public(ep)); BEAST_EXPECT(is_private(ep)); @@ -281,8 +284,11 @@ public: BEAST_EXPECT(!is_loopback(ep)); BEAST_EXPECT(to_string(ep) == "10.0.0.1"); // same address as v4 mapped in ipv6 - ep = Endpoint(AddressV6::v4_mapped(AddressV4{d})); - BEAST_EXPECT(get_class(ep.to_v6().to_v4()) == 'A'); + ep = Endpoint(boost::asio::ip::make_address_v6( + boost::asio::ip::v4_mapped, AddressV4{d})); + BEAST_EXPECT( + get_class(boost::asio::ip::make_address_v4( + boost::asio::ip::v4_mapped, ep.to_v6())) == 'A'); BEAST_EXPECT(!is_unspecified(ep)); BEAST_EXPECT(!is_public(ep)); BEAST_EXPECT(is_private(ep)); @@ -299,7 +305,8 @@ public: BEAST_EXPECT(!is_loopback(ep)); BEAST_EXPECT(to_string(ep) == "166.78.151.147"); // same address as v4 mapped in ipv6 - ep = Endpoint(AddressV6::v4_mapped(AddressV4{d})); + ep = Endpoint(boost::asio::ip::make_address_v6( + boost::asio::ip::v4_mapped, AddressV4{d})); BEAST_EXPECT(!is_unspecified(ep)); BEAST_EXPECT(is_public(ep)); BEAST_EXPECT(!is_private(ep)); diff --git a/src/test/beast/beast_io_latency_probe_test.cpp b/src/test/beast/beast_io_latency_probe_test.cpp index c72336bf27..841272d05a 100644 --- a/src/test/beast/beast_io_latency_probe_test.cpp +++ b/src/test/beast/beast_io_latency_probe_test.cpp @@ -23,7 +23,8 @@ #include #include -#include +#include +#include #include #include @@ -60,8 +61,10 @@ class io_latency_probe_test : public beast::unit_test::suite, measure_asio_timers(duration interval = 100ms, size_t num_samples = 50) { using namespace std::chrono; - boost::asio::io_service ios; - std::optional work{ios}; + boost::asio::io_context ios; + std::optional> + work{boost::asio::make_work_guard(ios)}; std::thread worker{[&] { ios.run(); }}; boost::asio::basic_waitable_timer timer{ios}; elapsed_times_.reserve(num_samples); @@ -135,7 +138,7 @@ class io_latency_probe_test : public beast::unit_test::suite, test_sampler( std::chrono::milliseconds interval, - boost::asio::io_service& ios) + boost::asio::io_context& ios) : probe_(interval, ios) { } @@ -164,9 +167,9 @@ class io_latency_probe_test : public beast::unit_test::suite, { testcase << "sample one"; boost::system::error_code ec; - test_sampler io_probe{100ms, get_io_service()}; + test_sampler io_probe{100ms, get_io_context()}; io_probe.start_one(); - MyTimer timer{get_io_service(), 1s}; + MyTimer timer{get_io_context(), 1s}; timer.async_wait(yield[ec]); if (!BEAST_EXPECTS(!ec, ec.message())) return; @@ -198,9 +201,9 @@ class io_latency_probe_test : public beast::unit_test::suite, duration_cast(probe_duration).count()) / static_cast(tt.getMean()); #endif - test_sampler io_probe{interval, get_io_service()}; + test_sampler io_probe{interval, get_io_context()}; io_probe.start(); - MyTimer timer{get_io_service(), probe_duration}; + MyTimer timer{get_io_context(), probe_duration}; timer.async_wait(yield[ec]); if (!BEAST_EXPECTS(!ec, ec.message())) return; @@ -212,7 +215,7 @@ class io_latency_probe_test : public beast::unit_test::suite, io_probe.probe_.cancel_async(); // wait again in order to flush the remaining // probes from the work queue - timer.expires_from_now(1s); + timer.expires_after(1s); timer.async_wait(yield[ec]); } @@ -220,7 +223,7 @@ class io_latency_probe_test : public beast::unit_test::suite, testCanceled(boost::asio::yield_context& yield) { testcase << "canceled"; - test_sampler io_probe{100ms, get_io_service()}; + test_sampler io_probe{100ms, get_io_context()}; io_probe.probe_.cancel_async(); except([&io_probe]() { io_probe.start_one(); }); except([&io_probe]() { io_probe.start(); }); diff --git a/src/test/jtx/TrustedPublisherServer.h b/src/test/jtx/TrustedPublisherServer.h index 7bc092cbe3..26e676c024 100644 --- a/src/test/jtx/TrustedPublisherServer.h +++ b/src/test/jtx/TrustedPublisherServer.h @@ -183,7 +183,7 @@ public: bool immediateStart = true, int sequence = 1) : sock_{ioc} - , ep_{beast::IP::Address::from_string( + , ep_{boost::asio::ip::make_address( ripple::test::getEnvLocalhostAddr()), // 0 means let OS pick the port based on what's available 0} @@ -284,7 +284,7 @@ public: acceptor_.set_option( boost::asio::ip::tcp::acceptor::reuse_address(true), ec); acceptor_.bind(ep_); - acceptor_.listen(boost::asio::socket_base::max_connections); + acceptor_.listen(boost::asio::socket_base::max_listen_connections); acceptor_.async_accept( sock_, [wp = std::weak_ptr{shared_from_this()}]( diff --git a/src/test/jtx/impl/JSONRPCClient.cpp b/src/test/jtx/impl/JSONRPCClient.cpp index 4db13c95fd..a4c5817788 100644 --- a/src/test/jtx/impl/JSONRPCClient.cpp +++ b/src/test/jtx/impl/JSONRPCClient.cpp @@ -78,7 +78,7 @@ class JSONRPCClient : public AbstractClient } boost::asio::ip::tcp::endpoint ep_; - boost::asio::io_service ios_; + boost::asio::io_context ios_; boost::asio::ip::tcp::socket stream_; boost::beast::multi_buffer bin_; boost::beast::multi_buffer bout_; diff --git a/src/test/jtx/impl/WSClient.cpp b/src/test/jtx/impl/WSClient.cpp index 20cca3179a..a3dc7d9733 100644 --- a/src/test/jtx/impl/WSClient.cpp +++ b/src/test/jtx/impl/WSClient.cpp @@ -25,6 +25,9 @@ #include #include +#include +#include +#include #include #include @@ -89,9 +92,11 @@ class WSClientImpl : public WSClient return s; } - boost::asio::io_service ios_; - std::optional work_; - boost::asio::io_service::strand strand_; + boost::asio::io_context ios_; + std::optional> + work_; + boost::asio::strand strand_; std::thread thread_; boost::asio::ip::tcp::socket stream_; boost::beast::websocket::stream ws_; @@ -114,14 +119,24 @@ class WSClientImpl : public WSClient void cleanup() { - ios_.post(strand_.wrap([this] { - if (!peerClosed_) - { - ws_.async_close({}, strand_.wrap([&](error_code ec) { - stream_.cancel(ec); - })); - } - })); + boost::asio::post( + ios_, boost::asio::bind_executor(strand_, [this] { + if (!peerClosed_) + { + ws_.async_close( + {}, + boost::asio::bind_executor(strand_, [&](error_code) { + try + { + stream_.cancel(); + } + catch (boost::system::system_error const&) + { + // ignored + } + })); + } + })); work_ = std::nullopt; thread_.join(); } @@ -132,8 +147,8 @@ public: bool v2, unsigned rpc_version, std::unordered_map const& headers = {}) - : work_(ios_) - , strand_(ios_) + : work_(std::in_place, boost::asio::make_work_guard(ios_)) + , strand_(boost::asio::make_strand(ios_)) , thread_([&] { ios_.run(); }) , stream_(ios_) , ws_(stream_) @@ -153,8 +168,12 @@ public: "/"); ws_.async_read( rb_, - strand_.wrap(std::bind( - &WSClientImpl::on_read_msg, this, std::placeholders::_1))); + boost::asio::bind_executor( + strand_, + std::bind( + &WSClientImpl::on_read_msg, + this, + std::placeholders::_1))); } catch (std::exception&) { @@ -284,8 +303,10 @@ private: } ws_.async_read( rb_, - strand_.wrap(std::bind( - &WSClientImpl::on_read_msg, this, std::placeholders::_1))); + boost::asio::bind_executor( + strand_, + std::bind( + &WSClientImpl::on_read_msg, this, std::placeholders::_1))); } // Called when the read op terminates diff --git a/src/test/overlay/compression_test.cpp b/src/test/overlay/compression_test.cpp index 01be43d58b..4bfbcae4f0 100644 --- a/src/test/overlay/compression_test.cpp +++ b/src/test/overlay/compression_test.cpp @@ -485,7 +485,7 @@ public: }; auto handshake = [&](int outboundEnable, int inboundEnable) { beast::IP::Address addr = - boost::asio::ip::address::from_string("172.1.1.100"); + boost::asio::ip::make_address("172.1.1.100"); auto env = getEnv(outboundEnable); auto request = ripple::makeRequest( diff --git a/src/test/overlay/reduce_relay_test.cpp b/src/test/overlay/reduce_relay_test.cpp index 0047454cf9..e53f53f2db 100644 --- a/src/test/overlay/reduce_relay_test.cpp +++ b/src/test/overlay/reduce_relay_test.cpp @@ -1655,7 +1655,7 @@ vp_base_squelch_max_selected_peers=2 }; auto handshake = [&](int outboundEnable, int inboundEnable) { beast::IP::Address addr = - boost::asio::ip::address::from_string("172.1.1.100"); + boost::asio::ip::make_address("172.1.1.100"); setEnv(outboundEnable); auto request = ripple::makeRequest( diff --git a/src/test/overlay/short_read_test.cpp b/src/test/overlay/short_read_test.cpp index 739d7ea954..88c6e7698b 100644 --- a/src/test/overlay/short_read_test.cpp +++ b/src/test/overlay/short_read_test.cpp @@ -23,12 +23,17 @@ #include #include -#include +#include +#include +#include +#include #include +#include +#include #include +#include #include -#include #include #include @@ -49,7 +54,7 @@ class short_read_test : public beast::unit_test::suite { private: using io_context_type = boost::asio::io_context; - using strand_type = boost::asio::io_context::strand; + using strand_type = boost::asio::strand; using timer_type = boost::asio::basic_waitable_timer; using acceptor_type = boost::asio::ip::tcp::acceptor; @@ -60,7 +65,8 @@ private: using address_type = boost::asio::ip::address; io_context_type io_context_; - std::optional> + boost::optional> work_; std::thread thread_; std::shared_ptr context_; @@ -72,7 +78,7 @@ private: using boost::asio::buffer; using boost::asio::buffer_copy; using boost::asio::buffer_size; - boost::asio::const_buffers_1 buf(s.data(), s.size()); + boost::asio::const_buffer buf(s.data(), s.size()); sb.commit(buffer_copy(sb.prepare(buffer_size(buf)), buf)); } @@ -185,11 +191,11 @@ private: , acceptor_( test_.io_context_, endpoint_type( - beast::IP::Address::from_string( + boost::asio::ip::make_address( test::getEnvLocalhostAddr()), 0)) , socket_(test_.io_context_) - , strand_(test_.io_context_) + , strand_(boost::asio::make_strand(test_.io_context_)) { acceptor_.listen(); server_.endpoint_ = acceptor_.local_endpoint(); @@ -265,7 +271,7 @@ private: , test_(server_.test_) , socket_(std::move(socket)) , stream_(socket_, *test_.context_) - , strand_(test_.io_context_) + , strand_(boost::asio::make_strand(test_.io_context_)) , timer_(test_.io_context_) { } @@ -287,7 +293,7 @@ private: void run() { - timer_.expires_from_now(std::chrono::seconds(3)); + timer_.expires_after(std::chrono::seconds(3)); timer_.async_wait(bind_executor( strand_, std::bind( @@ -450,7 +456,7 @@ private: , test_(client_.test_) , socket_(test_.io_context_) , stream_(socket_, *test_.context_) - , strand_(test_.io_context_) + , strand_(boost::asio::make_strand(test_.io_context_)) , timer_(test_.io_context_) , ep_(ep) { @@ -473,7 +479,7 @@ private: void run(endpoint_type const& ep) { - timer_.expires_from_now(std::chrono::seconds(3)); + timer_.expires_after(std::chrono::seconds(3)); timer_.async_wait(bind_executor( strand_, std::bind( diff --git a/src/test/overlay/tx_reduce_relay_test.cpp b/src/test/overlay/tx_reduce_relay_test.cpp index 0024f2b98e..0c67fd581c 100644 --- a/src/test/overlay/tx_reduce_relay_test.cpp +++ b/src/test/overlay/tx_reduce_relay_test.cpp @@ -174,13 +174,13 @@ private: makeFeaturesRequestHeader(false, false, true, false)) : (void)nDisabled--; auto stream_ptr = std::make_unique( - socket_type(std::forward( - env.app().getIOService())), + socket_type(std::forward( + env.app().getIOContext())), *context_); beast::IP::Endpoint local( - beast::IP::Address::from_string("172.1.1." + std::to_string(lid_))); + boost::asio::ip::make_address("172.1.1." + std::to_string(lid_))); beast::IP::Endpoint remote( - beast::IP::Address::from_string("172.1.1." + std::to_string(rid_))); + boost::asio::ip::make_address("172.1.1." + std::to_string(rid_))); PublicKey key(std::get<0>(randomKeyPair(KeyType::ed25519))); auto consumer = overlay.resourceManager().newInboundEndpoint(remote); auto slot = overlay.peerFinder().new_inbound_slot(local, remote); diff --git a/src/test/rpc/ValidatorRPC_test.cpp b/src/test/rpc/ValidatorRPC_test.cpp index d139a662de..bc54c8567c 100644 --- a/src/test/rpc/ValidatorRPC_test.cpp +++ b/src/test/rpc/ValidatorRPC_test.cpp @@ -187,14 +187,14 @@ public: for (auto const& val : validators) expectedKeys.insert(toStr(val.masterPublic)); - // Manage single-thread io_service for server. + // Manage single-thread io_context for server. BasicApp worker{1}; using namespace std::chrono_literals; NetClock::time_point const validUntil{3600s}; NetClock::time_point const validFrom2{validUntil - 60s}; NetClock::time_point const validUntil2{validFrom2 + 3600s}; auto server = make_TrustedPublisherServer( - worker.get_io_service(), + worker.get_io_context(), validators, validUntil, {{validFrom2, validUntil2}}, diff --git a/src/test/server/ServerStatus_test.cpp b/src/test/server/ServerStatus_test.cpp index b27dee6e0a..8bbad2cd99 100644 --- a/src/test/server/ServerStatus_test.cpp +++ b/src/test/server/ServerStatus_test.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -165,12 +166,11 @@ class ServerStatus_test : public beast::unit_test::suite, { using namespace boost::asio; using namespace boost::beast::http; - io_service& ios = get_io_service(); + io_context& ios = get_io_context(); ip::tcp::resolver r{ios}; boost::beast::multi_buffer sb; - auto it = r.async_resolve( - ip::tcp::resolver::query{host, std::to_string(port)}, yield[ec]); + auto it = r.async_resolve(host, std::to_string(port), yield[ec]); if (ec) return; @@ -476,12 +476,11 @@ class ServerStatus_test : public beast::unit_test::suite, auto req_string = boost::lexical_cast(req); req_string.erase(req_string.find_last_of("13"), std::string::npos); - io_service& ios = get_io_service(); + io_context& ios = get_io_context(); ip::tcp::resolver r{ios}; boost::beast::multi_buffer sb; - auto it = r.async_resolve( - ip::tcp::resolver::query{*ip, std::to_string(*port)}, yield[ec]); + auto it = r.async_resolve(*ip, std::to_string(*port), yield[ec]); if (!BEAST_EXPECTS(!ec, ec.message())) return; @@ -610,14 +609,13 @@ class ServerStatus_test : public beast::unit_test::suite, env.app().config()["port_rpc"].get("ip").value(); boost::system::error_code ec; - io_service& ios = get_io_service(); + io_context& ios = get_io_context(); ip::tcp::resolver r{ios}; Json::Value jr; jr[jss::method] = "server_info"; - auto it = r.async_resolve( - ip::tcp::resolver::query{ip, std::to_string(port)}, yield[ec]); + auto it = r.async_resolve(ip, std::to_string(port), yield[ec]); BEAST_EXPECT(!ec); std::vector> @@ -681,7 +679,7 @@ class ServerStatus_test : public beast::unit_test::suite, resp["Upgrade"] == "websocket"); BEAST_EXPECT( resp.find("Connection") != resp.end() && - resp["Connection"] == "Upgrade"); + boost::iequals(resp["Connection"], "upgrade")); } void @@ -728,11 +726,10 @@ class ServerStatus_test : public beast::unit_test::suite, env.app().config()["port_ws"].get("ip").value(); boost::system::error_code ec; - io_service& ios = get_io_service(); + io_context& ios = get_io_context(); ip::tcp::resolver r{ios}; - auto it = r.async_resolve( - ip::tcp::resolver::query{ip, std::to_string(port)}, yield[ec]); + auto it = r.async_resolve(ip, std::to_string(port), yield[ec]); if (!BEAST_EXPECT(!ec)) return; diff --git a/src/test/server/Server_test.cpp b/src/test/server/Server_test.cpp index fab271ff1c..874558f428 100644 --- a/src/test/server/Server_test.cpp +++ b/src/test/server/Server_test.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -52,14 +53,16 @@ public: class TestThread { private: - boost::asio::io_service io_service_; - std::optional work_; + boost::asio::io_context io_context_; + std::optional> + work_; std::thread thread_; public: TestThread() - : work_(std::in_place, std::ref(io_service_)) - , thread_([&]() { this->io_service_.run(); }) + : work_(std::in_place, boost::asio::make_work_guard(io_context_)) + , thread_([&]() { this->io_context_.run(); }) { } @@ -69,10 +72,10 @@ public: thread_.join(); } - boost::asio::io_service& - get_io_service() + boost::asio::io_context& + get_io_context() { - return io_service_; + return io_context_; } }; @@ -234,7 +237,7 @@ public: void test_request(boost::asio::ip::tcp::endpoint const& ep) { - boost::asio::io_service ios; + boost::asio::io_context ios; using socket = boost::asio::ip::tcp::socket; socket s(ios); @@ -260,7 +263,7 @@ public: void test_keepalive(boost::asio::ip::tcp::endpoint const& ep) { - boost::asio::io_service ios; + boost::asio::io_context ios; using socket = boost::asio::ip::tcp::socket; socket s(ios); @@ -300,10 +303,10 @@ public: sink.threshold(beast::severities::Severity::kAll); beast::Journal journal{sink}; TestHandler handler; - auto s = make_Server(handler, thread.get_io_service(), journal); + auto s = make_Server(handler, thread.get_io_context(), journal); std::vector serverPort(1); serverPort.back().ip = - beast::IP::Address::from_string(getEnvLocalhostAddr()), + boost::asio::ip::make_address(getEnvLocalhostAddr()), serverPort.back().port = 0; serverPort.back().protocol.insert("http"); auto eps = s->ports(serverPort); @@ -375,10 +378,10 @@ public: for (int i = 0; i < 1000; ++i) { TestThread thread; - auto s = make_Server(h, thread.get_io_service(), journal); + auto s = make_Server(h, thread.get_io_context(), journal); std::vector serverPort(1); serverPort.back().ip = - beast::IP::Address::from_string(getEnvLocalhostAddr()), + boost::asio::ip::make_address(getEnvLocalhostAddr()), serverPort.back().port = 0; serverPort.back().protocol.insert("http"); s->ports(serverPort); diff --git a/src/xrpld/app/ledger/detail/TimeoutCounter.cpp b/src/xrpld/app/ledger/detail/TimeoutCounter.cpp index e81ec6574d..774b70e4d1 100644 --- a/src/xrpld/app/ledger/detail/TimeoutCounter.cpp +++ b/src/xrpld/app/ledger/detail/TimeoutCounter.cpp @@ -39,7 +39,7 @@ TimeoutCounter::TimeoutCounter( , progress_(false) , timerInterval_(interval) , queueJobParameter_(std::move(jobParameter)) - , timer_(app_.getIOService()) + , timer_(app_.getIOContext()) { XRPL_ASSERT( (timerInterval_ > 10ms) && (timerInterval_ < 30s), diff --git a/src/xrpld/app/ledger/detail/TimeoutCounter.h b/src/xrpld/app/ledger/detail/TimeoutCounter.h index 85ce6fc3b4..8da290dd36 100644 --- a/src/xrpld/app/ledger/detail/TimeoutCounter.h +++ b/src/xrpld/app/ledger/detail/TimeoutCounter.h @@ -120,7 +120,7 @@ protected: return complete_ || failed_; } - // Used in this class for access to boost::asio::io_service and + // Used in this class for access to boost::asio::io_context and // ripple::Overlay. Used in subtypes for the kitchen sink. Application& app_; beast::Journal journal_; diff --git a/src/xrpld/app/main/Application.cpp b/src/xrpld/app/main/Application.cpp index c824eccfba..beaf85ce2e 100644 --- a/src/xrpld/app/main/Application.cpp +++ b/src/xrpld/app/main/Application.cpp @@ -83,7 +83,6 @@ #include #include #include -#include #include namespace ripple { @@ -108,7 +107,7 @@ private: beast::insight::Event ev, beast::Journal journal, std::chrono::milliseconds interval, - boost::asio::io_service& ios) + boost::asio::io_context& ios) : m_event(ev) , m_journal(journal) , m_probe(interval, ios) @@ -136,7 +135,7 @@ private: if (lastSample >= 500ms) { JLOG(m_journal.warn()) - << "io_service latency = " << lastSample.count(); + << "io_context latency = " << lastSample.count(); } } @@ -405,7 +404,7 @@ public: *m_jobQueue, *m_ledgerMaster, validatorKeys_, - get_io_service(), + get_io_context(), logs_->journal("NetworkOPs"), m_collectorManager->collector())) @@ -432,7 +431,7 @@ public: , serverHandler_(make_ServerHandler( *this, - get_io_service(), + get_io_context(), *m_jobQueue, *m_networkOPs, *m_resourceManager, @@ -456,22 +455,22 @@ public: , txQ_( std::make_unique(setup_TxQ(*config_), logs_->journal("TxQ"))) - , sweepTimer_(get_io_service()) + , sweepTimer_(get_io_context()) - , entropyTimer_(get_io_service()) + , entropyTimer_(get_io_context()) - , m_signals(get_io_service()) + , m_signals(get_io_context()) , checkSigs_(true) , m_resolver( - ResolverAsio::New(get_io_service(), logs_->journal("Resolver"))) + ResolverAsio::New(get_io_context(), logs_->journal("Resolver"))) , m_io_latency_sampler( m_collectorManager->collector()->make_event("ios_latency"), logs_->journal("Application"), std::chrono::milliseconds(100), - get_io_service()) + get_io_context()) , grpcServer_(std::make_unique(*this)) { initAccountIdCache(config_->getValueFor(SizedItem::accountIdCacheSize)); @@ -594,10 +593,10 @@ public: return *serverHandler_; } - boost::asio::io_service& - getIOService() override + boost::asio::io_context& + getIOContext() override { - return get_io_service(); + return get_io_context(); } std::chrono::milliseconds @@ -935,9 +934,8 @@ public: })) { using namespace std::chrono; - sweepTimer_.expires_from_now( - seconds{config_->SWEEP_INTERVAL.value_or( - config_->getValueFor(SizedItem::sweepInterval))}); + sweepTimer_.expires_after(seconds{config_->SWEEP_INTERVAL.value_or( + config_->getValueFor(SizedItem::sweepInterval))}); sweepTimer_.async_wait(std::move(*optionalCountedHandler)); } } @@ -966,7 +964,7 @@ public: })) { using namespace std::chrono_literals; - entropyTimer_.expires_from_now(5min); + entropyTimer_.expires_after(5min); entropyTimer_.async_wait(std::move(*optionalCountedHandler)); } } @@ -1398,7 +1396,7 @@ ApplicationImp::setup(boost::program_options::variables_map const& cmdline) *serverHandler_, *m_resourceManager, *m_resolver, - get_io_service(), + get_io_context(), *config_, m_collectorManager->collector()); add(*overlay_); // add to PropertyStream @@ -1571,11 +1569,11 @@ ApplicationImp::run() m_io_latency_sampler.cancel_async(); // VFALCO Enormous hack, we have to force the probe to cancel - // before we stop the io_service queue or else it never + // before we stop the io_context queue or else it never // unblocks in its destructor. The fix is to make all // io_objects gracefully handle exit so that we can - // naturally return from io_service::run() instead of - // forcing a call to io_service::stop() + // naturally return from io_context::run() instead of + // forcing a call to io_context::stop() m_io_latency_sampler.cancel(); m_resolver->stop_async(); @@ -1586,20 +1584,24 @@ ApplicationImp::run() m_resolver->stop(); { - boost::system::error_code ec; - sweepTimer_.cancel(ec); - if (ec) + try + { + sweepTimer_.cancel(); + } + catch (boost::system::system_error const& e) { JLOG(m_journal.error()) - << "Application: sweepTimer cancel error: " << ec.message(); + << "Application: sweepTimer cancel error: " << e.what(); } - ec.clear(); - entropyTimer_.cancel(ec); - if (ec) + try + { + entropyTimer_.cancel(); + } + catch (boost::system::system_error const& e) { JLOG(m_journal.error()) - << "Application: entropyTimer cancel error: " << ec.message(); + << "Application: entropyTimer cancel error: " << e.what(); } } diff --git a/src/xrpld/app/main/Application.h b/src/xrpld/app/main/Application.h index 36477cb75c..b3a433fee8 100644 --- a/src/xrpld/app/main/Application.h +++ b/src/xrpld/app/main/Application.h @@ -162,8 +162,8 @@ public: virtual Config& config() = 0; - virtual boost::asio::io_service& - getIOService() = 0; + virtual boost::asio::io_context& + getIOContext() = 0; virtual CollectorManager& getCollectorManager() = 0; diff --git a/src/xrpld/app/main/BasicApp.cpp b/src/xrpld/app/main/BasicApp.cpp index a4b1a74685..87f440dfc8 100644 --- a/src/xrpld/app/main/BasicApp.cpp +++ b/src/xrpld/app/main/BasicApp.cpp @@ -21,9 +21,11 @@ #include +#include + BasicApp::BasicApp(std::size_t numberOfThreads) { - work_.emplace(io_service_); + work_.emplace(boost::asio::make_work_guard(io_context_)); threads_.reserve(numberOfThreads); while (numberOfThreads--) @@ -31,7 +33,7 @@ BasicApp::BasicApp(std::size_t numberOfThreads) threads_.emplace_back([this, numberOfThreads]() { beast::setCurrentThreadName( "io svc #" + std::to_string(numberOfThreads)); - this->io_service_.run(); + this->io_context_.run(); }); } } diff --git a/src/xrpld/app/main/BasicApp.h b/src/xrpld/app/main/BasicApp.h index cd1e8c1a71..276676ca18 100644 --- a/src/xrpld/app/main/BasicApp.h +++ b/src/xrpld/app/main/BasicApp.h @@ -20,28 +20,30 @@ #ifndef RIPPLE_APP_BASICAPP_H_INCLUDED #define RIPPLE_APP_BASICAPP_H_INCLUDED -#include +#include #include #include #include -// This is so that the io_service can outlive all the children +// This is so that the io_context can outlive all the children class BasicApp { private: - std::optional work_; + std::optional> + work_; std::vector threads_; - boost::asio::io_service io_service_; + boost::asio::io_context io_context_; public: BasicApp(std::size_t numberOfThreads); ~BasicApp(); - boost::asio::io_service& - get_io_service() + boost::asio::io_context& + get_io_context() { - return io_service_; + return io_context_; } }; diff --git a/src/xrpld/app/main/Main.cpp b/src/xrpld/app/main/Main.cpp index 3fdf362dd9..2353d7acd1 100644 --- a/src/xrpld/app/main/Main.cpp +++ b/src/xrpld/app/main/Main.cpp @@ -28,12 +28,17 @@ #include #include +#include +#include +#include +#include + #ifdef ENABLE_TESTS #include #include #endif // ENABLE_TESTS -#include +#include #include #include @@ -283,7 +288,7 @@ runUnitTests( if (!child) { multi_runner_parent parent_runner; - std::vector children; + std::vector children; std::string const exe_name = argv[0]; std::vector args; @@ -296,7 +301,8 @@ runUnitTests( for (std::size_t i = 0; i < num_jobs; ++i) children.emplace_back( - boost::process::exe = exe_name, boost::process::args = args); + boost::process::v1::exe = exe_name, + boost::process::v1::args = args); int bad_child_exits = 0; int terminated_child_exits = 0; diff --git a/src/xrpld/app/misc/NetworkOPs.cpp b/src/xrpld/app/misc/NetworkOPs.cpp index 3220ce99fc..403090c390 100644 --- a/src/xrpld/app/misc/NetworkOPs.cpp +++ b/src/xrpld/app/misc/NetworkOPs.cpp @@ -233,7 +233,7 @@ public: JobQueue& job_queue, LedgerMaster& ledgerMaster, ValidatorKeys const& validatorKeys, - boost::asio::io_service& io_svc, + boost::asio::io_context& io_svc, beast::Journal journal, beast::insight::Collector::ptr const& collector) : app_(app) @@ -588,31 +588,35 @@ public: stop() override { { - boost::system::error_code ec; - heartbeatTimer_.cancel(ec); - if (ec) + try + { + heartbeatTimer_.cancel(); + } + catch (boost::system::system_error const& e) { JLOG(m_journal.error()) - << "NetworkOPs: heartbeatTimer cancel error: " - << ec.message(); + << "NetworkOPs: heartbeatTimer cancel error: " << e.what(); } - ec.clear(); - clusterTimer_.cancel(ec); - if (ec) + try + { + clusterTimer_.cancel(); + } + catch (boost::system::system_error const& e) { JLOG(m_journal.error()) - << "NetworkOPs: clusterTimer cancel error: " - << ec.message(); + << "NetworkOPs: clusterTimer cancel error: " << e.what(); } - ec.clear(); - accountHistoryTxTimer_.cancel(ec); - if (ec) + try + { + accountHistoryTxTimer_.cancel(); + } + catch (boost::system::system_error const& e) { JLOG(m_journal.error()) << "NetworkOPs: accountHistoryTxTimer cancel error: " - << ec.message(); + << e.what(); } } // Make sure that any waitHandlers pending in our timers are done. @@ -984,7 +988,7 @@ NetworkOPsImp::setTimer( } })) { - timer.expires_from_now(expiry_time); + timer.expires_after(expiry_time); timer.async_wait(std::move(*optionalCountedHandler)); } } @@ -4855,7 +4859,7 @@ make_NetworkOPs( JobQueue& job_queue, LedgerMaster& ledgerMaster, ValidatorKeys const& validatorKeys, - boost::asio::io_service& io_svc, + boost::asio::io_context& io_svc, beast::Journal journal, beast::insight::Collector::ptr const& collector) { diff --git a/src/xrpld/app/misc/NetworkOPs.h b/src/xrpld/app/misc/NetworkOPs.h index 639cd782b7..9587d63b3a 100644 --- a/src/xrpld/app/misc/NetworkOPs.h +++ b/src/xrpld/app/misc/NetworkOPs.h @@ -290,7 +290,7 @@ make_NetworkOPs( JobQueue& job_queue, LedgerMaster& ledgerMaster, ValidatorKeys const& validatorKeys, - boost::asio::io_service& io_svc, + boost::asio::io_context& io_svc, beast::Journal journal, beast::insight::Collector::ptr const& collector); diff --git a/src/xrpld/app/misc/detail/ValidatorSite.cpp b/src/xrpld/app/misc/detail/ValidatorSite.cpp index 42d4e9e271..e235ff3e66 100644 --- a/src/xrpld/app/misc/detail/ValidatorSite.cpp +++ b/src/xrpld/app/misc/detail/ValidatorSite.cpp @@ -91,7 +91,7 @@ ValidatorSite::ValidatorSite( std::chrono::seconds timeout) : app_{app} , j_{j ? *j : app_.logs().journal("ValidatorSite")} - , timer_{app_.getIOService()} + , timer_{app_.getIOContext()} , fetching_{false} , pending_{false} , stopping_{false} @@ -271,7 +271,7 @@ ValidatorSite::makeRequest( resource->pUrl.domain, resource->pUrl.path, std::to_string(*resource->pUrl.port), - app_.getIOService(), + app_.getIOContext(), j_, app_.config(), sites_[siteIdx].lastRequestEndpoint, @@ -284,7 +284,7 @@ ValidatorSite::makeRequest( resource->pUrl.domain, resource->pUrl.path, std::to_string(*resource->pUrl.port), - app_.getIOService(), + app_.getIOContext(), sites_[siteIdx].lastRequestEndpoint, sites_[siteIdx].lastRequestSuccessful, onFetch); @@ -293,7 +293,7 @@ ValidatorSite::makeRequest( { BOOST_ASSERT(resource->pUrl.scheme == "file"); sp = std::make_shared( - resource->pUrl.path, app_.getIOService(), onFetchFile); + resource->pUrl.path, app_.getIOContext(), onFetchFile); } sites_[siteIdx].lastRequestSuccessful = false; diff --git a/src/xrpld/app/misc/detail/WorkBase.h b/src/xrpld/app/misc/detail/WorkBase.h index 17f935126b..a73cd3d597 100644 --- a/src/xrpld/app/misc/detail/WorkBase.h +++ b/src/xrpld/app/misc/detail/WorkBase.h @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -57,8 +58,8 @@ protected: std::string path_; std::string port_; callback_type cb_; - boost::asio::io_service& ios_; - boost::asio::io_service::strand strand_; + boost::asio::io_context& ios_; + boost::asio::strand strand_; resolver_type resolver_; socket_type socket_; request_type req_; @@ -72,7 +73,7 @@ public: std::string const& host, std::string const& path, std::string const& port, - boost::asio::io_service& ios, + boost::asio::io_context& ios, endpoint_type const& lastEndpoint, bool lastStatus, callback_type cb); @@ -120,7 +121,7 @@ WorkBase::WorkBase( std::string const& host, std::string const& path, std::string const& port, - boost::asio::io_service& ios, + boost::asio::io_context& ios, endpoint_type const& lastEndpoint, bool lastStatus, callback_type cb) @@ -129,7 +130,7 @@ WorkBase::WorkBase( , port_(port) , cb_(std::move(cb)) , ios_(ios) - , strand_(ios) + , strand_(boost::asio::make_strand(ios)) , resolver_(ios) , socket_(ios) , lastEndpoint_{lastEndpoint} @@ -152,17 +153,21 @@ void WorkBase::run() { if (!strand_.running_in_this_thread()) - return ios_.post( - strand_.wrap(std::bind(&WorkBase::run, impl().shared_from_this()))); + return boost::asio::post( + ios_, + boost::asio::bind_executor( + strand_, std::bind(&WorkBase::run, impl().shared_from_this()))); resolver_.async_resolve( host_, port_, - strand_.wrap(std::bind( - &WorkBase::onResolve, - impl().shared_from_this(), - std::placeholders::_1, - std::placeholders::_2))); + boost::asio::bind_executor( + strand_, + std::bind( + &WorkBase::onResolve, + impl().shared_from_this(), + std::placeholders::_1, + std::placeholders::_2))); } template @@ -171,8 +176,12 @@ WorkBase::cancel() { if (!strand_.running_in_this_thread()) { - return ios_.post(strand_.wrap( - std::bind(&WorkBase::cancel, impl().shared_from_this()))); + return boost::asio::post( + ios_, + + boost::asio::bind_executor( + strand_, + std::bind(&WorkBase::cancel, impl().shared_from_this()))); } error_code ec; @@ -201,11 +210,13 @@ WorkBase::onResolve(error_code const& ec, results_type results) boost::asio::async_connect( socket_, results, - strand_.wrap(std::bind( - &WorkBase::onConnect, - impl().shared_from_this(), - std::placeholders::_1, - std::placeholders::_2))); + boost::asio::bind_executor( + strand_, + std::bind( + &WorkBase::onConnect, + impl().shared_from_this(), + std::placeholders::_1, + std::placeholders::_2))); } template @@ -233,10 +244,12 @@ WorkBase::onStart() boost::beast::http::async_write( impl().stream(), req_, - strand_.wrap(std::bind( - &WorkBase::onRequest, - impl().shared_from_this(), - std::placeholders::_1))); + boost::asio::bind_executor( + strand_, + std::bind( + &WorkBase::onRequest, + impl().shared_from_this(), + std::placeholders::_1))); } template @@ -250,10 +263,12 @@ WorkBase::onRequest(error_code const& ec) impl().stream(), readBuf_, res_, - strand_.wrap(std::bind( - &WorkBase::onResponse, - impl().shared_from_this(), - std::placeholders::_1))); + boost::asio::bind_executor( + strand_, + std::bind( + &WorkBase::onResponse, + impl().shared_from_this(), + std::placeholders::_1))); } template diff --git a/src/xrpld/app/misc/detail/WorkFile.h b/src/xrpld/app/misc/detail/WorkFile.h index 51fd6db78c..562e1c9ec1 100644 --- a/src/xrpld/app/misc/detail/WorkFile.h +++ b/src/xrpld/app/misc/detail/WorkFile.h @@ -26,6 +26,10 @@ #include #include +#include +#include +#include + namespace ripple { namespace detail { @@ -45,7 +49,7 @@ public: public: WorkFile( std::string const& path, - boost::asio::io_service& ios, + boost::asio::io_context& ios, callback_type cb); ~WorkFile(); @@ -58,17 +62,20 @@ public: private: std::string path_; callback_type cb_; - boost::asio::io_service& ios_; - boost::asio::io_service::strand strand_; + boost::asio::io_context& ios_; + boost::asio::strand strand_; }; //------------------------------------------------------------------------------ WorkFile::WorkFile( std::string const& path, - boost::asio::io_service& ios, + boost::asio::io_context& ios, callback_type cb) - : path_(path), cb_(std::move(cb)), ios_(ios), strand_(ios) + : path_(path) + , cb_(std::move(cb)) + , ios_(ios) + , strand_(boost::asio::make_strand(ios)) { } @@ -82,8 +89,10 @@ void WorkFile::run() { if (!strand_.running_in_this_thread()) - return ios_.post( - strand_.wrap(std::bind(&WorkFile::run, shared_from_this()))); + return boost::asio::post( + ios_, + boost::asio::bind_executor( + strand_, std::bind(&WorkFile::run, shared_from_this()))); error_code ec; auto const fileContents = getFileContents(ec, path_, megabytes(1)); diff --git a/src/xrpld/app/misc/detail/WorkPlain.h b/src/xrpld/app/misc/detail/WorkPlain.h index 16bf424131..38dd0df9fa 100644 --- a/src/xrpld/app/misc/detail/WorkPlain.h +++ b/src/xrpld/app/misc/detail/WorkPlain.h @@ -37,7 +37,7 @@ public: std::string const& host, std::string const& path, std::string const& port, - boost::asio::io_service& ios, + boost::asio::io_context& ios, endpoint_type const& lastEndpoint, bool lastStatus, callback_type cb); @@ -60,7 +60,7 @@ WorkPlain::WorkPlain( std::string const& host, std::string const& path, std::string const& port, - boost::asio::io_service& ios, + boost::asio::io_context& ios, endpoint_type const& lastEndpoint, bool lastStatus, callback_type cb) diff --git a/src/xrpld/app/misc/detail/WorkSSL.cpp b/src/xrpld/app/misc/detail/WorkSSL.cpp index 0d6801ab84..a262a66ca7 100644 --- a/src/xrpld/app/misc/detail/WorkSSL.cpp +++ b/src/xrpld/app/misc/detail/WorkSSL.cpp @@ -26,7 +26,7 @@ WorkSSL::WorkSSL( std::string const& host, std::string const& path, std::string const& port, - boost::asio::io_service& ios, + boost::asio::io_context& ios, beast::Journal j, Config const& config, endpoint_type const& lastEndpoint, @@ -56,8 +56,12 @@ WorkSSL::onConnect(error_code const& ec) stream_.async_handshake( boost::asio::ssl::stream_base::client, - strand_.wrap(std::bind( - &WorkSSL::onHandshake, shared_from_this(), std::placeholders::_1))); + boost::asio::bind_executor( + strand_, + std::bind( + &WorkSSL::onHandshake, + shared_from_this(), + std::placeholders::_1))); } void diff --git a/src/xrpld/app/misc/detail/WorkSSL.h b/src/xrpld/app/misc/detail/WorkSSL.h index 6a310986e7..cadc3fd8fd 100644 --- a/src/xrpld/app/misc/detail/WorkSSL.h +++ b/src/xrpld/app/misc/detail/WorkSSL.h @@ -52,7 +52,7 @@ public: std::string const& host, std::string const& path, std::string const& port, - boost::asio::io_service& ios, + boost::asio::io_context& ios, beast::Journal j, Config const& config, endpoint_type const& lastEndpoint, diff --git a/src/xrpld/overlay/detail/ConnectAttempt.cpp b/src/xrpld/overlay/detail/ConnectAttempt.cpp index 61049579c5..397ac06ba6 100644 --- a/src/xrpld/overlay/detail/ConnectAttempt.cpp +++ b/src/xrpld/overlay/detail/ConnectAttempt.cpp @@ -28,7 +28,7 @@ namespace ripple { ConnectAttempt::ConnectAttempt( Application& app, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, endpoint_type const& remote_endpoint, Resource::Consumer usage, shared_context const& context, @@ -43,10 +43,10 @@ ConnectAttempt::ConnectAttempt( , journal_(sink_) , remote_endpoint_(remote_endpoint) , usage_(usage) - , strand_(io_service) - , timer_(io_service) + , strand_(boost::asio::make_strand(io_context)) + , timer_(io_context) , stream_ptr_(std::make_unique( - socket_type(std::forward(io_service)), + socket_type(std::forward(io_context)), *context)) , socket_(stream_ptr_->next_layer().socket()) , stream_(*stream_ptr_) @@ -66,8 +66,8 @@ void ConnectAttempt::stop() { if (!strand_.running_in_this_thread()) - return strand_.post( - std::bind(&ConnectAttempt::stop, shared_from_this())); + return boost::asio::post( + strand_, std::bind(&ConnectAttempt::stop, shared_from_this())); if (socket_.is_open()) { JLOG(journal_.debug()) << "Stop"; @@ -80,10 +80,12 @@ ConnectAttempt::run() { stream_.next_layer().async_connect( remote_endpoint_, - strand_.wrap(std::bind( - &ConnectAttempt::onConnect, - shared_from_this(), - std::placeholders::_1))); + boost::asio::bind_executor( + strand_, + std::bind( + &ConnectAttempt::onConnect, + shared_from_this(), + std::placeholders::_1))); } //------------------------------------------------------------------------------ @@ -96,9 +98,16 @@ ConnectAttempt::close() "ripple::ConnectAttempt::close : strand in this thread"); if (socket_.is_open()) { - error_code ec; - timer_.cancel(ec); - socket_.close(ec); + try + { + timer_.cancel(); + socket_.close(); + } + catch (boost::system::system_error const&) + { + // ignored + } + JLOG(journal_.debug()) << "Closed"; } } @@ -120,23 +129,35 @@ ConnectAttempt::fail(std::string const& name, error_code ec) void ConnectAttempt::setTimer() { - error_code ec; - timer_.expires_from_now(std::chrono::seconds(15), ec); - if (ec) + try { - JLOG(journal_.error()) << "setTimer: " << ec.message(); + timer_.expires_after(std::chrono::seconds(15)); + } + catch (boost::system::system_error const& e) + { + JLOG(journal_.error()) << "setTimer: " << e.code(); return; } - timer_.async_wait(strand_.wrap(std::bind( - &ConnectAttempt::onTimer, shared_from_this(), std::placeholders::_1))); + timer_.async_wait(boost::asio::bind_executor( + strand_, + std::bind( + &ConnectAttempt::onTimer, + shared_from_this(), + std::placeholders::_1))); } void ConnectAttempt::cancelTimer() { - error_code ec; - timer_.cancel(ec); + try + { + timer_.cancel(); + } + catch (boost::system::system_error const&) + { + // ignored + } } void @@ -175,10 +196,12 @@ ConnectAttempt::onConnect(error_code ec) stream_.set_verify_mode(boost::asio::ssl::verify_none); stream_.async_handshake( boost::asio::ssl::stream_base::client, - strand_.wrap(std::bind( - &ConnectAttempt::onHandshake, - shared_from_this(), - std::placeholders::_1))); + boost::asio::bind_executor( + strand_, + std::bind( + &ConnectAttempt::onHandshake, + shared_from_this(), + std::placeholders::_1))); } void @@ -223,10 +246,12 @@ ConnectAttempt::onHandshake(error_code ec) boost::beast::http::async_write( stream_, req_, - strand_.wrap(std::bind( - &ConnectAttempt::onWrite, - shared_from_this(), - std::placeholders::_1))); + boost::asio::bind_executor( + strand_, + std::bind( + &ConnectAttempt::onWrite, + shared_from_this(), + std::placeholders::_1))); } void @@ -243,10 +268,12 @@ ConnectAttempt::onWrite(error_code ec) stream_, read_buf_, response_, - strand_.wrap(std::bind( - &ConnectAttempt::onRead, - shared_from_this(), - std::placeholders::_1))); + boost::asio::bind_executor( + strand_, + std::bind( + &ConnectAttempt::onRead, + shared_from_this(), + std::placeholders::_1))); } void @@ -262,10 +289,12 @@ ConnectAttempt::onRead(error_code ec) { JLOG(journal_.info()) << "EOF"; setTimer(); - return stream_.async_shutdown(strand_.wrap(std::bind( - &ConnectAttempt::onShutdown, - shared_from_this(), - std::placeholders::_1))); + return stream_.async_shutdown(boost::asio::bind_executor( + strand_, + std::bind( + &ConnectAttempt::onShutdown, + shared_from_this(), + std::placeholders::_1))); } if (ec) return fail("onRead", ec); @@ -299,7 +328,7 @@ ConnectAttempt::processResponse() s.reserve(boost::asio::buffer_size(response_.body().data())); for (auto const buffer : response_.body().data()) s.append( - boost::asio::buffer_cast(buffer), + static_cast(buffer.data()), boost::asio::buffer_size(buffer)); auto const success = r.parse(s, json); if (success) diff --git a/src/xrpld/overlay/detail/ConnectAttempt.h b/src/xrpld/overlay/detail/ConnectAttempt.h index c3e07f956a..febbe88f45 100644 --- a/src/xrpld/overlay/detail/ConnectAttempt.h +++ b/src/xrpld/overlay/detail/ConnectAttempt.h @@ -50,7 +50,7 @@ private: beast::Journal const journal_; endpoint_type remote_endpoint_; Resource::Consumer usage_; - boost::asio::io_service::strand strand_; + boost::asio::strand strand_; boost::asio::basic_waitable_timer timer_; std::unique_ptr stream_ptr_; socket_type& socket_; @@ -63,7 +63,7 @@ private: public: ConnectAttempt( Application& app, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, endpoint_type const& remote_endpoint, Resource::Consumer usage, shared_context const& context, diff --git a/src/xrpld/overlay/detail/Handshake.cpp b/src/xrpld/overlay/detail/Handshake.cpp index e3617a1d98..5ce4954a5e 100644 --- a/src/xrpld/overlay/detail/Handshake.cpp +++ b/src/xrpld/overlay/detail/Handshake.cpp @@ -326,7 +326,7 @@ verifyHandshake( { boost::system::error_code ec; auto const local_ip = - boost::asio::ip::address::from_string(iter->value(), ec); + boost::asio::ip::make_address(std::string_view(iter->value()), ec); if (ec) throw std::runtime_error("Invalid Local-IP"); @@ -341,7 +341,7 @@ verifyHandshake( { boost::system::error_code ec; auto const remote_ip = - boost::asio::ip::address::from_string(iter->value(), ec); + boost::asio::ip::make_address(std::string_view(iter->value()), ec); if (ec) throw std::runtime_error("Invalid Remote-IP"); diff --git a/src/xrpld/overlay/detail/OverlayImpl.cpp b/src/xrpld/overlay/detail/OverlayImpl.cpp index 874f951f56..f2c683b69f 100644 --- a/src/xrpld/overlay/detail/OverlayImpl.cpp +++ b/src/xrpld/overlay/detail/OverlayImpl.cpp @@ -41,6 +41,7 @@ #include #include +#include namespace ripple { @@ -68,7 +69,7 @@ OverlayImpl::Child::~Child() //------------------------------------------------------------------------------ OverlayImpl::Timer::Timer(OverlayImpl& overlay) - : Child(overlay), timer_(overlay_.io_service_) + : Child(overlay), timer_(overlay_.io_context_) { } @@ -85,8 +86,10 @@ void OverlayImpl::Timer::async_wait() { timer_.expires_after(std::chrono::seconds(1)); - timer_.async_wait(overlay_.strand_.wrap(std::bind( - &Timer::on_timer, shared_from_this(), std::placeholders::_1))); + timer_.async_wait(boost::asio::bind_executor( + overlay_.strand_, + std::bind( + &Timer::on_timer, shared_from_this(), std::placeholders::_1))); } void @@ -121,19 +124,19 @@ OverlayImpl::OverlayImpl( ServerHandler& serverHandler, Resource::Manager& resourceManager, Resolver& resolver, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, BasicConfig const& config, beast::insight::Collector::ptr const& collector) : app_(app) - , io_service_(io_service) - , work_(std::in_place, std::ref(io_service_)) - , strand_(io_service_) + , io_context_(io_context) + , work_(std::in_place, boost::asio::make_work_guard(io_context_)) + , strand_(boost::asio::make_strand(io_context_)) , setup_(setup) , journal_(app_.journal("Overlay")) , serverHandler_(serverHandler) , m_resourceManager(resourceManager) , m_peerFinder(PeerFinder::make_Manager( - io_service, + io_context, stopwatch(), app_.journal("PeerFinder"), config, @@ -408,7 +411,7 @@ OverlayImpl::connect(beast::IP::Endpoint const& remote_endpoint) auto const p = std::make_shared( app_, - io_service_, + io_context_, beast::IPAddressConversion::to_asio_endpoint(remote_endpoint), usage, setup_.context, @@ -560,7 +563,7 @@ OverlayImpl::start() void OverlayImpl::stop() { - strand_.dispatch(std::bind(&OverlayImpl::stopChildren, this)); + boost::asio::dispatch(strand_, std::bind(&OverlayImpl::stopChildren, this)); { std::unique_lock lock(mutex_); cond_.wait(lock, [this] { return list_.empty(); }); @@ -1498,7 +1501,7 @@ setup_Overlay(BasicConfig const& config) if (!ip.empty()) { boost::system::error_code ec; - setup.public_ip = beast::IP::Address::from_string(ip, ec); + setup.public_ip = boost::asio::ip::make_address(ip, ec); if (ec || beast::IP::is_private(setup.public_ip)) Throw("Configured public IP is invalid"); } @@ -1592,7 +1595,7 @@ make_Overlay( ServerHandler& serverHandler, Resource::Manager& resourceManager, Resolver& resolver, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, BasicConfig const& config, beast::insight::Collector::ptr const& collector) { @@ -1602,7 +1605,7 @@ make_Overlay( serverHandler, resourceManager, resolver, - io_service, + io_context, config, collector); } diff --git a/src/xrpld/overlay/detail/OverlayImpl.h b/src/xrpld/overlay/detail/OverlayImpl.h index 86107fc591..b4ea3307ec 100644 --- a/src/xrpld/overlay/detail/OverlayImpl.h +++ b/src/xrpld/overlay/detail/OverlayImpl.h @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -100,9 +101,11 @@ private: }; Application& app_; - boost::asio::io_service& io_service_; - std::optional work_; - boost::asio::io_service::strand strand_; + boost::asio::io_context& io_context_; + std::optional> + work_; + boost::asio::strand strand_; mutable std::recursive_mutex mutex_; // VFALCO use std::mutex std::condition_variable_any cond_; std::weak_ptr timer_; @@ -143,7 +146,7 @@ public: ServerHandler& serverHandler, Resource::Manager& resourceManager, Resolver& resolver, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, BasicConfig const& config, beast::insight::Collector::ptr const& collector); diff --git a/src/xrpld/overlay/detail/PeerImp.cpp b/src/xrpld/overlay/detail/PeerImp.cpp index 23b4760488..69f25e1eb4 100644 --- a/src/xrpld/overlay/detail/PeerImp.cpp +++ b/src/xrpld/overlay/detail/PeerImp.cpp @@ -84,7 +84,7 @@ PeerImp::PeerImp( , stream_ptr_(std::move(stream_ptr)) , socket_(stream_ptr_->next_layer().socket()) , stream_(*stream_ptr_) - , strand_(socket_.get_executor()) + , strand_(boost::asio::make_strand(socket_.get_executor())) , timer_(waitable_timer{socket_.get_executor()}) , remote_address_(slot->remote_endpoint()) , overlay_(overlay) @@ -581,9 +581,16 @@ PeerImp::close() if (socket_.is_open()) { detaching_ = true; // DEPRECATED - error_code ec; - timer_.cancel(ec); - socket_.close(ec); + try + { + timer_.cancel(); + socket_.close(); + } + catch (boost::system::system_error const&) + { + // ignored + } + overlay_.incPeerDisconnect(); if (inbound_) { @@ -654,12 +661,13 @@ PeerImp::gracefulClose() void PeerImp::setTimer() { - error_code ec; - timer_.expires_from_now(peerTimerInterval, ec); - - if (ec) + try { - JLOG(journal_.error()) << "setTimer: " << ec.message(); + timer_.expires_after(peerTimerInterval); + } + catch (boost::system::system_error const& e) + { + JLOG(journal_.error()) << "setTimer: " << e.code(); return; } timer_.async_wait(bind_executor( @@ -672,8 +680,14 @@ PeerImp::setTimer() void PeerImp::cancelTimer() { - error_code ec; - timer_.cancel(ec); + try + { + timer_.cancel(); + } + catch (boost::system::system_error const&) + { + // ignored + } } //------------------------------------------------------------------------------ diff --git a/src/xrpld/overlay/detail/PeerImp.h b/src/xrpld/overlay/detail/PeerImp.h index 5aa49fd152..3d9a0c0b1e 100644 --- a/src/xrpld/overlay/detail/PeerImp.h +++ b/src/xrpld/overlay/detail/PeerImp.h @@ -669,7 +669,7 @@ PeerImp::PeerImp( , stream_ptr_(std::move(stream_ptr)) , socket_(stream_ptr_->next_layer().socket()) , stream_(*stream_ptr_) - , strand_(socket_.get_executor()) + , strand_(boost::asio::make_strand(socket_.get_executor())) , timer_(waitable_timer{socket_.get_executor()}) , remote_address_(slot->remote_endpoint()) , overlay_(overlay) diff --git a/src/xrpld/overlay/detail/PeerSet.cpp b/src/xrpld/overlay/detail/PeerSet.cpp index 611728839c..74290f50d3 100644 --- a/src/xrpld/overlay/detail/PeerSet.cpp +++ b/src/xrpld/overlay/detail/PeerSet.cpp @@ -46,7 +46,7 @@ public: getPeerIds() const override; private: - // Used in this class for access to boost::asio::io_service and + // Used in this class for access to boost::asio::io_context and // ripple::Overlay. Application& app_; beast::Journal journal_; diff --git a/src/xrpld/overlay/detail/ZeroCopyStream.h b/src/xrpld/overlay/detail/ZeroCopyStream.h index 87a5e10bc2..23e26c5351 100644 --- a/src/xrpld/overlay/detail/ZeroCopyStream.h +++ b/src/xrpld/overlay/detail/ZeroCopyStream.h @@ -78,7 +78,7 @@ template bool ZeroCopyInputStream::Next(void const** data, int* size) { - *data = boost::asio::buffer_cast(pos_); + *data = pos_.data(); *size = boost::asio::buffer_size(pos_); if (first_ == last_) return false; @@ -195,7 +195,7 @@ ZeroCopyOutputStream::Next(void** data, int* size) pos_ = buffers_.begin(); } - *data = boost::asio::buffer_cast(*pos_); + *data = *pos_.data(); *size = boost::asio::buffer_size(*pos_); commit_ = *size; ++pos_; diff --git a/src/xrpld/overlay/make_Overlay.h b/src/xrpld/overlay/make_Overlay.h index 3476026562..142c922551 100644 --- a/src/xrpld/overlay/make_Overlay.h +++ b/src/xrpld/overlay/make_Overlay.h @@ -25,7 +25,7 @@ #include -#include +#include namespace ripple { @@ -40,7 +40,7 @@ make_Overlay( ServerHandler& serverHandler, Resource::Manager& resourceManager, Resolver& resolver, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, BasicConfig const& config, beast::insight::Collector::ptr const& collector); diff --git a/src/xrpld/peerfinder/detail/Checker.h b/src/xrpld/peerfinder/detail/Checker.h index e7983471a5..c5221fcc13 100644 --- a/src/xrpld/peerfinder/detail/Checker.h +++ b/src/xrpld/peerfinder/detail/Checker.h @@ -22,7 +22,7 @@ #include -#include +#include #include #include @@ -65,7 +65,7 @@ private: async_op( Checker& owner, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, Handler&& handler); ~async_op(); @@ -85,17 +85,17 @@ private: std::mutex mutex_; std::condition_variable cond_; - boost::asio::io_service& io_service_; + boost::asio::io_context& io_context_; list_type list_; bool stop_ = false; public: - explicit Checker(boost::asio::io_service& io_service); + explicit Checker(boost::asio::io_context& io_context); /** Destroy the service. Any pending I/O operations will be canceled. This call blocks until all pending operations complete (either with success or with - operation_aborted) and the associated thread and io_service have + operation_aborted) and the associated thread and io_context have no more work remaining. */ ~Checker(); @@ -132,10 +132,10 @@ template template Checker::async_op::async_op( Checker& owner, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, Handler&& handler) : checker_(owner) - , socket_(io_service) + , socket_(io_context) , handler_(std::forward(handler)) { } @@ -167,8 +167,8 @@ Checker::async_op::operator()(error_code const& ec) //------------------------------------------------------------------------------ template -Checker::Checker(boost::asio::io_service& io_service) - : io_service_(io_service) +Checker::Checker(boost::asio::io_context& io_context) + : io_context_(io_context) { } @@ -208,7 +208,7 @@ Checker::async_connect( Handler&& handler) { auto const op = std::make_shared>( - *this, io_service_, std::forward(handler)); + *this, io_context_, std::forward(handler)); { std::lock_guard lock(mutex_); list_.push_back(*op); diff --git a/src/xrpld/peerfinder/detail/PeerfinderManager.cpp b/src/xrpld/peerfinder/detail/PeerfinderManager.cpp index 86093fa166..205df67fa6 100644 --- a/src/xrpld/peerfinder/detail/PeerfinderManager.cpp +++ b/src/xrpld/peerfinder/detail/PeerfinderManager.cpp @@ -23,7 +23,8 @@ #include #include -#include +#include +#include #include #include @@ -34,8 +35,10 @@ namespace PeerFinder { class ManagerImp : public Manager { public: - boost::asio::io_service& io_service_; - std::optional work_; + boost::asio::io_context& io_context_; + std::optional> + work_; clock_type& m_clock; beast::Journal m_journal; StoreSqdb m_store; @@ -46,18 +49,18 @@ public: //-------------------------------------------------------------------------- ManagerImp( - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, clock_type& clock, beast::Journal journal, BasicConfig const& config, beast::insight::Collector::ptr const& collector) : Manager() - , io_service_(io_service) - , work_(std::in_place, std::ref(io_service_)) + , io_context_(io_context) + , work_(std::in_place, boost::asio::make_work_guard(io_context_)) , m_clock(clock) , m_journal(journal) , m_store(journal) - , checker_(io_service_) + , checker_(io_context_) , m_logic(clock, m_store, checker_, journal) , m_config(config) , m_stats(std::bind(&ManagerImp::collect_metrics, this), collector) @@ -271,14 +274,14 @@ Manager::Manager() noexcept : beast::PropertyStream::Source("peerfinder") std::unique_ptr make_Manager( - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, clock_type& clock, beast::Journal journal, BasicConfig const& config, beast::insight::Collector::ptr const& collector) { return std::make_unique( - io_service, clock, journal, config, collector); + io_context, clock, journal, config, collector); } } // namespace PeerFinder diff --git a/src/xrpld/peerfinder/make_Manager.h b/src/xrpld/peerfinder/make_Manager.h index fba95e8f22..e55964f4a7 100644 --- a/src/xrpld/peerfinder/make_Manager.h +++ b/src/xrpld/peerfinder/make_Manager.h @@ -22,7 +22,7 @@ #include -#include +#include #include @@ -32,7 +32,7 @@ namespace PeerFinder { /** Create a new Manager. */ std::unique_ptr make_Manager( - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, clock_type& clock, beast::Journal journal, BasicConfig const& config, diff --git a/src/xrpld/rpc/RPCCall.h b/src/xrpld/rpc/RPCCall.h index 4c6d25ca57..9e160b8fbd 100644 --- a/src/xrpld/rpc/RPCCall.h +++ b/src/xrpld/rpc/RPCCall.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include @@ -51,7 +51,7 @@ fromCommandLine( void fromNetwork( - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, std::string const& strIp, std::uint16_t const iPort, std::string const& strUsername, diff --git a/src/xrpld/rpc/RPCSub.h b/src/xrpld/rpc/RPCSub.h index 0f106be018..2fd1be0b20 100644 --- a/src/xrpld/rpc/RPCSub.h +++ b/src/xrpld/rpc/RPCSub.h @@ -23,7 +23,7 @@ #include #include -#include +#include namespace ripple { @@ -40,11 +40,11 @@ protected: explicit RPCSub(InfoSub::Source& source); }; -// VFALCO Why is the io_service needed? +// VFALCO Why is the io_context needed? std::shared_ptr make_RPCSub( InfoSub::Source& source, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, JobQueue& jobQueue, std::string const& strUrl, std::string const& strUsername, diff --git a/src/xrpld/rpc/ServerHandler.h b/src/xrpld/rpc/ServerHandler.h index 5f72673313..d0ebdcd67d 100644 --- a/src/xrpld/rpc/ServerHandler.h +++ b/src/xrpld/rpc/ServerHandler.h @@ -111,7 +111,7 @@ private: friend std::unique_ptr make_ServerHandler( Application& app, - boost::asio::io_service&, + boost::asio::io_context&, JobQueue&, NetworkOPs&, Resource::Manager&, @@ -122,7 +122,7 @@ public: ServerHandler( ServerHandlerCreator const&, Application& app, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, JobQueue& jobQueue, NetworkOPs& networkOPs, Resource::Manager& resourceManager, @@ -223,7 +223,7 @@ setup_ServerHandler(Config const& c, std::ostream&& log); std::unique_ptr make_ServerHandler( Application& app, - boost::asio::io_service&, + boost::asio::io_context&, JobQueue&, NetworkOPs&, Resource::Manager&, diff --git a/src/xrpld/rpc/detail/RPCCall.cpp b/src/xrpld/rpc/detail/RPCCall.cpp index aa8c80fff7..57432d920f 100644 --- a/src/xrpld/rpc/detail/RPCCall.cpp +++ b/src/xrpld/rpc/detail/RPCCall.cpp @@ -1543,7 +1543,7 @@ rpcClient( } { - boost::asio::io_service isService; + boost::asio::io_context isService; RPCCall::fromNetwork( isService, setup.client.ip, @@ -1647,7 +1647,7 @@ fromCommandLine( void fromNetwork( - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, std::string const& strIp, std::uint16_t const iPort, std::string const& strUsername, @@ -1685,7 +1685,7 @@ fromNetwork( HTTPClient::request( bSSL, - io_service, + io_context, strIp, iPort, std::bind( diff --git a/src/xrpld/rpc/detail/RPCSub.cpp b/src/xrpld/rpc/detail/RPCSub.cpp index 966ad6df4b..6619b5ddc5 100644 --- a/src/xrpld/rpc/detail/RPCSub.cpp +++ b/src/xrpld/rpc/detail/RPCSub.cpp @@ -35,14 +35,14 @@ class RPCSubImp : public RPCSub public: RPCSubImp( InfoSub::Source& source, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, JobQueue& jobQueue, std::string const& strUrl, std::string const& strUsername, std::string const& strPassword, Logs& logs) : RPCSub(source) - , m_io_service(io_service) + , m_io_context(io_context) , m_jobQueue(jobQueue) , mUrl(strUrl) , mSSL(false) @@ -155,7 +155,7 @@ private: JLOG(j_.info()) << "RPCCall::fromNetwork: " << mIp; RPCCall::fromNetwork( - m_io_service, + m_io_context, mIp, mPort, mUsername, @@ -177,7 +177,7 @@ private: } private: - boost::asio::io_service& m_io_service; + boost::asio::io_context& m_io_context; JobQueue& m_jobQueue; std::string mUrl; @@ -207,7 +207,7 @@ RPCSub::RPCSub(InfoSub::Source& source) : InfoSub(source, Consumer()) std::shared_ptr make_RPCSub( InfoSub::Source& source, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, JobQueue& jobQueue, std::string const& strUrl, std::string const& strUsername, @@ -216,7 +216,7 @@ make_RPCSub( { return std::make_shared( std::ref(source), - std::ref(io_service), + std::ref(io_context), std::ref(jobQueue), strUrl, strUsername, diff --git a/src/xrpld/rpc/detail/ServerHandler.cpp b/src/xrpld/rpc/detail/ServerHandler.cpp index 0c84e59413..f5f5e53238 100644 --- a/src/xrpld/rpc/detail/ServerHandler.cpp +++ b/src/xrpld/rpc/detail/ServerHandler.cpp @@ -104,7 +104,7 @@ authorized(Port const& port, std::map const& h) ServerHandler::ServerHandler( ServerHandlerCreator const&, Application& app, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, JobQueue& jobQueue, NetworkOPs& networkOPs, Resource::Manager& resourceManager, @@ -113,7 +113,7 @@ ServerHandler::ServerHandler( , m_resourceManager(resourceManager) , m_journal(app_.journal("Server")) , m_networkOPs(networkOPs) - , m_server(make_Server(*this, io_service, app_.journal("Server"))) + , m_server(make_Server(*this, io_context, app_.journal("Server"))) , m_jobQueue(jobQueue) { auto const& group(cm.group("rpc")); @@ -282,14 +282,13 @@ template static std::string buffers_to_string(ConstBufferSequence const& bs) { - using boost::asio::buffer_cast; using boost::asio::buffer_size; std::string s; s.reserve(buffer_size(bs)); // Use auto&& so the right thing happens whether bs returns a copy or // a reference for (auto&& b : bs) - s.append(buffer_cast(b), buffer_size(b)); + s.append(static_cast(b.data()), buffer_size(b)); return s; } @@ -1267,7 +1266,7 @@ setup_ServerHandler(Config const& config, std::ostream&& log) std::unique_ptr make_ServerHandler( Application& app, - boost::asio::io_service& io_service, + boost::asio::io_context& io_context, JobQueue& jobQueue, NetworkOPs& networkOPs, Resource::Manager& resourceManager, @@ -1276,7 +1275,7 @@ make_ServerHandler( return std::make_unique( ServerHandler::ServerHandlerCreator(), app, - io_service, + io_context, jobQueue, networkOPs, resourceManager, diff --git a/src/xrpld/rpc/handlers/Subscribe.cpp b/src/xrpld/rpc/handlers/Subscribe.cpp index c089f0255d..1696754e9c 100644 --- a/src/xrpld/rpc/handlers/Subscribe.cpp +++ b/src/xrpld/rpc/handlers/Subscribe.cpp @@ -76,7 +76,7 @@ doSubscribe(RPC::JsonContext& context) { auto rspSub = make_RPCSub( context.app.getOPs(), - context.app.getIOService(), + context.app.getIOContext(), context.app.getJobQueue(), strUrl, strUsername,