GCC Code Coverage Report


Directory: ./
File: libs/beast2/src/asio_io_context.cpp
Date: 2026-01-04 15:38:14
Exec Total Coverage
Lines: 0 43 0.0%
Functions: 0 12 0.0%
Branches: 0 18 0.0%

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/server/call_mf.hpp>
12 #include <boost/capy/application.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 capy::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 capy::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 capy::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 capy::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