Fix windows thd, I think

reviewable/pr17308/r1
yang-g 6 years ago
parent 49beab68be
commit c27db3ed0c
  1. 34
      src/core/lib/gprpp/thd_windows.cc

@ -48,6 +48,7 @@ struct thd_info {
void (*body)(void* arg); /* body of a thread */ void (*body)(void* arg); /* body of a thread */
void* arg; /* argument to a thread */ void* arg; /* argument to a thread */
HANDLE join_event; /* the join event */ HANDLE join_event; /* the join event */
bool joinable; /* whether it is joinable */
}; };
thread_local struct thd_info* g_thd_info; thread_local struct thd_info* g_thd_info;
@ -55,7 +56,8 @@ thread_local struct thd_info* g_thd_info;
class ThreadInternalsWindows class ThreadInternalsWindows
: public grpc_core::internal::ThreadInternalsInterface { : public grpc_core::internal::ThreadInternalsInterface {
public: public:
ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success) ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success,
const grpc_core::Thread::Options& options)
: started_(false) { : started_(false) {
gpr_mu_init(&mu_); gpr_mu_init(&mu_);
gpr_cv_init(&ready_); gpr_cv_init(&ready_);
@ -65,25 +67,37 @@ class ThreadInternalsWindows
info_->thread = this; info_->thread = this;
info_->body = thd_body; info_->body = thd_body;
info_->arg = arg; info_->arg = arg;
info_->join_event = nullptr;
info_->joinable = options.joinable();
if (info_->joinable) {
info_->join_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); info_->join_event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
if (info_->join_event == nullptr) { if (info_->join_event == nullptr) {
gpr_free(info_); gpr_free(info_);
*success = false; *success = false;
} else { return;
handle = CreateThread( }
nullptr, 64 * 1024, }
handle = CreateThread(nullptr, 64 * 1024,
[](void* v) WIN_LAMBDA -> DWORD { [](void* v) WIN_LAMBDA -> DWORD {
g_thd_info = static_cast<thd_info*>(v); g_thd_info = static_cast<thd_info*>(v);
gpr_mu_lock(&g_thd_info->thread->mu_); gpr_mu_lock(&g_thd_info->thread->mu_);
while (!g_thd_info->thread->started_) { while (!g_thd_info->thread->started_) {
gpr_cv_wait(&g_thd_info->thread->ready_, &g_thd_info->thread->mu_, gpr_cv_wait(&g_thd_info->thread->ready_,
&g_thd_info->thread->mu_,
gpr_inf_future(GPR_CLOCK_MONOTONIC)); gpr_inf_future(GPR_CLOCK_MONOTONIC));
} }
gpr_mu_unlock(&g_thd_info->thread->mu_); gpr_mu_unlock(&g_thd_info->thread->mu_);
if (!g_thd_info->joinable) {
grpc_core::Delete(g_thd_info->thread);
g_thd_info->thread = nullptr;
}
g_thd_info->body(g_thd_info->arg); g_thd_info->body(g_thd_info->arg);
if (g_thd_info->joinable) {
BOOL ret = SetEvent(g_thd_info->join_event); BOOL ret = SetEvent(g_thd_info->join_event);
GPR_ASSERT(ret); GPR_ASSERT(ret);
} else {
gpr_free(g_thd_info);
}
return 0; return 0;
}, },
info_, 0, nullptr); info_, 0, nullptr);
@ -95,7 +109,6 @@ class ThreadInternalsWindows
*success = true; *success = true;
} }
} }
}
~ThreadInternalsWindows() override { ~ThreadInternalsWindows() override {
gpr_mu_destroy(&mu_); gpr_mu_destroy(&mu_);
@ -117,7 +130,9 @@ class ThreadInternalsWindows
private: private:
void destroy_thread() { void destroy_thread() {
if (info_ != nullptr && info_->joinable) {
CloseHandle(info_->join_event); CloseHandle(info_->join_event);
}
gpr_free(info_); gpr_free(info_);
} }
@ -132,9 +147,10 @@ class ThreadInternalsWindows
namespace grpc_core { namespace grpc_core {
Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg,
bool* success) { bool* success, const Options& options) : options_(options) {
bool outcome = false; bool outcome = false;
impl_ = grpc_core::New<ThreadInternalsWindows>(thd_body, arg, &outcome); impl_ =
grpc_core::New<ThreadInternalsWindows>(thd_body, arg, &outcome, options);
if (outcome) { if (outcome) {
state_ = ALIVE; state_ = ALIVE;
} else { } else {

Loading…
Cancel
Save