proxygen
proxygen::WorkerThread Class Reference

#include <WorkerThread.h>

Inheritance diagram for proxygen::WorkerThread:
proxygen::RequestWorker

Public Member Functions

 WorkerThread (folly::EventBaseManager *ebm, const std::string &evbName=std::string())
 
virtual ~WorkerThread ()
 
void start ()
 
void stopWhenIdle ()
 
void forceStop ()
 
void wait ()
 
folly::EventBasegetEventBase ()
 
std::thread::native_handle_type getThreadNativeHandle () noexcept
 
std::thread::id getThreadId () const noexcept
 

Static Public Member Functions

static WorkerThreadgetCurrentWorkerThread ()
 

Protected Member Functions

virtual void setup ()
 
virtual void cleanup ()
 

Private Types

enum  State : uint8_t {
  State::IDLE, State::STARTING, State::RUNNING, State::STOP_WHEN_IDLE,
  State::FORCE_STOP
}
 

Private Member Functions

 WorkerThread (WorkerThread const &)=delete
 
WorkerThreadoperator= (WorkerThread const &)=delete
 
void runLoop ()
 

Private Attributes

State state_ {State::IDLE}
 
std::thread thread_
 
std::mutex joinLock_
 
folly::EventBase eventBase_
 
folly::EventBaseManagereventBaseManager_ {nullptr}
 

Static Private Attributes

static FOLLY_TLS WorkerThreadcurrentWorker_ = nullptr
 

Detailed Description

A WorkerThread represents an independent event loop that runs in its own thread.

Definition at line 29 of file WorkerThread.h.

Member Enumeration Documentation

enum proxygen::WorkerThread::State : uint8_t
strongprivate
Enumerator
IDLE 
STARTING 
RUNNING 
STOP_WHEN_IDLE 
FORCE_STOP 

Definition at line 120 of file WorkerThread.h.

120  : uint8_t {
121  IDLE, // Not yet started
122  STARTING, // start() called, thread not fully started yet
123  RUNNING, // Thread running normally
124  STOP_WHEN_IDLE, // stopWhenIdle() called, not stopped yet
125  FORCE_STOP, // forceStop() called, but the loop is still cleaning up
126  };

Constructor & Destructor Documentation

proxygen::WorkerThread::WorkerThread ( folly::EventBaseManager ebm,
const std::string evbName = std::string() 
)
explicit

Definition at line 22 of file WorkerThread.cpp.

References eventBase_, and folly::EventBase::setName().

24  : eventBaseManager_(eventBaseManager) {
25  // Only set the event base name if not empty.
26  // While not ideal, this preserves the previous program name inheritance
27  // behavior.
28  if (!evbName.empty()) {
29  eventBase_.setName(evbName);
30  }
31 }
folly::EventBase eventBase_
Definition: WorkerThread.h:137
folly::EventBaseManager * eventBaseManager_
Definition: WorkerThread.h:138
void setName(const std::string &name)
Definition: EventBase.cpp:740
proxygen::WorkerThread::~WorkerThread ( )
virtual

Definition at line 33 of file WorkerThread.cpp.

References IDLE, and state_.

proxygen::WorkerThread::WorkerThread ( WorkerThread const &  )
privatedelete

Member Function Documentation

void proxygen::WorkerThread::cleanup ( )
protectedvirtual

Reimplemented in proxygen::RequestWorker.

Definition at line 127 of file WorkerThread.cpp.

References folly::EventBaseManager::clearEventBase(), currentWorker_, and eventBaseManager_.

Referenced by proxygen::RequestWorker::cleanup(), and start().

127  {
128  currentWorker_ = nullptr;
129  if (eventBaseManager_) {
131  }
132 }
static FOLLY_TLS WorkerThread * currentWorker_
Definition: WorkerThread.h:141
folly::EventBaseManager * eventBaseManager_
Definition: WorkerThread.h:138
void proxygen::WorkerThread::forceStop ( )

Request that the worker stop executing as soon as possible.

This will terminate the worker thread's event loop, and cause the thread to return. If there are any services still running in the worker thread, their events will no longer be processed.

This function is asynchronous: it signals the worker thread to stop, and returns without waiting for the thread to actually terminate. The wait() method must be called to wait for the thread to terminate.

Definition at line 73 of file WorkerThread.cpp.

References eventBase_, FORCE_STOP, IDLE, folly::EventBase::runInEventBaseThread(), RUNNING, state_, STOP_WHEN_IDLE, and folly::EventBase::terminateLoopSoon().

