Line data Source code
1 : //
2 : // Copyright (c) 2022 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/application.hpp>
11 : #include <boost/beast2/logger.hpp>
12 : #include <boost/beast2/detail/except.hpp>
13 : #include <mutex>
14 : #include <vector>
15 :
16 : namespace boost {
17 : namespace beast2 {
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 : rts::context services;
33 : };
34 :
35 0 : application::
36 : ~application()
37 : {
38 : {
39 0 : std::lock_guard<std::mutex> lock(impl_->m);
40 0 : if( impl_->st != state::stopped &&
41 0 : impl_->st != state::none)
42 : {
43 : // stop() hasn't returned yet
44 0 : detail::throw_invalid_argument();
45 : }
46 0 : }
47 0 : delete impl_;
48 0 : }
49 :
50 0 : application::
51 0 : application()
52 0 : : impl_(new impl)
53 : {
54 0 : }
55 :
56 : void
57 0 : application::
58 : start()
59 : {
60 : {
61 0 : std::lock_guard<std::mutex> lock(impl_->m);
62 0 : if(impl_->st != state::none)
63 : {
64 : // can't call twice
65 0 : detail::throw_invalid_argument();
66 : }
67 0 : impl_->st = state::starting;
68 0 : }
69 0 : auto v = get_elements();
70 0 : for(std::size_t i = 0; i < v.size(); ++i)
71 : {
72 : try
73 : {
74 0 : v[i].start();
75 : }
76 0 : catch(std::exception const&)
77 : {
78 : {
79 0 : std::lock_guard<std::mutex> lock(impl_->m);
80 0 : impl_->st = state::stopping;
81 0 : }
82 : do
83 : {
84 0 : v[i].stop();
85 : }
86 0 : while(i-- != 0);
87 : {
88 0 : std::lock_guard<std::mutex> lock(impl_->m);
89 0 : impl_->st = state::stopped;
90 0 : }
91 0 : throw;
92 0 : }
93 : }
94 : {
95 0 : std::lock_guard<std::mutex> lock(impl_->m);
96 0 : impl_->st = state::running;
97 0 : }
98 0 : }
99 :
100 : void
101 0 : application::
102 : stop()
103 : {
104 : {
105 0 : std::lock_guard<std::mutex> lock(impl_->m);
106 0 : if(impl_->st != state::running)
107 0 : detail::throw_invalid_argument();
108 0 : impl_->st = state::stopping;
109 0 : }
110 :
111 0 : auto v = get_elements();
112 0 : for(std::size_t i = v.size(); i--;)
113 0 : v[i].stop();
114 :
115 : {
116 0 : std::lock_guard<std::mutex> lock(impl_->m);
117 0 : impl_->st = state::stopped;
118 0 : }
119 0 : }
120 :
121 : rts::context&
122 0 : application::
123 : services() noexcept
124 : {
125 0 : return impl_->services;
126 : }
127 :
128 : } // beast2
129 : } // boost
|