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