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/HostThreadWindows.h"
13 #include "lldb/Host/windows/windows.h"
14 
15 #include "llvm/ADT/STLExtras.h"
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 
20 namespace {
21 void __stdcall ExitThreadProxy(ULONG_PTR dwExitCode) {
22   ::ExitThread(dwExitCode);
23 }
24 }
25 
26 HostThreadWindows::HostThreadWindows()
27     : HostNativeThreadBase(), m_owns_handle(true) {}
28 
29 HostThreadWindows::HostThreadWindows(lldb::thread_t thread)
30     : HostNativeThreadBase(thread), m_owns_handle(true) {}
31 
32 HostThreadWindows::~HostThreadWindows() { Reset(); }
33 
34 void HostThreadWindows::SetOwnsHandle(bool owns) { m_owns_handle = owns; }
35 
36 Error HostThreadWindows::Join(lldb::thread_result_t *result) {
37   Error error;
38   if (IsJoinable()) {
39     DWORD wait_result = ::WaitForSingleObject(m_thread, INFINITE);
40     if (WAIT_OBJECT_0 == wait_result && result) {
41       DWORD exit_code = 0;
42       if (!::GetExitCodeThread(m_thread, &exit_code))
43         *result = 0;
44       *result = exit_code;
45     } else if (WAIT_OBJECT_0 != wait_result)
46       error.SetError(::GetLastError(), eErrorTypeWin32);
47   } else
48     error.SetError(ERROR_INVALID_HANDLE, eErrorTypeWin32);
49 
50   Reset();
51   return error;
52 }
53 
54 Error HostThreadWindows::Cancel() {
55   Error error;
56 
57   DWORD result = ::QueueUserAPC(::ExitThreadProxy, m_thread, 0);
58   error.SetError(result, eErrorTypeWin32);
59   return error;
60 }
61 
62 lldb::tid_t HostThreadWindows::GetThreadId() const {
63   return ::GetThreadId(m_thread);
64 }
65 
66 void HostThreadWindows::Reset() {
67   if (m_owns_handle && m_thread != LLDB_INVALID_HOST_THREAD)
68     ::CloseHandle(m_thread);
69 
70   HostNativeThreadBase::Reset();
71 }
72