libfoedus-core
FOEDUS Core Library
foedus::thread::StoppableThread Class Referencefinal

The frequently appearing quartet of std::thread, condition_varible, stop-request flag, and mutex. More...

Detailed Description

The frequently appearing quartet of std::thread, condition_varible, stop-request flag, and mutex.

This quartet helps implement a thread that consumes some task and also occasionally checks if someone requested to stop this thread. As this depends on C++11, the name of this file ends with impl. Thus, only private implementation classes directly use this class. If you are okay with C++11, you can use it from client programs, too.

Todo:
initialize() should only set thread. We should separate other initialization from it because the new thread might be already accessing those properties (at least valgrind is unhappy). We should have 'launch()' method instead.

Definition at line 45 of file stoppable_thread_impl.hpp.

#include <stoppable_thread_impl.hpp>

Public Member Functions

 StoppableThread ()
 
 StoppableThread (const StoppableThread &other)=delete
 
StoppableThreadoperator= (const StoppableThread &other)=delete
 
 StoppableThread (StoppableThread &&other)=delete
 
StoppableThreadoperator= (StoppableThread &&other)=delete
 
void initialize (const std::string &name, std::thread &&the_thread, const std::chrono::microseconds &sleep_interval)
 Initializes this object for the given thread. More...
 
void initialize (const std::string &name_prefix, int32_t name_ordinal, std::thread &&the_thread, const std::chrono::microseconds &sleep_interval)
 An overload to receive the common pattern of names "Xxx-ordinal". More...
 
void stop ()
 request_stop() plus wait_for_stop(). More...
 
void request_stop ()
 If the thread is still running, requests the thread to stop and waits until it exists. More...
 
void wait_for_stop ()
 Blocks until the thread stops. More...
 
void wakeup ()
 If the thread is still running and also sleeping, requests the thread to immediately wakeup and do its job. More...
 
bool sleep ()
 Sleep until the interval elapses or someone requests to stop this thread. More...
 
bool is_stop_requested () const
 returns whether someone has requested to stop this. More...
 
bool is_stop_requested_weak () const
 non-atomic is_stop_requested(). More...
 
