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 
347  bool m_is_stopping = false;
348  bool hasParent_{false};
349 };
350 
351 //------------------------------------------------------------------------------
352 
353 class RootStoppable : public Stoppable
354 {
355 public:
356  explicit RootStoppable(std::string name);
357 
358  virtual ~RootStoppable();
359 
360  bool
361  isStopping() const;
362 
369  void
370  prepare();
371 
378  void
379  start();
380 
389  void
390  stop(beast::Journal j);
391 
393  bool
394  started() const
395  {
396  return m_started;
397  }
398 
399  /* JobQueue uses this method for Job counting. */
400  JobCounter&
402  {
403  return jobCounter_;
404  }
405 
410  bool
411  alertable_sleep_until(std::chrono::system_clock::time_point const& t);
412 
413 private:
414  /* Notify a root stoppable and children to stop, without waiting.
415  Has no effect if the stoppable was already notified.
416 
417  Returns true on the first call to this method, false otherwise.
418 
419  Thread safety:
420  Safe to call from any thread at any time.
421  */
422  bool
424 
431 };
434 //------------------------------------------------------------------------------
435 
436 JobCounter&
438 {
439  return m_root.jobCounter();
440 }
441 
442 //------------------------------------------------------------------------------
443 
444 inline bool
446  std::chrono::system_clock::time_point const& t)
447 {
449  if (m_calledStop)
450  return true;
451  return c_.wait_until(lock, t, [this] { return m_calledStop.load(); });
452 }
453 
454 inline bool
455 Stoppable::alertable_sleep_until(std::chrono::system_clock::time_point const& t)
456 {
457  return m_root.alertable_sleep_until(t);
458 }
459 
460 } // namespace ripple
461 
462 #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
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:425
ripple::Stoppable::m_stopped
std::atomic< bool > m_stopped
Definition: Stoppable.h:342
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:428
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:455
ripple::Stoppable::Stoppable
Stoppable(std::string name, RootStoppable &root)
Definition: Stoppable.cpp:27
ripple::Stoppable::hasParent_
bool hasParent_
Definition: Stoppable.h:348
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:346
ripple::Stoppable::m_is_stopping
bool m_is_stopping
Definition: Stoppable.h:347
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:344
ripple::Stoppable
Provides an interface for starting and stopping.
Definition: Stoppable.h:201
ripple::RootStoppable
Definition: Stoppable.h:353
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:345
ripple::Stoppable::jobCounter
JobCounter & jobCounter()
Definition: Stoppable.h:437
ripple::Stoppable::m_child
Child m_child
Definition: Stoppable.h:341
ripple::RootStoppable::m_calledStop
std::atomic< bool > m_calledStop
Definition: Stoppable.h:427
ripple::RootStoppable::jobCounter
JobCounter & jobCounter()
Definition: Stoppable.h:401
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:445
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:426
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()
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:343
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:394
condition_variable
ripple::RootStoppable::jobCounter_
JobCounter jobCounter_
Definition: Stoppable.h:430
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:429
ripple::Stoppable::isStopping
bool isStopping() const
Returns true if the stoppable should stop.
Definition: Stoppable.cpp:54
beast::LockFreeStack< Child >