Add handle abstractions

This commit is contained in:
momo5502 2022-09-11 09:24:27 +02:00
parent 038ab2a4bb
commit b3377fc092
3 changed files with 91 additions and 16 deletions

View File

@ -102,6 +102,69 @@ namespace utils::nt
HMODULE module_;
};
template <HANDLE InvalidHandle = nullptr>
class handle
{
public:
handle() = default;
handle(const HANDLE h)
: handle_(h)
{
}
~handle()
{
if (*this)
{
CloseHandle(this->handle_);
this->handle_ = InvalidHandle;
}
}
handle(const handle&) = delete;
handle& operator=(const handle&) = delete;
handle(handle&& obj) noexcept
: handle()
{
this->operator=(std::move(obj));
}
handle& operator=(handle&& obj) noexcept
{
if (this != &obj)
{
this->~handle();
this->handle_ = obj.handle_;
obj.handle_ = InvalidHandle;
}
return *this;
}
handle& operator=(HANDLE h) noexcept
{
this->~handle();
this->handle_ = h;
return *this;
}
operator bool() const
{
return this->handle_ != InvalidHandle;
}
operator HANDLE() const
{
return this->handle_;
}
private:
HANDLE handle_{InvalidHandle};
};
__declspec(noreturn) void raise_hard_exception();
std::string load_resource(int id);

View File

@ -48,17 +48,12 @@ namespace utils::thread
std::vector<DWORD> get_thread_ids()
{
auto* const h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId());
if (h == INVALID_HANDLE_VALUE)
nt::handle<INVALID_HANDLE_VALUE> h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId());
if (!h)
{
return {};
}
const auto _ = utils::finally([h]()
{
CloseHandle(h);
});
THREADENTRY32 entry{};
entry.dwSize = sizeof(entry);
if (!Thread32First(h, &entry))
@ -84,20 +79,15 @@ namespace utils::thread
return ids;
}
void for_each_thread(const std::function<void(HANDLE)>& callback)
void for_each_thread(const std::function<void(HANDLE)>& callback, const DWORD access)
{
const auto ids = get_thread_ids();
for (const auto& id : ids)
{
auto* const thread = OpenThread(THREAD_ALL_ACCESS, FALSE, id);
if (thread != nullptr)
handle thread(id, access);
if (thread)
{
const auto _ = utils::finally([thread]()
{
CloseHandle(thread);
});
callback(thread);
}
}

View File

@ -17,8 +17,30 @@ namespace utils::thread
return t;
}
class handle
{
public:
handle(const DWORD thread_id, const DWORD access = THREAD_ALL_ACCESS)
: handle_(OpenThread(access, FALSE, thread_id))
{
}
operator bool() const
{
return this->handle_;
}
operator HANDLE() const
{
return this->handle_;
}
private:
nt::handle<> handle_{};
};
std::vector<DWORD> get_thread_ids();
void for_each_thread(const std::function<void(HANDLE)>& callback);
void for_each_thread(const std::function<void(HANDLE)>& callback, DWORD access = THREAD_ALL_ACCESS);
void suspend_other_threads();
void resume_other_threads();