bool is_stopped () const
 returns whether this thread has stopped (if the thread hasn't started, false too). More...
 
bool is_stopped_weak () const
 non-atomic is_stopped(). More...
 
template<typename HANDLE_TYPE >
HANDLE_TYPE native_handle ()
 wraps std::thread::native_handle() More...
 
std::string to_string () const
 

Friends

std::ostream & operator<< (std::ostream &o, const StoppableThread &v)
 

Constructor & Destructor Documentation

foedus::thread::StoppableThread::StoppableThread ( )
inline

Definition at line 47 of file stoppable_thread_impl.hpp.

47  : sleep_interval_(0),
48  started_(false), stop_requested_(false), stopped_(false) {}
foedus::thread::StoppableThread::StoppableThread ( const StoppableThread other)
delete
foedus::thread::StoppableThread::StoppableThread ( StoppableThread &&  other)
delete

Member Function Documentation

void foedus::thread::StoppableThread::initialize ( const std::string &  name,
std::thread &&  the_thread,
const std::chrono::microseconds &  sleep_interval 
)

Initializes this object for the given thread.

Definition at line 29 of file stoppable_thread_impl.cpp.

Referenced by initialize().

30  {
31  name_ = name;
32  thread_ = std::move(the_thread);
33  sleep_interval_ = sleep_interval;
34  started_ = true;
35  stop_requested_ = false;
36  stopped_ = false;
37  LOG(INFO) << name_ << " initialized. sleep_interval=" << sleep_interval_.count() << " microsec";
38 }

Here is the caller graph for this function:

void foedus::thread::StoppableThread::initialize ( const std::string &  name_prefix,
int32_t  name_ordinal,
std::thread &&  the_thread,
const std::chrono::microseconds &  sleep_interval 
)

An overload to receive the common pattern of names "Xxx-ordinal".

Definition at line 40 of file stoppable_thread_impl.cpp.

References initialize().

41  {
42  std::stringstream str;
43  str << name_prefix << name_ordinal;
44  initialize(str.str(), std::move(the_thread), sleep_interval);
45 }
void initialize(const std::string &name, std::thread &&the_thread, const std::chrono::microseconds &sleep_interval)
Initializes this object for the given thread.

Here is the call graph for this function:

bool foedus::thread::StoppableThread::is_stop_requested ( ) const
inline

returns whether someone has requested to stop this.

Definition at line 103 of file stoppable_thread_impl.hpp.

Referenced by request_stop(), and sleep().

103 { return stop_requested_; }

Here is the caller graph for this function:

bool foedus::thread::StoppableThread::is_stop_requested_weak ( ) const
inline

non-atomic is_stop_requested().

Definition at line 105 of file stoppable_thread_impl.hpp.

105  {
106  return stop_requested_.load(std::memory_order_relaxed);
107  }
bool foedus::thread::StoppableThread::is_stopped ( ) const
inline

returns whether this thread has stopped (if the thread hasn't started, false too).

Definition at line 110 of file stoppable_thread_impl.hpp.

Referenced by request_stop(), and wait_for_stop().

110 { return stopped_; }

Here is the caller graph for this function:

bool foedus::thread::StoppableThread::is_stopped_weak ( ) const
inline

non-atomic is_stopped().

Definition at line 112 of file stoppable_thread_impl.hpp.

112 { return stopped_.load(std::memory_order_relaxed); }
template<typename HANDLE_TYPE >
HANDLE_TYPE foedus::thread::StoppableThread::native_handle ( )
inline

wraps std::thread::native_handle()

Definition at line 116 of file stoppable_thread_impl.hpp.

116 { return static_cast<HANDLE_TYPE>(thread_.native_handle()); }
StoppableThread& foedus::thread::StoppableThread::operator= ( const StoppableThread other)
delete
StoppableThread& foedus::thread::StoppableThread::operator= ( StoppableThread &&  other)
delete
void foedus::thread::StoppableThread::request_stop ( )

If the thread is still running, requests the thread to stop and waits until it exists.

If the thread has not started or has already stopped, do nothing (so, this is idempotent). Unlike stop(), this method doesn't join the thread. So, it immediately returns.

Definition at line 68 of file stoppable_thread_impl.cpp.

References is_stop_requested(), is_stopped(), and foedus::thread::ConditionVariable::notify_one().

Referenced by stop().

68  {
69  if (started_ && !is_stopped() && !is_stop_requested()) {
70  LOG(INFO) << "Requesting to stop " << name_ << "...";
71  condition_.notify_one([this]{ stop_requested_ = true; });
72  LOG(INFO) << "Requested to stop " << name_;
73  } else {
74  LOG(INFO) << "Already requested to stop: " << name_;
75  }
76 }
bool is_stopped() const
returns whether this thread has stopped (if the thread hasn't started, false too).
bool is_stop_requested() const
returns whether someone has requested to stop this.
void notify_one(SIGNAL_ACTION signal_action)
Notify one waiter that the event has happened.

Here is the call graph for this function:

Here is the caller graph for this function:

bool foedus::thread::StoppableThread::sleep ( )

Sleep until the interval elapses or someone requests to stop this thread.

Returns
whether someone has requested to stop this thread.

For example, use it as follows.

void my_thread_handler(StoppableThread* me) {
while (!me->sleep()) {
// some stuff
}
}

Definition at line 47 of file stoppable_thread_impl.cpp.

References is_stop_requested(), and foedus::thread::ConditionVariable::wait_for().

47  {
48  VLOG(1) << name_ << " sleeping for " << sleep_interval_.count() << " microsec";
49  condition_.wait_for(sleep_interval_);
50  VLOG(1) << name_ << " woke up";
51  if (is_stop_requested()) {
52  LOG(INFO) << name_ << " stop requested";
53  return true;
54  } else {
55  return false;
56  }
57 }
bool wait_for(const std::chrono::duration< REP, PERIOD > &timeout, PREDICATE predicate)
Block until the event happens or the given period elapses.
bool is_stop_requested() const
returns whether someone has requested to stop this.

Here is the call graph for this function:

void foedus::thread::StoppableThread::stop ( )

request_stop() plus wait_for_stop().

This method is idempotent. If the thread is not running already, this immediately returns.

Definition at line 64 of file stoppable_thread_impl.cpp.

References request_stop(), and wait_for_stop().

64  {
65  request_stop();
66  wait_for_stop();
67 }
void request_stop()
If the thread is still running, requests the thread to stop and waits until it exists.
void wait_for_stop()
Blocks until the thread stops.

Here is the call graph for this function:

std::string foedus::thread::StoppableThread::to_string ( ) const

Definition at line 87 of file stoppable_thread_impl.cpp.

87  {
88  std::stringstream stream;
89  stream << *this;
90  return stream.str();
91 }
void foedus::thread::StoppableThread::wait_for_stop ( )

Blocks until the thread stops.

If the thread is not running anyways, this does nothing.

Definition at line 78 of file stoppable_thread_impl.cpp.

References is_stopped().

Referenced by stop().

78  {
79  if (started_ && !is_stopped()) {
80  LOG(INFO) << "Stopping " << name_ << "...";
81  thread_.join();
82  LOG(INFO) << "Successfully Stopped " << name_;
83  stopped_ = true;
84  }
85 }
bool is_stopped() const
returns whether this thread has stopped (if the thread hasn't started, false too).

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::thread::StoppableThread::wakeup ( )

If the thread is still running and also sleeping, requests the thread to immediately wakeup and do its job.

If the thread is not running or not sleeping, has no effect.

Definition at line 59 of file stoppable_thread_impl.cpp.

References foedus::thread::ConditionVariable::notify_one().

59  {
60  VLOG(1) << "Waking up " << name_ << "...";
61  condition_.notify_one();
62 }
void notify_one(SIGNAL_ACTION signal_action)
Notify one waiter that the event has happened.

Here is the call graph for this function:

Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  o,
const StoppableThread v 
)
friend

Definition at line 93 of file stoppable_thread_impl.cpp.

93  {
94  o << "<StoppableThread>"
95  << "<name_>" << v.name_ << "</name_>"
96  << "<native_thread_id>" << v.thread_.get_id() << "</native_thread_id>"
97  << "<sleep_interval_>" << v.sleep_interval_.count() << "</sleep_interval_>"
98  << "<started_>" << v.started_.load() << "</started_>"
99  << "<stop_requested_>" << v.stop_requested_.load() << "</stop_requested_>"
100  << "<stopped_>" << v.stopped_.load() << "</stopped_>"
101  << "</StoppableThread>";
102  return o;
103 }

The documentation for this class was generated from the following files: