EventLoop.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // EventLoop.cpp - 事件循环实现
  2. #include "pch.h"
  3. #include "EventLoop.h"
  4. #include "Logger.h"
  5. namespace commkit {
  6. EventLoop::EventLoop() {}
  7. EventLoop::~EventLoop() {
  8. Stop();
  9. }
  10. bool EventLoop::Start(HANDLE driver_handle, TOnData callback) {
  11. if (running_.load()) {
  12. return true;
  13. }
  14. if (driver_handle == INVALID_HANDLE_VALUE || !callback) {
  15. LOG_ERROR("EventLoop::Start invalid args");
  16. return false;
  17. }
  18. driver_handle_ = driver_handle;
  19. callback_ = callback;
  20. running_.store(true);
  21. try {
  22. thread_ = std::thread(&EventLoop::Run, this);
  23. } catch (const std::exception& e) {
  24. LOG_ERROR(std::string("EventLoop thread create failed: ") + e.what());
  25. running_.store(false);
  26. return false;
  27. }
  28. LOG_INFO("EventLoop started");
  29. return true;
  30. }
  31. void EventLoop::Stop() {
  32. if (!running_.exchange(false)) {
  33. return;
  34. }
  35. // 关闭驱动句柄会阻塞的 ReadEvents 立即返回错误
  36. // 此处仅设置标志,由 Run() 循环自行退出
  37. // 注意:不能在此处 CloseHandle(driver_handle_),因为 Run() 可能正在使用
  38. if (thread_.joinable()) {
  39. thread_.join();
  40. }
  41. LOG_INFO("EventLoop stopped");
  42. }
  43. void EventLoop::Run() {
  44. // 批量读取缓冲区:单次最多 COMMKIT_EVENT_BATCH 条事件
  45. COMMKIT_EVENT batch[COMMKIT_EVENT_BATCH];
  46. while (running_.load()) {
  47. DWORD returned = 0;
  48. // 阻塞式 IOCTL:驱动在无事件时会让 IRP pending
  49. // 当驱动有事件或被取消时返回
  50. BOOL ok = DeviceIoControl(
  51. driver_handle_,
  52. IOCTL_COMMKIT_READ_EVENTS,
  53. nullptr, 0,
  54. batch, sizeof(batch),
  55. &returned,
  56. nullptr);
  57. if (!running_.load()) {
  58. break;
  59. }
  60. if (!ok) {
  61. DWORD err = ::GetLastError();
  62. // 驱动关闭或句柄无效时退出循环
  63. if (err == ERROR_INVALID_HANDLE || err == ERROR_OPERATION_ABORTED) {
  64. LOG_WARNING("EventLoop Run: driver handle closed, exiting");
  65. break;
  66. }
  67. // 其他错误:短暂 sleep 后重试,避免空转
  68. LOG_ERROR("EventLoop Run: DeviceIoControl failed, error=" + std::to_string(err));
  69. std::this_thread::sleep_for(std::chrono::milliseconds(50));
  70. continue;
  71. }
  72. // 处理返回的事件
  73. DWORD count = returned / sizeof(COMMKIT_EVENT);
  74. for (DWORD i = 0; i < count; ++i) {
  75. const COMMKIT_EVENT& e = batch[i];
  76. if (callback_) {
  77. // 调用用户注册的回调
  78. // TimeStamp 是 100ns 单位,转换为 double(用户可根据需要自行处理)
  79. double timestamp = static_cast<double>(e.TimeStamp);
  80. callback_(e.Sequence, timestamp, e.ComNumber,
  81. e.EventType, e.DataSize,
  82. const_cast<char*>(e.Data));
  83. }
  84. }
  85. // 无事件时短暂 sleep,避免忙循环占满 CPU(驱动当前实现是立即返回而非 pending IRP)
  86. if (count == 0) {
  87. std::this_thread::sleep_for(std::chrono::milliseconds(50));
  88. }
  89. }
  90. }
  91. } // namespace commkit