Skip to main content
deleted 27 characters in body
toolic
  • 11.1k
  • 4
  • 25
  • 156

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; } ```

Trying to learn windows internals and made my first work with Events and Threads. What do you think about my code? Any advices?

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; } ```

Trying to learn windows internals and made my first work with Events and Threads. What do you think about my code? Any advice?

#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; } 

Simple WinAPI Event manager implementation

Trying to learn windows internals and made my first work with Events and Threads. What do you think about my code? Any advices?

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; } ```
close