#include "port/poller.h" #include #include bool poller::PollObject::isPollIn() const { return revents != 0; } bool poller::PollObject::isPollOut() const { return true; } // для Windows драйверов обычно всегда можно писать bool poller::PollObject::isPollHup() const { // UART: проверка ClearCommError if (hCom != INVALID_HANDLE_VALUE) { DWORD errors; if (!ClearCommError(hCom, &errors, nullptr)) { DWORD err = GetLastError(); if (err == ERROR_INVALID_HANDLE || err == ERROR_FILE_NOT_FOUND) return true; // COM порт физически пропал } if (errors & CE_RXOVER) return true; // overflow тоже можно трактовать как проблему } // UDP: проверка ошибки сокета через SO_ERROR if (sock != INVALID_SOCKET) { int err = 0; int len = sizeof(err); if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*)&err, &len) == 0) { if (err != 0) return true; // есть ошибка на сокете } } return false; } poller::PollObject::~PollObject() = default; poller::PollWrapper::PollWrapper() = default; void poller::PollWrapper::loop(int timeoutMs) { // собираем все события std::vector handles; for (auto& obj : objects) { #ifdef _WIN32 if (!obj) continue; // UART HANDLE или UDP событие if (obj->winHandle) handles.push_back(obj->winHandle); #endif } if (handles.empty()) return; DWORD waitTime = (timeoutMs < 0) ? INFINITE : static_cast(timeoutMs); DWORD rc = WaitForMultipleObjects(static_cast(handles.size()), handles.data(), FALSE, // ждем любого события waitTime); if (rc == WAIT_FAILED) throw std::runtime_error("WaitForMultipleObjects failed"); // Определяем, какой объект сработал int idx = rc - WAIT_OBJECT_0; if (idx >= 0 && idx < static_cast(handles.size())) { auto& obj = objects[idx]; obj->revents = 1; // простая метка, что событие произошло } } poller::PollWrapper::~PollWrapper() = default;