libs/http/src/application.cpp

18.6% Lines (11/59) 28.6% Functions (2/7) 13.8% Branches (4/29)
libs/http/src/application.cpp
Line Branch Hits Source Code
1 //
2 // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.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/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 1 application::
35 ~application()
36 {
37 {
38 1 std::lock_guard<std::mutex> lock(impl_->m);
39
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if( impl_->st != state::stopped &&
40
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 impl_->st != state::none)
41 {
42 // stop() hasn't returned yet
43 ✗ detail::throw_invalid_argument();
44 }
45 1 }
46
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 delete impl_;
47 1 }
48
49 1 application::
50 1 application()
51
1/1
✓ Branch 2 taken 1 time.
1 : impl_(new impl)
52 {
53 1 }
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