rippled
Stoppable.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012-2015 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef RIPPLE_CORE_STOPPABLE_H_INCLUDED
21 #define RIPPLE_CORE_STOPPABLE_H_INCLUDED
22 
23 #include <ripple/beast/core/LockFreeStack.h>
24 #include <ripple/beast/utility/Journal.h>
25 #include <ripple/core/ClosureCounter.h>
26 #include <ripple/core/Job.h>
27 #include <atomic>
28 #include <chrono>
29 #include <condition_variable>
30 #include <mutex>
31 
32 namespace ripple {
33 
34 // Give a reasonable name for the JobCounter
36 
37 class RootStoppable;
38 
202 {
203 protected:
204  Stoppable(std::string name, RootStoppable& root);
205 
206 public:
208  Stoppable(std::string name, Stoppable& parent);
209 
211  virtual ~Stoppable();
212 
215  {
216  return m_root;
217  }
218 
225  void
226  setParent(Stoppable& parent);
227 
229  bool
230  isStopping() const;
231 
233  bool
234  isStopped() const;
235 
237  bool
238  areChildrenStopped() const;
239 
240  /* JobQueue uses this method for Job counting. */
241  inline JobCounter&
242  jobCounter();
243 
248  bool
249  alertable_sleep_until(std::chrono::system_clock::time_point const& t);
250 
251 protected:
253  void
254  stopped();
255 
256 private:
264  virtual void
265  onPrepare();
266 
268  virtual void
269  onStart();
270 
292  virtual void
293  onStop();
294 
313  virtual void
315 
316  friend class RootStoppable;
317 
318  struct Child;
320 
321  struct Child : Children::Node
322  {
323  Child(Stoppable* stoppable_) : stoppable(stoppable_)
324  {
325  }
326 
328  };
329 
330  void
332  void
333  startRecursive();
334  void
336  void
338 
342  // TODO [C++20]: Use std::atomic_flag instead.
348  bool m_is_stopping = false;
349  bool hasParent_{false};
350 };
351 
352 //------------------------------------------------------------------------------
353 
354 class RootStoppable : public Stoppable
355 {
356 public:
357  explicit RootStoppable(std::string name);
358 
359  virtual ~RootStoppable();
360 
361  bool
362  isStopping() const;
363 
371  void
372  start();
373 
382  void
383  stop(beast::Journal j);
384 
386  bool
387  started() const
388  {
389  return startExited_;
390  }
391 
392  /* JobQueue uses this method for Job counting. */
393  JobCounter&
395  {
396  return jobCounter_;
397  }
398 
403  bool
404  alertable_sleep_until(std::chrono::system_clock::time_point const& t);
405 
406 private:
407  // TODO [C++20]: Use std::atomic_flag instead.
414 };
417 //------------------------------------------------------------------------------
418 
419 JobCounter&
421 {
422  return m_root.jobCounter();
423 }
424 
425 //------------------------------------------------------------------------------
426 
427 inline bool
429  std::chrono::system_clock::time_point const& t)
430 {
432  if (stopEntered_)
433  return true;
434  // TODO [C++20]: When `stopEntered_` is changed to a `std::atomic_flag`,
435  // this call to `load` needs to change to a call to `test`.
436  return c_.wait_until(lock, t, [this] { return stopEntered_.load(); });
437 }
438 
439 inline bool
440 Stoppable::alertable_sleep_until(std::chrono::system_clock::time_point const& t)
441 {
442  return m_root.alertable_sleep_until(t);
443 }
444 
445 } // namespace ripple
446 
447 #endif
ripple::Stoppable::~Stoppable
virtual ~Stoppable()
Destroy the Stoppable.
Definition: Stoppable.cpp:38
ripple::RootStoppable::~RootStoppable
virtual ~RootStoppable()
Definition: Stoppable.cpp:168
ripple::Stoppable::prepareRecursive
void prepareRecursive()
Definition: Stoppable.cpp:103
ripple::Stoppable::Child::Child
Child(Stoppable *stoppable_)
Definition: Stoppable.h:323
std::string
STL class.
ripple::Stoppable::m_stopped
std::atomic< bool > m_stopped
Definition: Stoppable.h:343
ripple::Stoppable::stopped
void stopped()
Called by derived classes to indicate that the stoppable has stopped.
Definition: Stoppable.cpp:72
ripple::Stoppable::onStop
virtual void onStop()
Override called when the stop notification is issued.
Definition: Stoppable.cpp:90
ripple::RootStoppable::m_
std::mutex m_
Definition: Stoppable.h:411
ripple::RootStoppable::startEntered_
std::atomic< bool > startEntered_
Definition: Stoppable.h:408
ripple::Stoppable::alertable_sleep_until
bool alertable_sleep_until(std::chrono::system_clock::time_point const &t)
Sleep or wake up on stop.
Definition: Stoppable.h:440
ripple::RootStoppable::stopEntered_
std::atomic< bool > stopEntered_
Definition: Stoppable.h:410
ripple::Stoppable::Stoppable
Stoppable(std::string name, RootStoppable &root)
Definition: Stoppable.cpp:27
ripple::Stoppable::hasParent_
bool hasParent_
Definition: Stoppable.h:349
ripple::Stoppable::onStart
virtual void onStart()
Override called during start.
Definition: Stoppable.cpp:85
ripple::Stoppable::m_mut
std::mutex m_mut
Definition: Stoppable.h:347
ripple::Stoppable::m_is_stopping
bool m_is_stopping
Definition: Stoppable.h:348
ripple::Stoppable::setParent
void setParent(Stoppable &parent)
Set the parent of this Stoppable.
Definition: Stoppable.cpp:43
ripple::Stoppable::stopAsyncRecursive
void stopAsyncRecursive(beast::Journal j)
Definition: Stoppable.cpp:123
ripple::RootStoppable::stop
void stop(beast::Journal j)
Notify a root stoppable and children to stop, and block until stopped.
Definition: Stoppable.cpp:191
ripple::Stoppable::isStopped
bool isStopped() const
Returns true if the requested stop has completed.
Definition: Stoppable.cpp:60
ripple::Stoppable::m_children
Children m_children
Definition: Stoppable.h:345
ripple::Stoppable
Provides an interface for starting and stopping.
Definition: Stoppable.h:201
ripple::RootStoppable
Definition: Stoppable.h:354
ripple::RootStoppable::startExited_
std::atomic< bool > startExited_
Definition: Stoppable.h:409
std::atomic::load
T load(T... args)
ripple::Stoppable::onPrepare
virtual void onPrepare()
Override called during preparation.
Definition: Stoppable.cpp:80
ripple::RootStoppable::isStopping
bool isStopping() const
Definition: Stoppable.cpp:175
chrono
std::unique_lock
STL class.
ripple::Stoppable::areChildrenStopped
bool areChildrenStopped() const
Returns true if all children have stopped.
Definition: Stoppable.cpp:66
ripple::Stoppable::m_cv
std::condition_variable m_cv
Definition: Stoppable.h:346
ripple::Stoppable::jobCounter
JobCounter & jobCounter()
Definition: Stoppable.h:420
ripple::Stoppable::m_child
Child m_child
Definition: Stoppable.h:341
ripple::RootStoppable::jobCounter
JobCounter & jobCounter()
Definition: Stoppable.h:394
ripple::Stoppable::Child::stoppable
Stoppable * stoppable
Definition: Stoppable.h:327
ripple::ClosureCounter< void, Job & >
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::RootStoppable::alertable_sleep_until
bool alertable_sleep_until(std::chrono::system_clock::time_point const &t)
Sleep or wake up on stop.
Definition: Stoppable.h:428
atomic
ripple::Stoppable::stopRecursive
void stopRecursive(beast::Journal j)
Definition: Stoppable.cpp:134
ripple::Stoppable::Child
Definition: Stoppable.h:321
ripple::Stoppable::RootStoppable
friend class RootStoppable
Definition: Stoppable.h:316
ripple::Stoppable::startRecursive
void startRecursive()
Definition: Stoppable.cpp:113
ripple::RootStoppable::start
void start()
Prepare and start all contained Stoppable objects.
Definition: Stoppable.cpp:181
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Stoppable::m_childrenStopped
std::atomic< bool > m_childrenStopped
Definition: Stoppable.h:344
std::condition_variable::wait_until
T wait_until(T... args)
ripple::Stoppable::onChildrenStopped
virtual void onChildrenStopped()
Override called when all children have stopped.
Definition: Stoppable.cpp:96
ripple::Stoppable::m_name
std::string m_name
Definition: Stoppable.h:339
ripple::RootStoppable::started
bool started() const
Return true if start() was ever called.
Definition: Stoppable.h:387
condition_variable
ripple::RootStoppable::jobCounter_
JobCounter jobCounter_
Definition: Stoppable.h:413
ripple::Stoppable::m_root
RootStoppable & m_root
Definition: Stoppable.h:340
mutex
ripple::Stoppable::getRoot
RootStoppable & getRoot()
Definition: Stoppable.h:214
ripple::RootStoppable::c_
std::condition_variable c_
Definition: Stoppable.h:412
ripple::Stoppable::isStopping
bool isStopping() const
Returns true if the stoppable should stop.
Definition: Stoppable.cpp:54
beast::LockFreeStack< Child >