diff options
| author | Tom Cherry <tomcherry@google.com> | 2018-05-01 13:39:52 -0700 |
|---|---|---|
| committer | Mark Salyzyn <salyzyn@google.com> | 2018-05-08 13:19:12 -0700 |
| commit | 8ae7375f020367bab2e99a0737d7f7bde69cddf9 (patch) | |
| tree | 9f184fb311ec513c206bcfcff37591bee83791bc /init/init.cpp | |
| parent | b004620f807984d898ae4c75660a220b9a4e20a3 (diff) | |
| download | system_core-8ae7375f020367bab2e99a0737d7f7bde69cddf9.tar.gz system_core-8ae7375f020367bab2e99a0737d7f7bde69cddf9.tar.bz2 system_core-8ae7375f020367bab2e99a0737d7f7bde69cddf9.zip | |
init: use std::function for epoll handling
Also allow unregistering of epoll handlers.
Bug: 64114943
Test: boot
Change-Id: I2abe6a56fd451839931d607dddb91669a7d02ff1
Diffstat (limited to 'init/init.cpp')
| -rw-r--r-- | init/init.cpp | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/init/init.cpp b/init/init.cpp index 0d5690b07..42032caeb 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -31,6 +31,10 @@ #include <sys/types.h> #include <unistd.h> +#include <map> +#include <memory> +#include <optional> + #include <android-base/chrono_utils.h> #include <android-base/file.h> #include <android-base/logging.h> @@ -43,9 +47,6 @@ #include <private/android_filesystem_config.h> #include <selinux/android.h> -#include <memory> -#include <optional> - #include "action_parser.h" #include "import_parser.h" #include "init_first_stage.h" @@ -130,12 +131,31 @@ static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_ } } -void register_epoll_handler(int fd, void (*fn)()) { +static std::map<int, std::function<void()>> epoll_handlers; + +void register_epoll_handler(int fd, std::function<void()> handler) { + auto[it, inserted] = epoll_handlers.emplace(fd, std::move(handler)); + if (!inserted) { + LOG(ERROR) << "Cannot specify two epoll handlers for a given FD"; + return; + } epoll_event ev; ev.events = EPOLLIN; - ev.data.ptr = reinterpret_cast<void*>(fn); + // std::map's iterators do not get invalidated until erased, so we use the pointer to the + // std::function in the map directly for epoll_ctl. + ev.data.ptr = reinterpret_cast<void*>(&it->second); if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) { - PLOG(ERROR) << "epoll_ctl failed"; + PLOG(ERROR) << "epoll_ctl failed to add fd"; + epoll_handlers.erase(fd); + } +} + +void unregister_epoll_handler(int fd) { + if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, nullptr) == -1) { + PLOG(ERROR) << "epoll_ctl failed to remove fd"; + } + if (epoll_handlers.erase(fd) != 1) { + LOG(ERROR) << "Attempting to remove epoll handler for FD without an existing handler"; } } @@ -809,7 +829,7 @@ int main(int argc, char** argv) { if (nr == -1) { PLOG(ERROR) << "epoll_wait failed"; } else if (nr == 1) { - ((void (*)()) ev.data.ptr)(); + std::invoke(*reinterpret_cast<std::function<void()>*>(ev.data.ptr)); } } |
