From 429905d4e893f91618908773166ba867970c9a17 Mon Sep 17 00:00:00 2001 From: Yuqian Yang Date: Tue, 9 Sep 2025 01:43:13 +0800 Subject: Implement SetPoll of event loop. --- include/cru/base/platform/unix/EventLoop.h | 7 ++++--- src/base/platform/unix/EventLoop.cpp | 25 +++++++++++++++++------ test/base/platform/unix/EventLoopTest.cpp | 32 +++++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 10 deletions(-) diff --git a/include/cru/base/platform/unix/EventLoop.h b/include/cru/base/platform/unix/EventLoop.h index 1fea6598..4f445fa3 100644 --- a/include/cru/base/platform/unix/EventLoop.h +++ b/include/cru/base/platform/unix/EventLoop.h @@ -47,8 +47,9 @@ class UnixTimerFile : public Object2 { class UnixEventLoop : public Object2 { CRU_DEFINE_CLASS_LOG_TAG("cru::platform::unix::UnixEventLoop") public: - using PollHandler = - std::function().revents) revent)>; + using PollEvents = decltype(std::declval().events); + using PollRevents = decltype(std::declval().revents); + using PollHandler = std::function; UnixEventLoop(); @@ -79,7 +80,7 @@ class UnixEventLoop : public Object2 { return this->SetTimer(std::move(action), std::move(interval), true); } - void AddPoll(int fd, PollHandler action); + void SetPoll(int fd, PollEvents events, PollHandler action); void RemovePoll(int fd); private: diff --git a/src/base/platform/unix/EventLoop.cpp b/src/base/platform/unix/EventLoop.cpp index 53c54866..7c475697 100644 --- a/src/base/platform/unix/EventLoop.cpp +++ b/src/base/platform/unix/EventLoop.cpp @@ -1,5 +1,4 @@ #include "cru/base/platform/unix/EventLoop.h" -#include "cru/base/Base.h" #include "cru/base/Exception.h" #include @@ -174,16 +173,30 @@ bool UnixEventLoop::CheckActionPipe() { return true; } -void UnixEventLoop::AddPoll(int fd, PollHandler action) { - for (const auto &poll_fd : polls_) { +void UnixEventLoop::SetPoll(int fd, PollEvents events, PollHandler action) { + for (auto &poll_fd : polls_) { if (poll_fd.fd == fd) { - throw Exception("The file descriptor is already in poll list."); + poll_fd.events = events; + return; } } - NotImplemented(); + pollfd poll_fd; + poll_fd.fd = fd; + poll_fd.events = events; + poll_fd.revents = 0; + polls_.push_back(poll_fd); + poll_actions_.push_back(std::move(action)); } -void UnixEventLoop::RemovePoll(int fd) { NotImplemented(); } +void UnixEventLoop::RemovePoll(int fd) { + auto iter = std::ranges::find_if( + polls_, [fd](const pollfd &poll_fd) { return poll_fd.fd == fd; }); + if (iter != polls_.cend()) { + auto index = iter - polls_.cbegin(); + polls_.erase(iter); + poll_actions_.erase(poll_actions_.cbegin() + index); + } +} } // namespace cru::platform::unix diff --git a/test/base/platform/unix/EventLoopTest.cpp b/test/base/platform/unix/EventLoopTest.cpp index 5d4dbcf2..3a9e3281 100644 --- a/test/base/platform/unix/EventLoopTest.cpp +++ b/test/base/platform/unix/EventLoopTest.cpp @@ -25,7 +25,7 @@ TEST_CASE("UnixTimerFile Work", "[unix][time]") { REQUIRE(delay < std::chrono::milliseconds(500)); } -TEST_CASE("UnixEventLoop Work", "[unix][time]") { +TEST_CASE("UnixEventLoop Timer Work", "[unix][time]") { using namespace cru; using namespace cru::platform::unix; @@ -78,3 +78,33 @@ TEST_CASE("UnixEventLoop Work", "[unix][time]") { REQUIRE(exit_code == 0); REQUIRE(counter == 2); } + +TEST_CASE("UnixEventLoop Poll Work", "[unix][time]") { + using namespace cru; + using namespace cru::platform::unix; + + UnixEventLoop loop; + + auto test_pipe = OpenUniDirectionalPipe(); + + bool triggered = false; + + loop.SetPoll(test_pipe.read, POLLIN, [&loop, &triggered](auto revent) { + REQUIRE(revent & POLLIN); + REQUIRE(!triggered); + triggered = true; + loop.RequestQuit(); + }); + + loop.SetTimeout( + [&test_pipe] { + auto buffer = ""; + test_pipe.write.Write(buffer, 1); + }, + std::chrono::milliseconds(300)); + + auto exit_code = loop.Run(); + + REQUIRE(exit_code == 0); + REQUIRE(triggered); +} -- cgit v1.2.3