1 //===-- HostThreadWindows.cpp -----------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Utility/Status.h" 10 11 #include "lldb/Host/windows/HostThreadWindows.h" 12 #include "lldb/Host/windows/windows.h" 13 14 #include "llvm/ADT/STLExtras.h" 15 16 using namespace lldb; 17 using namespace lldb_private; 18 19 namespace { 20 void __stdcall ExitThreadProxy(ULONG_PTR dwExitCode) { 21 ::ExitThread(dwExitCode); 22 } 23 } 24 25 HostThreadWindows::HostThreadWindows() 26 : HostNativeThreadBase(), m_owns_handle(true) {} 27 28 HostThreadWindows::HostThreadWindows(lldb::thread_t thread) 29 : HostNativeThreadBase(thread), m_owns_handle(true) {} 30 31 HostThreadWindows::~HostThreadWindows() { Reset(); } 32 33 void HostThreadWindows::SetOwnsHandle(bool owns) { m_owns_handle = owns; } 34 35 Status HostThreadWindows::Join(lldb::thread_result_t *result) { 36 Status error; 37 if (IsJoinable()) { 38 DWORD wait_result = ::WaitForSingleObject(m_thread, INFINITE); 39 if (WAIT_OBJECT_0 == wait_result && result) { 40 DWORD exit_code = 0; 41 if (!::GetExitCodeThread(m_thread, &exit_code)) 42 *result = 0; 43 *result = exit_code; 44 } else if (WAIT_OBJECT_0 != wait_result) 45 error.SetError(::GetLastError(), eErrorTypeWin32); 46 } else 47 error.SetError(ERROR_INVALID_HANDLE, eErrorTypeWin32); 48 49 Reset(); 50 return error; 51 } 52 53 Status HostThreadWindows::Cancel() { 54 Status error; 55 56 DWORD result = ::QueueUserAPC(::ExitThreadProxy, m_thread, 0); 57 error.SetError(result, eErrorTypeWin32); 58 return error; 59 } 60 61 lldb::tid_t HostThreadWindows::GetThreadId() const { 62 return ::GetThreadId(m_thread); 63 } 64 65 void HostThreadWindows::Reset() { 66 if (m_owns_handle && m_thread != LLDB_INVALID_HOST_THREAD) 67 ::CloseHandle(m_thread); 68 69 HostNativeThreadBase::Reset(); 70 } 71 72 bool HostThreadWindows::EqualsThread(lldb::thread_t thread) const { 73 return GetThreadId() == ::GetThreadId(thread); 74 } 75