src/application.cpp

18.6% Lines (11/0/59) 28.6% List of functions (2/0/7)
application.cpp
f(x) Functions (7)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2022 Vinnie Falco ([email protected])
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/http
8 //
9
10 #include <boost/http/application.hpp>
11 #include <boost/http/detail/except.hpp>
12 #include <boost/assert.hpp>
13 #include <mutex>
14 #include <vector>
15
16 namespace boost {
17 namespace http {
18
19 enum application::state : char
20 {
21 none,
22 starting,
23 running,
24 stopping,
25 stopped
26 };
27
28 struct application::impl
29 {
30 std::mutex m;
31 state st = state::none;
32 };
33
34 1x application::
35 ~application()
36 {
37 {
38 1x std::lock_guard<std::mutex> lock(impl_->m);
39 1x if( impl_->st != state::stopped &&
40 1x impl_->st != state::none)
41 {
42 // stop() hasn't returned yet
43 ✗ detail::throw_invalid_argument();
44 }
45 1x }
46 1x delete impl_;
47 1x }
48
49 1x application::
50 1x application()
51 1x : impl_(new impl)
52 {
53 1x }
54
55 void
56 ✗ application::
57 start()
58 {
59 struct action
60 {
61 ✗ action(application& self)
62 ✗ : self_(self)
63 {
64 std::lock_guard<
65 ✗ std::mutex> lock(self_.impl_->m);
66 // can't call twice
67 ✗ if(self_.impl_->st != state::none)
68 ✗ detail::throw_invalid_argument();
69 ✗ self_.impl_->st = state::starting;
70 ✗ }
71
72 ✗ ~action()
73 ✗ {
74 ✗ if(n_ == 0)
75 ✗ return;
76 {
77 std::lock_guard<
78 ✗ std::mutex> lock(self_.impl_->m);
79 ✗ BOOST_ASSERT(
80 self_.impl_->st == state::stopping);
81 ✗ self_.impl_->st = state::stopping;
82 ✗ }
83 // stop what we started
84 ✗ auto v = self_.get_elements();
85 ✗ while(n_-- > 0)
86 ✗ v[n_].stop();
87 {
88 std::lock_guard<std::mutex> lock(
89 ✗ self_.impl_->m);
90 ✗ self_.impl_->st = state::stopped;
91 ✗ }
92 ✗ }
93
94 ✗ void apply()
95 {
96 ✗ auto v = self_.get_elements();
97 ✗ while(n_ < v.size())
98 {
99 ✗ v[n_].start();
100 ✗ ++n_;
101 }
102 ✗ n_ = 0;
103 std::lock_guard<
104 ✗ std::mutex> lock(self_.impl_->m);
105 ✗ self_.impl_->st = state::running;
106 ✗ }
107
108 private:
109 application& self_;
110 std::size_t n_ = 0;
111 };
112
113 ✗ action(*this).apply();
114 ✗ }
115
116 void
117 ✗ application::
118 stop()
119 {
120 {
121 ✗ std::lock_guard<std::mutex> lock(impl_->m);
122 ✗ if(impl_->st != state::running)
123 ✗ detail::throw_invalid_argument();
124 ✗ impl_->st = state::stopping;
125 ✗ }
126
127 ✗ auto v = get_elements();
128 ✗ for(std::size_t i = v.size(); i--;)
129 ✗ v[i].stop();
130
131 {
132 ✗ std::lock_guard<std::mutex> lock(impl_->m);
133 ✗ impl_->st = state::stopped;
134 ✗ }
135 ✗ }
136
137 } // http
138 } // boost
139