Use std::shared_ptr in Epoll's callback list.
Ignore-AOSP-First: Awaiting security triage
Bug: 187862380
Bug: 190126442
Test: CtsInitTestCases
Change-Id: Ibb34a6b8a5675dbc515b7f8a43d7eecf2084510c
(cherry picked from commit aea97815308ab98faf1599c16d6190b787d34941)
diff --git a/init/epoll.cpp b/init/epoll.cpp
index 17d63fa..74d8aac 100644
--- a/init/epoll.cpp
+++ b/init/epoll.cpp
@@ -38,11 +38,12 @@
return {};
}
-Result<void> Epoll::RegisterHandler(int fd, std::function<void()> handler, uint32_t events) {
+Result<void> Epoll::RegisterHandler(int fd, Handler handler, uint32_t events) {
if (!events) {
return Error() << "Must specify events";
}
- auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(handler));
+ auto sp = std::make_shared<decltype(handler)>(std::move(handler));
+ auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(sp));
if (!inserted) {
return Error() << "Cannot specify two epoll handlers for a given FD";
}
@@ -69,7 +70,7 @@
return {};
}
-Result<std::vector<std::function<void()>*>> Epoll::Wait(
+Result<std::vector<std::shared_ptr<Epoll::Handler>>> Epoll::Wait(
std::optional<std::chrono::milliseconds> timeout) {
int timeout_ms = -1;
if (timeout && timeout->count() < INT_MAX) {
@@ -81,9 +82,10 @@
if (num_events == -1) {
return ErrnoError() << "epoll_wait failed";
}
- std::vector<std::function<void()>*> pending_functions;
+ std::vector<std::shared_ptr<Handler>> pending_functions;
for (int i = 0; i < num_events; ++i) {
- pending_functions.emplace_back(reinterpret_cast<std::function<void()>*>(ev[i].data.ptr));
+ auto sp = *reinterpret_cast<std::shared_ptr<Handler>*>(ev[i].data.ptr);
+ pending_functions.emplace_back(std::move(sp));
}
return pending_functions;