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 
201 {
202 protected:
203  Stoppable(std::string name, RootStoppable& root);
204 
205 public:
207  Stoppable(std::string name, Stoppable& parent);
208 
210  virtual ~Stoppable();
211 
214  {
215  return m_root;
216  }
217 
224  void
225  setParent(Stoppable& parent);
226 
228  bool
229  isStopping() const;
230 
232  bool
233  isStopped() const;
234 
236  bool
237  areChildrenStopped() const;
238 
239  /* JobQueue uses this method for Job counting. */
240  inline JobCounter&
241  jobCounter();
242 
247  bool
248  alertable_sleep_until(std::chrono::system_clock::time_point const& t);
249 
250 protected:
252  void
253  stopped();
254 
255 private:
263  virtual void
264  onPrepare();
265 
267  virtual void
268  onStart();
269 
291  virtual void
292  onStop();
293 
312  virtual void
314 
315  friend class RootStoppable;
316 
317  struct Child;
319 
320  struct Child : Children::Node
321  {
322  Child(Stoppable* stoppable_) : stoppable(stoppable_)
323  {
324  }
325 
327  };
328 
329  void
331  void
332  startRecursive();
333  void
335  void
337 
346  bool m_is_stopping = false;
347  bool hasParent_{false};
348 };
349 
350 //------------------------------------------------------------------------------
351 
352 class RootStoppable : public Stoppable
353 {
354 public:
355  explicit RootStoppable(std::string name);
356 
357  virtual ~RootStoppable();
358 
359  bool
360  isStopping() const;
361 
368  void
369  prepare();
370 
377  void
378  start();
379 
388  void
389  stop(beast::Journal j);
390 
392  bool
393  started() const
394  {
395  return m_started;
396  }
397 
398  /* JobQueue uses this method for Job counting. */
399  JobCounter&
401  {
402  return jobCounter_;
403  }
404 
409  bool
410  alertable_sleep_until(std::chrono::system_clock::time_point const& t);
411 
412 private:
413  /* Notify a root stoppable and children to stop, without waiting.
414  Has no effect if the stoppable was already notified.
415 
416  Returns true on the first call to this method, false otherwise.
417 
418  Thread safety:
419  Safe to call from any thread at any time.
420  */
421  bool
423 
430 };
433 //------------------------------------------------------------------------------
434 
435 JobCounter&
437 {
438  return m_root.jobCounter();
439 }
440 
441 //------------------------------------------------------------------------------
442 
443 inline bool
445  std::chrono::system_clock::time_point const& t)
446 {
448  if (m_calledStop)
449  return true;
450  return c_.wait_until(lock, t, [this] { return m_calledStop.load(); });
451 }
452 
453 inline bool
454 Stoppable::alertable_sleep_until(std::chrono::system_clock::time_point const& t)
455 {
456  return m_root.alertable_sleep_until(t);
457 }
458 
459 } // namespace ripple
460 
461 #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:322
ripple::RootStoppable::stopAsync
bool stopAsync(beast::Journal j)
Definition: Stoppable.cpp:209
std::string
STL class.
ripple::RootStoppable::m_prepared
std::atomic< bool > m_prepared
Definition: Stoppable.h:424
ripple::Stoppable::m_stopped
std::atomic< bool > m_stopped
Definition: Stoppable.h:341
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:427
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:454
ripple::Stoppable::Stoppable
Stoppable(std::string name, RootStoppable &root)
Definition: Stoppable.cpp:27
ripple::Stoppable::hasParent_
bool hasParent_
Definition: Stoppable.h:347
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:345
ripple::Stoppable::m_is_stopping
bool m_is_stopping
Definition: Stoppable.h:346
ripple::Stoppable::setParent
void setParent(Stoppable &parent)
Set the parent of this Stoppable.
Definition: Stoppable.cpp:43
ripple::RootStoppable::prepare
void prepare()
Prepare all contained Stoppable objects.
Definition: Stoppable.cpp:181
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:199
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:343
ripple::Stoppable
Provides an interface for starting and stopping.
Definition: Stoppable.h:200
ripple::RootStoppable
Definition: Stoppable.h:352
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:344
ripple::Stoppable::jobCounter
JobCounter & jobCounter()
Definition: Stoppable.h:436
ripple::Stoppable::m_child
Child m_child
Definition: Stoppable.h:340
ripple::RootStoppable::m_calledStop
std::atomic< bool > m_calledStop
Definition: Stoppable.h:426
ripple::RootStoppable::jobCounter
JobCounter & jobCounter()
Definition: Stoppable.h:400
ripple::Stoppable::Child::stoppable
Stoppable * stoppable
Definition: Stoppable.h:326
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:444
atomic
ripple::Stoppable::stopRecursive
void stopRecursive(beast::Journal j)
Definition: Stoppable.cpp:134
ripple::RootStoppable::m_started
std::atomic< bool > m_started
Definition: Stoppable.h:425
ripple::Stoppable::Child
Definition: Stoppable.h:320
ripple::Stoppable::RootStoppable
friend class RootStoppable
Definition: Stoppable.h:315
ripple::Stoppable::startRecursive
void startRecursive()
Definition: Stoppable.cpp:113
ripple::RootStoppable::start
void start()
Start all contained Stoppable objects.
Definition: Stoppable.cpp:188
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:342
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:338
ripple::RootStoppable::started
bool started() const
Return true if start() was ever called.
Definition: Stoppable.h:393
condition_variable
ripple::RootStoppable::jobCounter_
JobCounter jobCounter_
Definition: Stoppable.h:429
ripple::Stoppable::m_root
RootStoppable & m_root
Definition: Stoppable.h:339
mutex
ripple::Stoppable::getRoot
RootStoppable & getRoot()
Definition: Stoppable.h:213
ripple::RootStoppable::c_
std::condition_variable c_
Definition: Stoppable.h:428
ripple::Stoppable::isStopping
bool isStopping() const
Returns true if the stoppable should stop.
Definition: Stoppable.cpp:54
beast::LockFreeStack< Child >