From 72035e7265037676a8cd63abd2556d20df64e377 Mon Sep 17 00:00:00 2001 From: Yuwei Huang Date: Tue, 19 Feb 2019 13:58:26 -0800 Subject: [PATCH] Move thread body logic into a private static method Clang doesn't support adapting calling convention when converting a non-capturing lambda into a function pointer, and it doesn't support tagging a lambda with calling convention AFAICT. In thd_windows.cc, we create the thread body lambda and pass it to CreateThread(), which fails to build on clang because it cannot convert the lambda into stdcall function. Note that this bug only happens when building for x32 architecture. x64 is not affected because there is only one standard x64 calling convention. This change fixes this by moving the thread body logic into a private static method and tagging it with WINAPI (which expands to __stdcall). --- src/core/lib/gprpp/thd_windows.cc | 33 ++++++++++++++----------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc index 71584fd358e52..2512002a96c32 100644 --- a/src/core/lib/gprpp/thd_windows.cc +++ b/src/core/lib/gprpp/thd_windows.cc @@ -33,10 +33,8 @@ #if defined(_MSC_VER) #define thread_local __declspec(thread) -#define WIN_LAMBDA #elif defined(__GNUC__) #define thread_local __thread -#define WIN_LAMBDA WINAPI #else #error "Unknown compiler - please file a bug report" #endif @@ -71,22 +69,7 @@ class ThreadInternalsWindows gpr_free(info_); *success = false; } else { - handle = CreateThread( - nullptr, 64 * 1024, - [](void* v) WIN_LAMBDA -> DWORD { - g_thd_info = static_cast(v); - gpr_mu_lock(&g_thd_info->thread->mu_); - while (!g_thd_info->thread->started_) { - gpr_cv_wait(&g_thd_info->thread->ready_, &g_thd_info->thread->mu_, - gpr_inf_future(GPR_CLOCK_MONOTONIC)); - } - gpr_mu_unlock(&g_thd_info->thread->mu_); - g_thd_info->body(g_thd_info->arg); - BOOL ret = SetEvent(g_thd_info->join_event); - GPR_ASSERT(ret); - return 0; - }, - info_, 0, nullptr); + handle = CreateThread(nullptr, 64 * 1024, thread_body, info_, 0, nullptr); if (handle == nullptr) { destroy_thread(); *success = false; @@ -116,6 +99,20 @@ class ThreadInternalsWindows } private: + static DWORD WINAPI thread_body(void* v) { + g_thd_info = static_cast(v); + gpr_mu_lock(&g_thd_info->thread->mu_); + while (!g_thd_info->thread->started_) { + gpr_cv_wait(&g_thd_info->thread->ready_, &g_thd_info->thread->mu_, + gpr_inf_future(GPR_CLOCK_MONOTONIC)); + } + gpr_mu_unlock(&g_thd_info->thread->mu_); + g_thd_info->body(g_thd_info->arg); + BOOL ret = SetEvent(g_thd_info->join_event); + GPR_ASSERT(ret); + return 0; + } + void destroy_thread() { CloseHandle(info_->join_event); gpr_free(info_);