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