1dda28197Spatrick //===-- HostThreadWindows.cpp ---------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "lldb/Utility/Status.h"
10061da546Spatrick
11061da546Spatrick #include "lldb/Host/windows/HostThreadWindows.h"
12061da546Spatrick #include "lldb/Host/windows/windows.h"
13061da546Spatrick
14061da546Spatrick #include "llvm/ADT/STLExtras.h"
15061da546Spatrick
16061da546Spatrick using namespace lldb;
17061da546Spatrick using namespace lldb_private;
18061da546Spatrick
ExitThreadProxy(ULONG_PTR dwExitCode)19*f6aab3d8Srobert static void __stdcall ExitThreadProxy(ULONG_PTR dwExitCode) {
20061da546Spatrick ::ExitThread(dwExitCode);
21061da546Spatrick }
22061da546Spatrick
HostThreadWindows()23061da546Spatrick HostThreadWindows::HostThreadWindows()
24061da546Spatrick : HostNativeThreadBase(), m_owns_handle(true) {}
25061da546Spatrick
HostThreadWindows(lldb::thread_t thread)26061da546Spatrick HostThreadWindows::HostThreadWindows(lldb::thread_t thread)
27061da546Spatrick : HostNativeThreadBase(thread), m_owns_handle(true) {}
28061da546Spatrick
~HostThreadWindows()29061da546Spatrick HostThreadWindows::~HostThreadWindows() { Reset(); }
30061da546Spatrick
SetOwnsHandle(bool owns)31061da546Spatrick void HostThreadWindows::SetOwnsHandle(bool owns) { m_owns_handle = owns; }
32061da546Spatrick
Join(lldb::thread_result_t * result)33061da546Spatrick Status HostThreadWindows::Join(lldb::thread_result_t *result) {
34061da546Spatrick Status error;
35061da546Spatrick if (IsJoinable()) {
36061da546Spatrick DWORD wait_result = ::WaitForSingleObject(m_thread, INFINITE);
37061da546Spatrick if (WAIT_OBJECT_0 == wait_result && result) {
38061da546Spatrick DWORD exit_code = 0;
39061da546Spatrick if (!::GetExitCodeThread(m_thread, &exit_code))
40061da546Spatrick *result = 0;
41061da546Spatrick *result = exit_code;
42061da546Spatrick } else if (WAIT_OBJECT_0 != wait_result)
43061da546Spatrick error.SetError(::GetLastError(), eErrorTypeWin32);
44061da546Spatrick } else
45061da546Spatrick error.SetError(ERROR_INVALID_HANDLE, eErrorTypeWin32);
46061da546Spatrick
47061da546Spatrick Reset();
48061da546Spatrick return error;
49061da546Spatrick }
50061da546Spatrick
Cancel()51061da546Spatrick Status HostThreadWindows::Cancel() {
52061da546Spatrick Status error;
53061da546Spatrick
54061da546Spatrick DWORD result = ::QueueUserAPC(::ExitThreadProxy, m_thread, 0);
55061da546Spatrick error.SetError(result, eErrorTypeWin32);
56061da546Spatrick return error;
57061da546Spatrick }
58061da546Spatrick
GetThreadId() const59061da546Spatrick lldb::tid_t HostThreadWindows::GetThreadId() const {
60061da546Spatrick return ::GetThreadId(m_thread);
61061da546Spatrick }
62061da546Spatrick
Reset()63061da546Spatrick void HostThreadWindows::Reset() {
64061da546Spatrick if (m_owns_handle && m_thread != LLDB_INVALID_HOST_THREAD)
65061da546Spatrick ::CloseHandle(m_thread);
66061da546Spatrick
67061da546Spatrick HostNativeThreadBase::Reset();
68061da546Spatrick }
69061da546Spatrick
EqualsThread(lldb::thread_t thread) const70061da546Spatrick bool HostThreadWindows::EqualsThread(lldb::thread_t thread) const {
71061da546Spatrick return GetThreadId() == ::GetThreadId(thread);
72061da546Spatrick }
73