73  {
74  // Call runInEventBaseThread() to perform all of the work in the actual
75  // worker thread.
76  //
77  // This way we don't have to synchronize access to state_.
82  // state_ could be IDLE if we don't execute this callback until the
83  // EventBase is destroyed in the WorkerThread destructor
84  } else if (state_ != State::IDLE) {
85  LOG(FATAL) << "forceStop() called in unexpected state " <<
86  static_cast<int>(state_);
87  }
88  });
89 }
folly::EventBase eventBase_
Definition: WorkerThread.h:137
void terminateLoopSoon()
Definition: EventBase.cpp:493
bool runInEventBaseThread(void(*fn)(T *), T *arg)
Definition: EventBase.h:794
static WorkerThread* proxygen::WorkerThread::getCurrentWorkerThread ( )
inlinestatic

Get the current WorkerThread running this thread.

Returns nullptr if called from a thread that is not running inside WorkerThread.

Definition at line 111 of file WorkerThread.h.

References folly::ssl::cleanup().

Referenced by proxygen::RequestWorker::getRequestWorker().

111  {
112  return currentWorker_;
113  }
static FOLLY_TLS WorkerThread * currentWorker_
Definition: WorkerThread.h:141
folly::EventBase* proxygen::WorkerThread::getEventBase ( )
inline

Get the EventBase used to drive the events in this worker thread.

Definition at line 85 of file WorkerThread.h.

Referenced by proxygen::RequestWorker::flushStats().

85  {
86  return &eventBase_;
87  }
folly::EventBase eventBase_
Definition: WorkerThread.h:137
std::thread::id proxygen::WorkerThread::getThreadId ( ) const
inlinenoexcept

Get ID of the underlying thread objects (valid only when the thread is running).

Definition at line 101 of file WorkerThread.h.

101  {
102  return thread_.get_id();
103  }
std::thread::native_handle_type proxygen::WorkerThread::getThreadNativeHandle ( )
inlinenoexcept

Get native handle of the underlying thread object (valid only when the thread is running).

Definition at line 93 of file WorkerThread.h.

93  {
94  return thread_.native_handle();
95  }
WorkerThread& proxygen::WorkerThread::operator= ( WorkerThread const &  )
privatedelete
void proxygen::WorkerThread::runLoop ( )
private

Definition at line 134 of file WorkerThread.cpp.

References eventBase_, FORCE_STOP, IDLE, folly::EventBase::loop(), folly::EventBase::loopForever(), RUNNING, STARTING, state_, and STOP_WHEN_IDLE.

Referenced by start().

134  {
135  // Update state_
136  CHECK(state_ == State::STARTING);
138 
139  VLOG(1) << "WorkerThread " << this << " starting";
140 
141  // Call loopForever(). This will only return after stopWhenIdle() or
142  // forceStop() has been called.
144 
145  if (state_ == State::STOP_WHEN_IDLE) {
146  // We have been asked to stop when there are no more events left.
147  // Call loop() to finish processing events. This will return when there
148  // are no more events to process, or after forceStop() has been called.
149  VLOG(1) << "WorkerThread " << this << " finishing non-internal events";
150  eventBase_.loop();
151  }
152 
155 
156  VLOG(1) << "WorkerThread " << this << " terminated";
157 }
folly::EventBase eventBase_
Definition: WorkerThread.h:137
void proxygen::WorkerThread::setup ( )
protectedvirtual

Reimplemented in proxygen::RequestWorker.

Definition at line 98 of file WorkerThread.cpp.

References currentWorker_, eventBase_, eventBaseManager_, and folly::EventBaseManager::setEventBase().

Referenced by proxygen::RequestWorker::setup(), and start().

98  {
99 #ifndef _MSC_VER
100  sigset_t ss;
101 
102  // Ignore some signals
103  sigemptyset(&ss);
104  sigaddset(&ss, SIGHUP);
105  sigaddset(&ss, SIGINT);
106  sigaddset(&ss, SIGQUIT);
107  sigaddset(&ss, SIGUSR1);
108  sigaddset(&ss, SIGUSR2);
109  sigaddset(&ss, SIGPIPE);
110  sigaddset(&ss, SIGALRM);
111  sigaddset(&ss, SIGTERM);
112  sigaddset(&ss, SIGCHLD);
113  sigaddset(&ss, SIGIO);
114  PCHECK(pthread_sigmask(SIG_BLOCK, &ss, nullptr) == 0);
115 #endif
116 
117  // Update the currentWorker_ thread-local pointer
118  CHECK(nullptr == currentWorker_);
119  currentWorker_ = this;
120 
121  // Update the manager with the event base this worker runs on
122  if (eventBaseManager_) {
124  }
125 }
static FOLLY_TLS WorkerThread * currentWorker_
Definition: WorkerThread.h:141
void setEventBase(EventBase *eventBase, bool takeOwnership)
folly::EventBase eventBase_
Definition: WorkerThread.h:137
folly::EventBaseManager * eventBaseManager_
Definition: WorkerThread.h:138
void proxygen::WorkerThread::start ( )

