From 578f7b1707bb5ebcea8cb2bc31cd02e5bd385ad8 Mon Sep 17 00:00:00 2001 From: Jason Lokerson Date: Thu, 14 Aug 2014 18:18:13 -0700 Subject: [PATCH] Thread instantiation must happen via placement operations It's possible for the created thread to attempt to make use of m_thisThread before it's actually been moved out of the rvalue and into its permanent home. To prevent this from happening, we completely avoid the earlier strategy of performing a move, and instead place the thread type in the memory allocated for it. This happens before the corresponding thread is started. --- src/autowiring/BasicThread.cpp | 6 ++++-- src/autowiring/CoreThreadWin.cpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/autowiring/BasicThread.cpp b/src/autowiring/BasicThread.cpp index 859049e8e..42573a1ca 100644 --- a/src/autowiring/BasicThread.cpp +++ b/src/autowiring/BasicThread.cpp @@ -144,8 +144,10 @@ bool BasicThread::Start(std::shared_ptr outstanding) { m_state->m_stateCondition.notify_all(); } - // Kick off a thread and return here - m_state->m_thisThread = std::thread( + // Place the new thread entity directly in the space where it goes to avoid + // any kind of races arising from asynchronous access to this space + m_state->m_thisThread.~thread(); + new (&m_state->m_thisThread) std::thread( [this, outstanding] () mutable { this->DoRun(std::move(outstanding)); } diff --git a/src/autowiring/CoreThreadWin.cpp b/src/autowiring/CoreThreadWin.cpp index 1f35cb5a6..05991b37d 100644 --- a/src/autowiring/CoreThreadWin.cpp +++ b/src/autowiring/CoreThreadWin.cpp @@ -41,7 +41,7 @@ void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName) } void BasicThread::SetCurrentThreadName(void) const { - DWORD threadId = ::GetThreadId(static_cast(m_state->m_thisThread.native_handle())); + DWORD threadId = ::GetThreadId(m_state->m_thisThread.native_handle()); ::SetThreadName(threadId, m_name); }