GRPC Core  9.0.0
thd.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #ifndef GRPC_CORE_LIB_GPRPP_THD_H
20 #define GRPC_CORE_LIB_GPRPP_THD_H
21 
25 
26 #include <grpc/support/log.h>
27 #include <grpc/support/sync.h>
28 #include <grpc/support/thd_id.h>
29 #include <grpc/support/time.h>
30 
32 
33 namespace grpc_core {
34 namespace internal {
35 
38  public:
40  virtual void Start() = 0;
41  virtual void Join() = 0;
42 };
43 
44 } // namespace internal
45 
46 class Thread {
47  public:
48  class Options {
49  public:
50  Options() : joinable_(true), tracked_(true), stack_size_(0) {}
53  joinable_ = joinable;
54  return *this;
55  }
56  bool joinable() const { return joinable_; }
57 
60  tracked_ = tracked;
61  return *this;
62  }
63  bool tracked() const { return tracked_; }
64 
67  Options& set_stack_size(size_t bytes) {
68  stack_size_ = bytes;
69  return *this;
70  }
71  size_t stack_size() const { return stack_size_; }
72 
73  private:
74  bool joinable_;
75  bool tracked_;
76  size_t stack_size_;
77  };
81  Thread() : state_(FAKE), impl_(nullptr) {}
82 
89  Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg,
90  bool* success = nullptr, const Options& options = Options());
91 
94  Thread(Thread&& other)
95  : state_(other.state_), impl_(other.impl_), options_(other.options_) {
96  other.state_ = MOVED;
97  other.impl_ = nullptr;
98  other.options_ = Options();
99  }
100 
104  Thread& operator=(Thread&& other) {
105  if (this != &other) {
106  // TODO(vjpai): if we can be sure that all Thread's are actually
107  // constructed, then we should assert GPR_ASSERT(impl_ == nullptr) here.
108  // However, as long as threads come in structures that are
109  // allocated via gpr_malloc, this will not be the case, so we cannot
110  // assert it for the time being.
111  state_ = other.state_;
112  impl_ = other.impl_;
113  options_ = other.options_;
114  other.state_ = MOVED;
115  other.impl_ = nullptr;
116  other.options_ = Options();
117  }
118  return *this;
119  }
120 
126  ~Thread() { GPR_ASSERT(!options_.joinable() || impl_ == nullptr); }
127 
128  void Start() {
129  if (impl_ != nullptr) {
130  GPR_ASSERT(state_ == ALIVE);
131  state_ = STARTED;
132  impl_->Start();
133  // If the Thread is not joinable, then the impl_ will cause the deletion
134  // of this Thread object when the thread function completes. Since no
135  // other operation is allowed to a detached thread after Start, there is
136  // no need to change the value of the impl_ or state_ . The next operation
137  // on this object will be the deletion, which will trigger the destructor.
138  } else {
139  GPR_ASSERT(state_ == FAILED);
140  }
141  }
142 
143  // It is only legal to call Join if the Thread is created as joinable.
144  void Join() {
145  if (impl_ != nullptr) {
146  impl_->Join();
147  delete impl_;
148  state_ = DONE;
149  impl_ = nullptr;
150  } else {
151  GPR_ASSERT(state_ == FAILED);
152  }
153  }
154 
155  private:
156  Thread(const Thread&) = delete;
157  Thread& operator=(const Thread&) = delete;
158 
166  enum ThreadState { FAKE, ALIVE, STARTED, DONE, FAILED, MOVED };
167  ThreadState state_;
168  internal::ThreadInternalsInterface* impl_;
169  Options options_;
170 };
171 
172 } // namespace grpc_core
173 
174 #endif /* GRPC_CORE_LIB_GPRPP_THD_H */
Definition: thd.h:48
bool tracked() const
Definition: thd.h:63
size_t stack_size() const
Definition: thd.h:71
Options & set_joinable(bool joinable)
Set whether the thread is joinable or detached.
Definition: thd.h:52
Options & set_stack_size(size_t bytes)
Sets thread stack size (in bytes).
Definition: thd.h:67
bool joinable() const
Definition: thd.h:56
Options & set_tracked(bool tracked)
Set whether the thread is tracked for fork support.
Definition: thd.h:59
Options()
Definition: thd.h:50
Definition: thd.h:46
void Join()
Definition: thd.h:144
void Start()
Definition: thd.h:128
Thread(const char *thd_name, void(*thd_body)(void *arg), void *arg, bool *success=nullptr, const Options &options=Options())
Normal constructor to create a thread with name thd_name, which will execute a thread based on functi...
~Thread()
The destructor is strictly optional; either the thread never came to life and the constructor itself ...
Definition: thd.h:126
Thread(Thread &&other)
Move constructor for thread.
Definition: thd.h:94
Thread()
Default constructor only to allow use in structs that lack constructors Does not produce a validly-co...
Definition: thd.h:81
Thread & operator=(Thread &&other)
Move assignment operator for thread.
Definition: thd.h:104
Base class for platform-specific thread-state.
Definition: thd.h:37
virtual ~ThreadInternalsInterface()
Definition: thd.h:39
#define GPR_ASSERT(x)
abort() the process if x is zero, having written a line to the log.
Definition: log.h:94
Round Robin Policy.
Definition: backend_metric.cc:24
Definition: executor.h:30