65 lines
2.4 KiB
C++
65 lines
2.4 KiB
C++
#include "port/poller.h"
|
|
#include <windows.h>
|
|
#include <stdexcept>
|
|
|
|
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<HANDLE> 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<DWORD>(timeoutMs);
|
|
DWORD rc = WaitForMultipleObjects(static_cast<DWORD>(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<int>(handles.size())) {
|
|
auto& obj = objects[idx];
|
|
obj->revents = 1; // простая метка, что событие произошло
|
|
}
|
|
}
|
|
|
|
poller::PollWrapper::~PollWrapper() = default;
|