Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / deps / grpc / src / core / lib / gprpp / thd.h
diff --git a/legacy-libs/grpc/deps/grpc/src/core/lib/gprpp/thd.h b/legacy-libs/grpc/deps/grpc/src/core/lib/gprpp/thd.h
new file mode 100644 (file)
index 0000000..0af33fa
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_GPRPP_THD_H
+#define GRPC_CORE_LIB_GPRPP_THD_H
+
+/** Internal thread interface. */
+
+#include <grpc/support/port_platform.h>
+
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd_id.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/gprpp/abstract.h"
+#include "src/core/lib/gprpp/memory.h"
+
+namespace grpc_core {
+namespace internal {
+
+/// Base class for platform-specific thread-state
+class ThreadInternalsInterface {
+ public:
+  virtual ~ThreadInternalsInterface() {}
+  virtual void Start() GRPC_ABSTRACT;
+  virtual void Join() GRPC_ABSTRACT;
+  GRPC_ABSTRACT_BASE_CLASS
+};
+
+}  // namespace internal
+
+class Thread {
+ public:
+  class Options {
+   public:
+    Options() : joinable_(true), tracked_(true), stack_size_(0) {}
+    /// Set whether the thread is joinable or detached.
+    Options& set_joinable(bool joinable) {
+      joinable_ = joinable;
+      return *this;
+    }
+    bool joinable() const { return joinable_; }
+
+    /// Set whether the thread is tracked for fork support.
+    Options& set_tracked(bool tracked) {
+      tracked_ = tracked;
+      return *this;
+    }
+    bool tracked() const { return tracked_; }
+
+    /// Sets thread stack size (in bytes). Sets to 0 will use the default stack
+    /// size which is 64KB for Windows threads and 2MB for Posix(x86) threads.
+    Options& set_stack_size(size_t bytes) {
+      stack_size_ = bytes;
+      return *this;
+    }
+    size_t stack_size() const { return stack_size_; }
+
+   private:
+    bool joinable_;
+    bool tracked_;
+    size_t stack_size_;
+  };
+  /// Default constructor only to allow use in structs that lack constructors
+  /// Does not produce a validly-constructed thread; must later
+  /// use placement new to construct a real thread. Does not init mu_ and cv_
+  Thread() : state_(FAKE), impl_(nullptr) {}
+
+  /// Normal constructor to create a thread with name \a thd_name,
+  /// which will execute a thread based on function \a thd_body
+  /// with argument \a arg once it is started.
+  /// The optional \a success argument indicates whether the thread
+  /// is successfully created.
+  /// The optional \a options can be used to set the thread detachable.
+  Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg,
+         bool* success = nullptr, const Options& options = Options());
+
+  /// Move constructor for thread. After this is called, the other thread
+  /// no longer represents a living thread object
+  Thread(Thread&& other)
+      : state_(other.state_), impl_(other.impl_), options_(other.options_) {
+    other.state_ = MOVED;
+    other.impl_ = nullptr;
+    other.options_ = Options();
+  }
+
+  /// Move assignment operator for thread. After this is called, the other
+  /// thread no longer represents a living thread object. Not allowed if this
+  /// thread actually exists
+  Thread& operator=(Thread&& other) {
+    if (this != &other) {
+      // TODO(vjpai): if we can be sure that all Thread's are actually
+      // constructed, then we should assert GPR_ASSERT(impl_ == nullptr) here.
+      // However, as long as threads come in structures that are
+      // allocated via gpr_malloc, this will not be the case, so we cannot
+      // assert it for the time being.
+      state_ = other.state_;
+      impl_ = other.impl_;
+      options_ = other.options_;
+      other.state_ = MOVED;
+      other.impl_ = nullptr;
+      other.options_ = Options();
+    }
+    return *this;
+  }
+
+  /// The destructor is strictly optional; either the thread never came to life
+  /// and the constructor itself killed it, or it has already been joined and
+  /// the Join function kills it, or it was detached (non-joinable) and it has
+  /// run to completion and is now killing itself. The destructor shouldn't have
+  /// to do anything.
+  ~Thread() { GPR_ASSERT(!options_.joinable() || impl_ == nullptr); }
+
+  void Start() {
+    if (impl_ != nullptr) {
+      GPR_ASSERT(state_ == ALIVE);
+      state_ = STARTED;
+      impl_->Start();
+      // If the Thread is not joinable, then the impl_ will cause the deletion
+      // of this Thread object when the thread function completes. Since no
+      // other operation is allowed to a detached thread after Start, there is
+      // no need to change the value of the impl_ or state_ . The next operation
+      // on this object will be the deletion, which will trigger the destructor.
+    } else {
+      GPR_ASSERT(state_ == FAILED);
+    }
+  }
+
+  // It is only legal to call Join if the Thread is created as joinable.
+  void Join() {
+    if (impl_ != nullptr) {
+      impl_->Join();
+      grpc_core::Delete(impl_);
+      state_ = DONE;
+      impl_ = nullptr;
+    } else {
+      GPR_ASSERT(state_ == FAILED);
+    }
+  }
+
+ private:
+  Thread(const Thread&) = delete;
+  Thread& operator=(const Thread&) = delete;
+
+  /// The thread states are as follows:
+  /// FAKE -- just a dummy placeholder Thread created by the default constructor
+  /// ALIVE -- an actual thread of control exists associated with this thread
+  /// STARTED -- the thread of control has been started
+  /// DONE -- the thread of control has completed and been joined
+  /// FAILED -- the thread of control never came alive
+  /// MOVED -- contents were moved out and we're no longer tracking them
+  enum ThreadState { FAKE, ALIVE, STARTED, DONE, FAILED, MOVED };
+  ThreadState state_;
+  internal::ThreadInternalsInterface* impl_;
+  Options options_;
+};
+
+}  // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_GPRPP_THD_H */