1 //===-- HostThreadWindows.cpp -----------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Core/Error.h" 11 12 #include "lldb/Host/windows/windows.h" 13 #include "lldb/Host/windows/HostThreadWindows.h" 14 15 #include "llvm/ADT/STLExtras.h" 16 17 using namespace lldb; 18 using namespace lldb_private; 19 20 namespace 21 { 22 void __stdcall ExitThreadProxy(ULONG_PTR dwExitCode) 23 { 24 ::ExitThread(dwExitCode); 25 } 26 } 27 28 HostThreadWindows::HostThreadWindows() 29 : HostNativeThreadBase() 30 , m_owns_handle(true) 31 { 32 } 33 34 HostThreadWindows::HostThreadWindows(lldb::thread_t thread) 35 : HostNativeThreadBase(thread) 36 , m_owns_handle(true) 37 { 38 } 39 40 HostThreadWindows::~HostThreadWindows() 41 { 42 Reset(); 43 } 44 45 void 46 HostThreadWindows::SetOwnsHandle(bool owns) 47 { 48 m_owns_handle = owns; 49 } 50 51 Error 52 HostThreadWindows::Join(lldb::thread_result_t *result) 53 { 54 Error error; 55 if (IsJoinable()) 56 { 57 DWORD wait_result = ::WaitForSingleObject(m_thread, INFINITE); 58 if (WAIT_OBJECT_0 == wait_result && result) 59 { 60 DWORD exit_code = 0; 61 if (!::GetExitCodeThread(m_thread, &exit_code)) 62 *result = 0; 63 *result = exit_code; 64 } 65 else if (WAIT_OBJECT_0 != wait_result) 66 error.SetError(::GetLastError(), eErrorTypeWin32); 67 } 68 else 69 error.SetError(ERROR_INVALID_HANDLE, eErrorTypeWin32); 70 71 Reset (); 72 return error; 73 } 74 75 Error 76 HostThreadWindows::Cancel() 77 { 78 Error error; 79 80 DWORD result = ::QueueUserAPC(::ExitThreadProxy, m_thread, 0); 81 error.SetError(result, eErrorTypeWin32); 82 return error; 83 } 84 85 lldb::tid_t 86 HostThreadWindows::GetThreadId() const 87 { 88 return ::GetThreadId(m_thread); 89 } 90 91 void 92 HostThreadWindows::Reset() 93 { 94 if (m_owns_handle && m_thread != LLDB_INVALID_HOST_THREAD) 95 ::CloseHandle(m_thread); 96 97 HostNativeThreadBase::Reset(); 98 } 99