diff options
Diffstat (limited to 'network/netadaptercx/netvadapterlibrary/code/rtl/KWaitEvent.h')
| -rw-r--r-- | network/netadaptercx/netvadapterlibrary/code/rtl/KWaitEvent.h | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/network/netadaptercx/netvadapterlibrary/code/rtl/KWaitEvent.h b/network/netadaptercx/netvadapterlibrary/code/rtl/KWaitEvent.h new file mode 100644 index 00000000..124f416e --- /dev/null +++ b/network/netadaptercx/netvadapterlibrary/code/rtl/KWaitEvent.h @@ -0,0 +1,172 @@ +// Copyright (C) Microsoft Corporation. All rights reserved. +#pragma once + +#include <KMacros.h> + +#if _KERNEL_MODE +typedef wistd::integral_constant<EVENT_TYPE, SynchronizationEvent> auto_reset_event_t; +#else +typedef wistd::integral_constant<bool, false> auto_reset_event_t; +#endif + +#if _KERNEL_MODE +typedef wistd::integral_constant<EVENT_TYPE, NotificationEvent> manual_reset_event_t; +#else +typedef wistd::integral_constant<bool, true> manual_reset_event_t; +#endif + +#define WIN_VERIFY NT_VERIFY +#define WIN_ASSERT NT_ASSERT + +template<typename TEventType> +class KWaitEventBase +{ +public: + + KWaitEventBase() = default; + +#ifdef _KERNEL_MODE + NONPAGED ~KWaitEventBase() = default; +#else + NONPAGED ~KWaitEventBase() + { + WIN_ASSERT(m_event == nullptr); + } +#endif + + KWaitEventBase(KWaitEventBase &) = delete; + KWaitEventBase(KWaitEventBase &&) = delete; + KWaitEventBase & operator=(KWaitEventBase &) = delete; + KWaitEventBase & operator=(KWaitEventBase &&) = delete; + + _IRQL_requires_max_(DISPATCH_LEVEL) void Set() + { +#if _KERNEL_MODE + KeSetEvent(&m_event, 0, false); +#else + WIN_VERIFY(SetEvent(m_event)); +#endif + } + + _IRQL_requires_max_(DISPATCH_LEVEL) void Clear() + { +#if _KERNEL_MODE + KeClearEvent(&m_event); +#else + WIN_VERIFY(ResetEvent(m_event)); +#endif + } + + PAGED void Wait() + { +#if _KERNEL_MODE + // Not used at runtime, but might be useful during debugging + volatile LARGE_INTEGER SystemTime; + KeQuerySystemTime(const_cast<LARGE_INTEGER*>(&SystemTime)); + + NTSTATUS NtStatus = KeWaitForSingleObject( + &m_event, Executive, KernelMode, FALSE, nullptr); + NT_VERIFY(NtStatus == STATUS_SUCCESS); +#else + ULONG r = WaitForSingleObject(m_event, INFINITE); + WIN_VERIFY(r == NO_ERROR); +#endif + } + + PAGED bool Test() + { +#if _KERNEL_MODE + return !!KeReadStateEvent(&m_event); +#else + ULONG r = WaitForSingleObject(m_event, 0); + WIN_VERIFY(r == WAIT_TIMEOUT || r == WAIT_OBJECT_0); + return (r == WAIT_OBJECT_0); +#endif + } + + NONPAGED bool TestNP() + { +#if _KERNEL_MODE + return !!KeReadStateEvent(&m_event); +#else + ULONG r = WaitForSingleObject(m_event, 0); + WIN_VERIFY(r == WAIT_TIMEOUT || r == WAIT_OBJECT_0); + return (r == WAIT_OBJECT_0); +#endif + } + +protected: + + PAGED void InitializeBase() + { +#if _KERNEL_MODE + KeInitializeEvent(&m_event, TEventType(), FALSE); +#else + m_event = CreateEventW(nullptr, TEventType(), false, nullptr); + WIN_VERIFY(m_event); +#endif + } + + NONPAGED void CleanupBase() + { +#ifndef _KERNEL_MODE + CloseHandle(m_event); + m_event = nullptr; +#endif + } + +private: + +#if _KERNEL_MODE + KEVENT m_event; +#else + HANDLE m_event; +#endif + +}; + +class KWaitEvent : public KWaitEventBase<manual_reset_event_t> +{ +public: + + PAGED KWaitEvent() noexcept + { + InitializeBase(); + } + + NONPAGED ~KWaitEvent() + { + CleanupBase(); + } +}; + +class KWaitEventManualConstruct : public KWaitEventBase<manual_reset_event_t> +{ +public: + + PAGED void Initialize() + { + InitializeBase(); + } + + PAGED void Cleanup() + { + CleanupBase(); + } +}; + + +class KAutoEvent : public KWaitEventBase<auto_reset_event_t> +{ +public: + + PAGED KAutoEvent() noexcept + { + InitializeBase(); + } + + NONPAGED ~KAutoEvent() + { + CleanupBase(); + } +}; |
