Trying to learn windows internals and made my first work with Events and Threads. What do you think about my code? Any advicesadvice?
P.S. Sorry for my English
#include <windows.h> #include <iostream> #include <vector> enum class EventType : UINT8 { EVENT_TYPE_1, EVENT_TYPE_N }; using EventFnc = void (*)(void); struct Event { EventType type; EventFnc on_event_fnc; }; class Events { private: std::vector<Event> _events; std::vector<HANDLE> _handles; HANDLE events_changed_evt{INVALID_HANDLE_VALUE}; HANDLE events_dtor_evt{INVALID_HANDLE_VALUE}; HANDLE wait_event_thread_hwnd{INVALID_HANDLE_VALUE}; DWORD wait_event_thread_id{0}; private: static DWORD WINAPI _WaitEventThreadStatic(LPVOID param) { return ((Events *)param)->_WaitEventProc(); } DWORD WINAPI _WaitEventProc() { while (true) { DWORD event_index = WaitForMultipleObjects(_handles.size(), _handles.data(), FALSE, INFINITE); if (event_index == WAIT_FAILED) { throw std::runtime_error("WaitForMultipleObjects failed"); } event_index -= WAIT_OBJECT_0; switch (event_index) { case 0: /* events_changed_evt */ continue; case 1: /* events_dtor_evt */ return 0; default: /* user events */ SIZE_T idx = event_index - (_handles.size() - _events.size()); _events[idx].on_event_fnc(); break; } } return 0; } public: Events() { events_dtor_evt = ::CreateEventW(NULL, FALSE, FALSE, NULL); if (events_dtor_evt == NULL) { throw std::runtime_error("Failed to create event"); } events_changed_evt = ::CreateEventW(NULL, FALSE, FALSE, NULL); if (events_changed_evt == NULL) { throw std::runtime_error("Failed to create event"); } wait_event_thread_hwnd = ::CreateThread(NULL, 0, _WaitEventThreadStatic, (LPVOID)this, CREATE_SUSPENDED, &wait_event_thread_id); if (wait_event_thread_hwnd == NULL) { throw std::runtime_error("Failed to create thread"); } _handles.push_back(events_changed_evt); _handles.push_back(events_dtor_evt); if (::ResumeThread(wait_event_thread_hwnd) == (DWORD)-1) { throw std::runtime_error("Failed to resume thread"); } } ~Events() { ::SetEvent(events_dtor_evt); for (const auto hwnd : _handles) { ::CloseHandle(hwnd); } ::CloseHandle(wait_event_thread_hwnd); } Events(const Event &) = delete; Events(Event &&) = delete; Events &operator=(const Event &) = delete; Events &operator=(Event &&) = delete; public: SIZE_T AddEvent(const Event &event) { HANDLE hwnd = ::CreateEventW(NULL, FALSE, FALSE, NULL); if (hwnd == NULL) { throw std::runtime_error("Failed to create event"); } _events.push_back(event); _handles.push_back(hwnd); ::SetEvent(events_changed_evt); return _handles.size()-1; } bool TriggerEvent(SIZE_T event_id) const { if (event_id < _handles.size()) { ::SetEvent(_handles[event_id]); return true; } return false; } // bool TriggerEvent(EventType event_type) const // { // bool res{false}; // for (const auto &event : _events) // { // if (event.type == event_type) // { // ::SetEvent(_handles[event.id]); // res = true; // } // } // return res; // } }; void OnEvent(void){ std::cout << "Event 1"; } int APIENTRY main() { Events evts; SIZE_T id = evts.AddEvent({EventType::EVENT_TYPE_1,&OnEvent}); evts.TriggerEvent(id); while(true); return 0; } ```