#include "LinuxEvent.h" // 初始化静态成员 std::mutex LinuxEvent::s_namedEventsMutex; std::unordered_map> LinuxEvent::s_namedEvents; std::atomic LinuxEvent::s_objectCounter(0); std::string LinuxEvent::getCurrentTimestamp() const { auto now = std::chrono::system_clock::now(); auto in_time_t = std::chrono::system_clock::to_time_t(now); auto ms = std::chrono::duration_cast( now.time_since_epoch()) % 1000; std::stringstream ss; ss << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %H:%M:%S") << '.' << std::setfill('0') << std::setw(3) << ms.count(); return ss.str(); } std::string LinuxEvent::getLogPrefix() const { std::stringstream ss; ss << "[" << getCurrentTimestamp() << "][Event#" << m_objectId; if (!m_name.empty()) ss << ":" << m_name; ss << "][FD:" << m_fd << "] "; return ss.str(); } LinuxEvent::LinuxEvent(EventType type) : m_type(type), m_state(false), m_objectId(s_objectCounter.fetch_add(1, std::memory_order_relaxed)) { m_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); if (m_fd == -1) { throw std::system_error(errno, std::system_category(), "eventfd creation failed"); } } LinuxEvent::~LinuxEvent() { m_destructing.store(true); std::lock_guard lock(m_mutex); if (m_fd != -1) { close(m_fd); m_fd = -1; } // 从命名事件映射中移除(仅当有名称时) if (!m_name.empty()) { std::lock_guard lock(s_namedEventsMutex); auto it = s_namedEvents.find(m_name); if (it != s_namedEvents.end() && it->second.expired()) { s_namedEvents.erase(it); } } } void LinuxEvent::Initialize(bool initialState) { /*std::cout << getLogPrefix() << "Initialize. Initial state: " << initialState << std::endl;*/ if (initialState) { // 直接操作 eventfd,不通过 SetEvent() const uint64_t value = 1; ssize_t result = write(m_fd, &value, sizeof(value)); if (result != sizeof(value)) { throw std::system_error(errno, std::system_category(), "eventfd initial write failed"); } m_state.store(true); } } void LinuxEvent::SetEvent() { if (this == nullptr) { // 关键空指针检查 std::cerr << "[CRITICAL] SetEvent called with NULL pointer!" << std::endl; return; } auto self = shared_from_this(); std::lock_guard lock(m_mutex); // 检查析构状态 if (m_destructing.load()) { std::cerr << getLogPrefix() << "SetEvent ABORTED: Object is being destroyed" << std::endl; return; } const uint64_t value = 1; ssize_t result = write(m_fd, &value, sizeof(value)); if (result == -1 && errno != EAGAIN) { throw std::system_error(errno, std::system_category(), "eventfd write failed"); } m_state.store(true); } void LinuxEvent::ResetEvent() { auto self = shared_from_this(); std::lock_guard lock(m_mutex); if (m_destructing.load()) { std::cerr << getLogPrefix() << "ResetEvent ABORTED: Object is being destroyed" << std::endl; return; } uint64_t value; while (read(m_fd, &value, sizeof(value)) == sizeof(value)); m_state.store(false); } bool LinuxEvent::IsSet() const { std::lock_guard lock(m_mutex); return m_state; } int LinuxEvent::GetFD() const { return m_fd; } bool LinuxEvent::Wait(unsigned long timeoutMs) { auto self = shared_from_this(); if (m_destructing.load() || m_fd == -1) { return false; } struct pollfd pfd = { .fd = m_fd, .events = POLLIN }; int timeout = (timeoutMs == static_cast(-1)) ? -1 : static_cast(timeoutMs); int ready, retry = 0; do { ready = poll(&pfd, 1, timeout); if (ready == -1 && errno == EINTR && retry < 5) { retry++; continue; } break; } while (true); if (ready <= 0) { return false; // 超时或错误 } // 自动重置类型需要读取事件 if (m_type == AUTO_RESET) { std::lock_guard lock(m_mutex); uint64_t value; if (read(m_fd, &value, sizeof(value)) == sizeof(value)) { m_state.store(false); } } return true; } int LinuxEvent::WaitForMultipleEvents(LinuxEvent** events, int count, unsigned long timeoutMs) { if (count <= 0 || !events) return -1; // 使用智能指针管理动态数组 auto pfds = std::make_unique(count); for (int i = 0; i < count; ++i) { if (!events[i]) return -1; pfds[i] = { .fd = events[i]->GetFD(), .events = POLLIN }; } int timeout = (timeoutMs == static_cast(-1)) ? -1 : static_cast(timeoutMs); int ready = poll(pfds.get(), count, timeout); if (ready <= 0) return -1; // 返回第一个就绪的事件索引 for (int i = 0; i < count; ++i) { if (pfds[i].revents & POLLIN) { if (events[i]->m_type == AUTO_RESET) { uint64_t value; read(events[i]->GetFD(), &value, sizeof(value)); // 重置事件 events[i]->m_state.store(false); } return i; } } return -1; } int LinuxEvent::WaitForMultipleEvents(std::vector>& events, unsigned long timeoutMs) { int count = events.size(); if (count <= 0) return -1; // 使用智能指针管理动态数组 auto pfds = std::make_unique(count); for (int i = 0; i < count; ++i) { if (!events[i]) return -1; if (events[i]->m_destructing.load()) { return -1; } pfds[i] = { .fd = events[i]->GetFD(), .events = POLLIN }; } int timeout = (timeoutMs == static_cast(-1)) ? -1 : static_cast(timeoutMs); int ready = poll(pfds.get(), count, timeout); if (ready <= 0) return -1; for (int i = 0; i < count; ++i) { if (pfds[i].revents & POLLIN) { if (events[i]->m_type == AUTO_RESET) { uint64_t value; read(events[i]->GetFD(), &value, sizeof(value)); // 重置事件 std::lock_guard lock(events[i]->m_mutex); events[i]->m_state.store(false); } return i; } } return -1; } std::shared_ptr LinuxEvent::CreateEvent(EventType type, bool initialState, const char* name) { auto event = std::make_shared(type); event->m_name = name ? name : ""; event->Initialize(initialState); if (!event->m_name.empty()) { std::lock_guard lock(s_namedEventsMutex); s_namedEvents[event->m_name] = event; } return event; } std::shared_ptr LinuxEvent::OpenEvent(const char* name, bool inheritHandle) { if (name == nullptr || *name == '\0') { std::cerr << "OpenEvent: Invalid event name" << std::endl; throw std::invalid_argument("Invalid event name"); } CleanupNamedEvents(); std::string eventName(name); std::lock_guard lock(s_namedEventsMutex); auto it = s_namedEvents.find(eventName); if (it == s_namedEvents.end()) { return nullptr; // 未找到 } if (auto event = it->second.lock()) { return event; } // 弱引用已过期,从映射中移除 s_namedEvents.erase(it); return nullptr; } void LinuxEvent::CleanupNamedEvents() { std::lock_guard lock(s_namedEventsMutex); size_t count = 0; for (auto it = s_namedEvents.begin(); it != s_namedEvents.end(); ) { if (it->second.expired()) { it = s_namedEvents.erase(it); count++; } else { ++it; } } std::cout << "CleanupNamedEvents: Removed " << count << " expired events" << std::endl; }