#ifndef GRPC_CORE_LIB_GPRPP_THD_H
#define GRPC_CORE_LIB_GPRPP_THD_H
#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 {
class ThreadInternalsInterface {
public:
virtual ~ThreadInternalsInterface() {}
virtual void Start() GRPC_ABSTRACT;
virtual void Join() GRPC_ABSTRACT;
GRPC_ABSTRACT_BASE_CLASS
};
}
class Thread {
public:
Thread() : state_(FAKE), impl_(nullptr) {}
Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg,
bool* success = nullptr);
Thread(Thread&& other) : state_(other.state_), impl_(other.impl_) {
other.state_ = MOVED;
other.impl_ = nullptr;
}
Thread& operator=(Thread&& other) {
if (this != &other) {
state_ = other.state_;
impl_ = other.impl_;
other.state_ = MOVED;
other.impl_ = nullptr;
}
return *this;
}
~Thread() { GPR_ASSERT(impl_ == nullptr); }
void Start() {
if (impl_ != nullptr) {
GPR_ASSERT(state_ == ALIVE);
state_ = STARTED;
impl_->Start();
} else {
GPR_ASSERT(state_ == FAILED);
}
};
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;
enum ThreadState { FAKE, ALIVE, STARTED, DONE, FAILED, MOVED };
ThreadState state_;
internal::ThreadInternalsInterface* impl_;
};
}
#endif