123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- #include "LinuxEvent.h"
- // 初始化静态成员
- std::mutex LinuxEvent::s_namedEventsMutex;
- std::unordered_map<std::string, std::weak_ptr<LinuxEvent>> LinuxEvent::s_namedEvents;
- std::atomic<uint64_t> 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<std::chrono::milliseconds>(
- 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<std::mutex> lock(m_mutex);
- if (m_fd != -1) {
- close(m_fd);
- m_fd = -1;
- }
-
- // 从命名事件映射中移除(仅当有名称时)
- if (!m_name.empty()) {
- std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<unsigned long>(-1)) ? -1 : static_cast<int>(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<std::mutex> 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<struct pollfd[]>(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<unsigned long>(-1)) ? -1 : static_cast<int>(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<std::shared_ptr<LinuxEvent>>& events, unsigned long timeoutMs) {
- int count = events.size();
- if (count <= 0) return -1;
- // 使用智能指针管理动态数组
- auto pfds = std::make_unique<struct pollfd[]>(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<unsigned long>(-1)) ? -1 : static_cast<int>(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<std::mutex> lock(events[i]->m_mutex);
- events[i]->m_state.store(false);
- }
- return i;
- }
- }
- return -1;
- }
- std::shared_ptr<LinuxEvent> LinuxEvent::CreateEvent(EventType type, bool initialState, const char* name) {
- auto event = std::make_shared<LinuxEvent>(type);
- event->m_name = name ? name : "";
- event->Initialize(initialState);
- if (!event->m_name.empty()) {
- std::lock_guard<std::mutex> lock(s_namedEventsMutex);
- s_namedEvents[event->m_name] = event;
- }
- return event;
- }
- std::shared_ptr<LinuxEvent> 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<std::mutex> 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<std::mutex> 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;
- }
|