aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuqian Yang <crupest@crupest.life>2025-09-09 01:43:13 +0800
committerYuqian Yang <crupest@crupest.life>2025-09-09 01:43:13 +0800
commit429905d4e893f91618908773166ba867970c9a17 (patch)
treef87fc7a6ed6ce345a6795d059426d9a60f50c3c3
parent37d9a034013b4245a50c0d748dc83d2c3d136210 (diff)
downloadcru-429905d4e893f91618908773166ba867970c9a17.tar.gz
cru-429905d4e893f91618908773166ba867970c9a17.tar.bz2
cru-429905d4e893f91618908773166ba867970c9a17.zip
Implement SetPoll of event loop.
-rw-r--r--include/cru/base/platform/unix/EventLoop.h7
-rw-r--r--src/base/platform/unix/EventLoop.cpp25
-rw-r--r--test/base/platform/unix/EventLoopTest.cpp32
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<void(decltype(std::declval<pollfd>().revents) revent)>;
+ using PollEvents = decltype(std::declval<pollfd>().events);
+ using PollRevents = decltype(std::declval<pollfd>().revents);
+ using PollHandler = std::function<void(PollEvents revent)>;
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 <poll.h>
@@ -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);
+}