| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // | ||
| 2 | // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com) | ||
| 3 | // | ||
| 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
| 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
| 6 | // | ||
| 7 | // Official repository: https://github.com/cppalliance/beast2 | ||
| 8 | // | ||
| 9 | |||
| 10 | #include <boost/beast2/asio_io_context.hpp> | ||
| 11 | #include <boost/beast2/application.hpp> | ||
| 12 | #include <boost/beast2/server/call_mf.hpp> | ||
| 13 | #include <boost/asio/executor_work_guard.hpp> | ||
| 14 | #include <boost/asio/signal_set.hpp> | ||
| 15 | #include <thread> | ||
| 16 | #include <vector> | ||
| 17 | |||
| 18 | namespace boost { | ||
| 19 | namespace beast2 { | ||
| 20 | |||
| 21 | namespace { | ||
| 22 | |||
| 23 | /** Asio's io_context as an application part | ||
| 24 | */ | ||
| 25 | class asio_io_context_impl | ||
| 26 | : public asio_io_context | ||
| 27 | { | ||
| 28 | public: | ||
| 29 | using key_type = asio_io_context; | ||
| 30 | |||
| 31 | ✗ | ~asio_io_context_impl() | |
| 32 | ✗ | { | |
| 33 | ✗ | } | |
| 34 | |||
| 35 | ✗ | asio_io_context_impl( | |
| 36 | application& app, | ||
| 37 | int num_threads) | ||
| 38 | ✗ | : app_(app) | |
| 39 | ✗ | , num_threads_(num_threads) | |
| 40 | ✗ | , ioc_(num_threads) | |
| 41 | ✗ | , sigs_(ioc_.get_executor(), SIGINT, SIGTERM) | |
| 42 | ✗ | , work_(ioc_.get_executor()) | |
| 43 | { | ||
| 44 | ✗ | if(num_threads > 1) | |
| 45 | ✗ | vt_.resize(num_threads - 1); | |
| 46 | ✗ | } | |
| 47 | |||
| 48 | executor_type | ||
| 49 | ✗ | get_executor() noexcept override | |
| 50 | { | ||
| 51 | ✗ | return ioc_.get_executor(); | |
| 52 | } | ||
| 53 | |||
| 54 | std::size_t | ||
| 55 | ✗ | concurrency() const noexcept override | |
| 56 | { | ||
| 57 | ✗ | return num_threads_; | |
| 58 | } | ||
| 59 | |||
| 60 | ✗ | void attach() override | |
| 61 | { | ||
| 62 | // VFALCO exception catcher? | ||
| 63 | ✗ | ioc_.run(); | |
| 64 | |||
| 65 | // VFALCO can't figure out where to put this | ||
| 66 | ✗ | for(auto& t : vt_) | |
| 67 | ✗ | t.join(); | |
| 68 | ✗ | } | |
| 69 | |||
| 70 | ✗ | void start() override | |
| 71 | { | ||
| 72 | // Capture SIGINT and SIGTERM to | ||
| 73 | // perform a clean shutdown | ||
| 74 | ✗ | sigs_.async_wait(call_mf( | |
| 75 | &asio_io_context_impl::on_signal, this)); | ||
| 76 | |||
| 77 | ✗ | for(auto& t : vt_) | |
| 78 | { | ||
| 79 | ✗ | t = std::thread( | |
| 80 | ✗ | [&] | |
| 81 | { | ||
| 82 | // VFALCO exception catcher? | ||
| 83 | ✗ | ioc_.run(); | |
| 84 | ✗ | }); | |
| 85 | } | ||
| 86 | ✗ | } | |
| 87 | |||
| 88 | ✗ | void stop() override | |
| 89 | { | ||
| 90 | ✗ | system::error_code ec; | |
| 91 | ✗ | sigs_.cancel(ec); // VFALCO should we use the 0-arg overload? | |
| 92 | ✗ | work_.reset(); | |
| 93 | ✗ | } | |
| 94 | |||
| 95 | private: | ||
| 96 | void | ||
| 97 | ✗ | on_signal( | |
| 98 | system::error_code const& ec, int) | ||
| 99 | { | ||
| 100 | ✗ | if(ec == asio::error::operation_aborted) | |
| 101 | ✗ | return; | |
| 102 | ✗ | app_.stop(); | |
| 103 | } | ||
| 104 | |||
| 105 | application& app_; | ||
| 106 | int num_threads_; | ||
| 107 | asio::io_context ioc_; | ||
| 108 | asio::signal_set sigs_; | ||
| 109 | asio::executor_work_guard< | ||
| 110 | asio::io_context::executor_type> work_; | ||
| 111 | std::vector<std::thread> vt_; | ||
| 112 | }; | ||
| 113 | |||
| 114 | } // (anon) | ||
| 115 | |||
| 116 | //------------------------------------------------ | ||
| 117 | |||
| 118 | ✗ | asio_io_context:: | |
| 119 | ~asio_io_context() = default; | ||
| 120 | |||
| 121 | auto | ||
| 122 | ✗ | install_single_threaded_asio_io_context( | |
| 123 | application& app) -> | ||
| 124 | asio_io_context& | ||
| 125 | { | ||
| 126 | return app.emplace< | ||
| 127 | ✗ | asio_io_context_impl>(app, 1); | |
| 128 | } | ||
| 129 | |||
| 130 | auto | ||
| 131 | ✗ | install_multi_threaded_asio_io_context( | |
| 132 | application& app, | ||
| 133 | int num_threads) -> | ||
| 134 | asio_io_context& | ||
| 135 | { | ||
| 136 | return app.emplace< | ||
| 137 | ✗ | asio_io_context_impl>(app, num_threads); | |
| 138 | } | ||
| 139 | |||
| 140 | } // beast2 | ||
| 141 | } // boost | ||
| 142 |