service.h
Go to the documentation of this file.
1 /*
2  * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  * http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 #pragma once
17 
18 #include <atomic>
19 #include <condition_variable>
20 #include <map>
21 #include <mutex>
22 #include <string>
23 #include <thread>
24 #include <typeinfo>
25 
27 
29  CREATED, // created and ready to start
30  STARTED, // started and ready to use
31  SHUTDOWN, // clean shutdown, possibly restartable
32 };
33 
37 static std::map<ServiceState, std::string> SERVICE_STATE_NAME_MAP = {{CREATED, "CREATED"}, {STARTED, "STARTED"},
38  {SHUTDOWN,"SHUTDOWN"}};
39 
43 class Service {
44 public:
45 
47  virtual ~Service() = default;
48 
64  virtual bool start() {
66  return true;
67  }
68 
83  virtual bool shutdown() {
85  return true;
86  }
87 
92  virtual std::string getStatusString() {
93  // a more descriptive name (tag supplied on construction) would be ideal
94  return typeid(this).name() + std::string(", state=") + SERVICE_STATE_NAME_MAP[getState()];
95  }
96 
102  return state_.getValue();
103  }
104 
105 protected:
111  void setState(ServiceState new_state) {
112  state_.setValue(new_state);
113  }
114 
115 private:
120 };
121 
127 // consider extending the waiter interface
128 class RunnableService : public Service
129 {
130 public:
132  should_run_.store(false);
133  }
134  ~RunnableService() override = default;
135 
140  bool start() override {
141  bool started = startWorkerThread();
142  started &= Service::start();
143  return started;
144  }
145 
150  bool shutdown() override {
151  bool is_shutdown = Service::shutdown();
152  is_shutdown &= stopWorkerThread();
153  return is_shutdown;
154  }
155 
160  virtual bool isRunning() {
161  return Service::getState() == ServiceState::STARTED && should_run_.load();
162  }
163 
168  std::unique_lock <std::mutex> lck(this->mtx_);
169  if (runnable_thread_.joinable()) {
170  cv_.wait(lck); // todo guard against spurious wakeup, or could do while
171  }
172  }
173 
178  void waitForShutdown(std::chrono::milliseconds millis) {
179  std::unique_lock <std::mutex> lck(this->mtx_);
180  if (runnable_thread_.joinable()) {
181  cv_.wait_for(lck, millis); // todo guard against spurious wakeup
182  }
183  }
184 
188  void join() {
189  if (runnable_thread_.joinable()) {
190  runnable_thread_.join();
191  }
192  }
193 
198  std::string getStatusString() override {
199  return Service::getStatusString() + std::string(", isRunning=") + (isRunning()
200  ? std::string("True") : std::string("False"));
201  }
202 
203 protected:
204 
209  virtual bool startWorkerThread() {
210  if(!runnable_thread_.joinable()) {
211  should_run_.store(true);
212  runnable_thread_ = std::thread(&RunnableService::run, this);
213  return true;
214  }
215  return false;
216  }
217 
222  virtual bool stopWorkerThread() {
223  if(should_run_.load()) {
224  should_run_.store(false);
225  return true;
226  }
227  return false;
228  }
229 
233  virtual void run() {
234  while(should_run_.load() && ServiceState::STARTED == Service::getState()) {
235  work();
236  }
237  // done, notify anyone waiting
238  std::unique_lock <std::mutex> lck(this->mtx_);
239  this->cv_.notify_all();
240  }
241 
245  virtual void work() = 0;
246 
247 private:
248  std::thread runnable_thread_;
249  std::atomic<bool> should_run_{};
250  std::condition_variable cv_;
251  mutable std::mutex mtx_;
252 };
virtual bool isRunning()
Definition: service.h:160
virtual ~Service()=default
std::condition_variable cv_
Definition: service.h:250
ServiceState
Definition: service.h:28
std::string getStatusString() override
Definition: service.h:198
void waitForShutdown()
Definition: service.h:167
virtual bool startWorkerThread()
Definition: service.h:209
void join()
Definition: service.h:188
void waitForShutdown(std::chrono::milliseconds millis)
Definition: service.h:178
void setState(ServiceState new_state)
Definition: service.h:111
virtual void setValue(const T &v)
bool shutdown() override
Definition: service.h:150
std::mutex mtx_
Definition: service.h:251
virtual bool shutdown()
Definition: service.h:83
virtual void run()
Definition: service.h:233
virtual T getValue()
ObservableObject< ServiceState > state_
Definition: service.h:119
virtual bool stopWorkerThread()
Definition: service.h:222
virtual std::string getStatusString()
Definition: service.h:92
Service()
Definition: service.h:46
std::thread runnable_thread_
Definition: service.h:248
ServiceState getState()
Definition: service.h:101
virtual bool start()
Definition: service.h:64
bool start() override
Definition: service.h:140
static std::map< ServiceState, std::string > SERVICE_STATE_NAME_MAP
Definition: service.h:37


dataflow_lite
Author(s): AWS RoboMaker
autogenerated on Fri May 7 2021 02:18:22