proxygen
WorkerThread.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
11 
12 #include <folly/Portability.h>
13 #include <folly/String.h>
15 #include <glog/logging.h>
16 #include <signal.h>
17 
18 namespace proxygen {
19 
20 FOLLY_TLS WorkerThread* WorkerThread::currentWorker_ = nullptr;
21 
23  folly::EventBaseManager* eventBaseManager, const std::string& evbName)
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 }
32 
34  CHECK(state_ == State::IDLE);
35 }
36 
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 }
54 
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 }
72 
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 }
90 
92  std::lock_guard<std::mutex> guard(joinLock_);
93  if (thread_.joinable()) {
94  thread_.join();
95  }
96 }
97 
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 }
126 
128  currentWorker_ = nullptr;
129  if (eventBaseManager_) {
131  }
132 }
133 
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 }
158 
159 } // proxygen
static FOLLY_TLS WorkerThread * currentWorker_
Definition: WorkerThread.h:141
void setEventBase(EventBase *eventBase, bool takeOwnership)
virtual void cleanup()
folly::EventBase eventBase_
Definition: WorkerThread.h:137
virtual void setup()
WorkerThread(folly::EventBaseManager *ebm, const std::string &evbName=std::string())
folly::EventBaseManager * eventBaseManager_
Definition: WorkerThread.h:138
void terminateLoopSoon()
Definition: EventBase.cpp:493
GuardImpl guard(ErrorHandler &&handler)
Definition: Base.h:840
bool runInEventBaseThread(void(*fn)(T *), T *arg)
Definition: EventBase.h:794
const char * string
Definition: Conv.cpp:212
void setName(const std::string &name)
Definition: EventBase.cpp:740
void waitUntilRunning()
Definition: EventBase.cpp:249