summaryrefslogtreecommitdiffstats
path: root/init/init.cpp
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2015-04-24 21:13:44 -0700
committerElliott Hughes <enh@google.com>2015-04-24 21:13:44 -0700
commit929f4070767d1e4806c058849178afa13d9ded1e (patch)
treeac2368c66c572e1fb95406d8542605993fa68f6a /init/init.cpp
parentdf5d4482074fc68a25a6a33992f3fc5164c2d3ec (diff)
downloadsystem_core-929f4070767d1e4806c058849178afa13d9ded1e.zip
system_core-929f4070767d1e4806c058849178afa13d9ded1e.tar.gz
system_core-929f4070767d1e4806c058849178afa13d9ded1e.tar.bz2
Switch init to epoll.
Not just because it's what the cool kids are doing --- it also lets us simplify the inner loop and decouple it from whatever systems want to be woken to perform some activity if there's data to be read on some fd. Currently this is just used to clean up the existing signal handling, keychord, and property service code. Change-Id: I4d7541a2c4386957ad877df69e3be08b96a7dec5
Diffstat (limited to 'init/init.cpp')
-rw-r--r--init/init.cpp60
1 files changed, 25 insertions, 35 deletions
diff --git a/init/init.cpp b/init/init.cpp
index 4ed23b6..90cbea0 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -25,8 +25,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/epoll.h>
#include <sys/mount.h>
-#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -82,6 +82,17 @@ static const char *ENV[32];
bool waiting_for_exec = false;
+static int epoll_fd = -1;
+
+void register_epoll_handler(int fd, void (*fn)()) {
+ epoll_event ev;
+ ev.events = EPOLLIN;
+ ev.data.ptr = reinterpret_cast<void*>(fn);
+ if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
+ ERROR("epoll_ctl failed: %s\n", strerror(errno));
+ }
+}
+
void service::NotifyStateChange(const char* new_state) {
if (!properties_initialized()) {
// If properties aren't available yet, we can't set them.
@@ -1037,7 +1048,13 @@ int main(int argc, char** argv) {
restorecon("/dev/__properties__");
restorecon_recursive("/sys");
- signal_init();
+ epoll_fd = epoll_create1(EPOLL_CLOEXEC);
+ if (epoll_fd == -1) {
+ ERROR("epoll_create1 failed: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ signal_handler_init();
property_load_boot_defaults();
start_property_service();
@@ -1071,27 +1088,12 @@ int main(int argc, char** argv) {
// Run all property triggers based on current state of the properties.
queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");
- size_t fd_count = 0;
- struct pollfd ufds[3];
- ufds[fd_count++] = { .fd = get_signal_fd(), .events = POLLIN, .revents = 0 };
- ufds[fd_count++] = { .fd = get_property_set_fd(), .events = POLLIN, .revents = 0 };
- // TODO: can we work out when /dev/keychord is first accessible and open this fd then?
- bool keychord_fd_init = false;
-
while (true) {
if (!waiting_for_exec) {
execute_one_command();
restart_processes();
}
- if (!keychord_fd_init && get_keychord_fd() > 0) {
- ufds[fd_count].fd = get_keychord_fd();
- ufds[fd_count].events = POLLIN;
- ufds[fd_count].revents = 0;
- fd_count++;
- keychord_fd_init = true;
- }
-
int timeout = -1;
if (process_needs_restart) {
timeout = (process_needs_restart - gettime()) * 1000;
@@ -1105,24 +1107,12 @@ int main(int argc, char** argv) {
bootchart_sample(&timeout);
- int nr = TEMP_FAILURE_RETRY(poll(ufds, fd_count, timeout));
- if (nr <= 0) {
- if (nr == -1) {
- ERROR("poll failed: %s\n", strerror(errno));
- }
- continue;
- }
-
- for (size_t i = 0; i < fd_count; i++) {
- if (ufds[i].revents & POLLIN) {
- if (ufds[i].fd == get_property_set_fd()) {
- handle_property_set_fd();
- } else if (ufds[i].fd == get_keychord_fd()) {
- handle_keychord();
- } else if (ufds[i].fd == get_signal_fd()) {
- handle_signal();
- }
- }
+ epoll_event ev;
+ int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
+ if (nr == -1) {
+ ERROR("epoll_wait failed: %s\n", strerror(errno));
+ } else if (nr == 1) {
+ ((void (*)()) ev.data.ptr)();
}
}