Begin execution of the worker.

This starts the worker thread, and returns immediately.

Definition at line 37 of file WorkerThread.cpp.

References cleanup(), eventBase_, folly::gen::guard(), IDLE, joinLock_, runLoop(), setup(), STARTING, state_, thread_, and folly::EventBase::waitUntilRunning().

37  {
38  CHECK(state_ == State::IDLE);
40 
41  {
42  // because you could theoretically call wait in parallel with start,
43  // why are you in such a hurry anyways?
44  std::lock_guard<std::mutex> guard(joinLock_);
45  thread_ = std::thread([&]() mutable {
46  this->setup();
47  this->runLoop();
48  this->cleanup();
49  });
50  }
52  // The server has been set up and is now in the loop implementation
53 }
virtual void cleanup()
folly::EventBase eventBase_
Definition: WorkerThread.h:137
virtual void setup()
GuardImpl guard(ErrorHandler &&handler)
Definition: Base.h:840
void waitUntilRunning()
Definition: EventBase.cpp:249
void proxygen::WorkerThread::stopWhenIdle ( )

Request that the worker thread stop when there are no more events to process.

Normally each worker thread runs forever, even if it is idle with no events to process. This function requests that the worker thread return when it becomes idle.

This is used for graceful shutdown: Once the services have been asked to shutdown, stopWhenIdle() can be called on the WorkerThread so that it will return as soon as the services in this thread no longer have any events to process.

Typically you will still want to call forceStop() after a timeout, in case some of the services take too long to shut down gracefully.

Definition at line 55 of file WorkerThread.cpp.

References eventBase_, IDLE, folly::EventBase::runInEventBaseThread(), RUNNING, state_, STOP_WHEN_IDLE, and folly::EventBase::terminateLoopSoon().

55  {
56  // Call runInEventBaseThread() to perform all of the work in the actual
57  // worker thread.
58  //
59  // This way we don't have to synchronize access to state_.
61  if (state_ == State::RUNNING) {
64  // state_ could be IDLE if we don't execute this callback until the
65  // EventBase is destroyed in the WorkerThread destructor
66  } else if (state_ != State::IDLE && state_ != State::STOP_WHEN_IDLE) {
67  LOG(FATAL) << "stopWhenIdle() called in unexpected state " <<
68  static_cast<int>(state_);
69  }
70  });
71 }
folly::EventBase eventBase_
Definition: WorkerThread.h:137
void terminateLoopSoon()
Definition: EventBase.cpp:493
bool runInEventBaseThread(void(*fn)(T *), T *arg)
Definition: EventBase.h:794
void proxygen::WorkerThread::wait ( )

Synchronously wait for termination of the worker thread.

Note that the worker thread will only terminate after stopWhenIdle() or forceStop() has been called, so you typically should only call wait() after first using one of these functions.

Definition at line 91 of file WorkerThread.cpp.

References folly::gen::guard(), joinLock_, and thread_.

91  {
92  std::lock_guard<std::mutex> guard(joinLock_);
93  if (thread_.joinable()) {
94  thread_.join();
95  }
96 }
GuardImpl guard(ErrorHandler &&handler)
Definition: Base.h:840

Member Data Documentation

FOLLY_TLS WorkerThread * proxygen::WorkerThread::currentWorker_ = nullptr
staticprivate

Definition at line 141 of file WorkerThread.h.

Referenced by cleanup(), and setup().

folly::EventBase proxygen::WorkerThread::eventBase_
private

Definition at line 137 of file WorkerThread.h.

Referenced by forceStop(), runLoop(), setup(), start(), stopWhenIdle(), and WorkerThread().

folly::EventBaseManager* proxygen::WorkerThread::eventBaseManager_ {nullptr}
private

Definition at line 138 of file WorkerThread.h.

Referenced by cleanup(), and setup().

std::mutex proxygen::WorkerThread::joinLock_
private

Definition at line 136 of file WorkerThread.h.

Referenced by start(), and wait().

State proxygen::WorkerThread::state_ {State::IDLE}
private

Definition at line 134 of file WorkerThread.h.

Referenced by forceStop(), runLoop(), start(), stopWhenIdle(), and ~WorkerThread().

std::thread proxygen::WorkerThread::thread_
private

Definition at line 135 of file WorkerThread.h.

Referenced by start(), and wait().


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