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.SetError(::err: GetLastError(), type: eErrorTypeWin32); |
44 | } else |
45 | error.SetError(err: ERROR_INVALID_HANDLE, type: 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.SetError(err: result, type: 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 | |