summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2015-04-25 05:21:43 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-04-25 05:21:43 +0000
commit2b57981b05a3771bfce01e801581442e4b63299f (patch)
tree93e0c415e060fb33b5617ee4c19d9b9d51491188 /init
parent52e5e55cac4e630e4eac59c387815aa307194540 (diff)
parentae3154e3968e991fb1e9a6b47bedd1e0819f7925 (diff)
downloadsystem_core-2b57981b05a3771bfce01e801581442e4b63299f.zip
system_core-2b57981b05a3771bfce01e801581442e4b63299f.tar.gz
system_core-2b57981b05a3771bfce01e801581442e4b63299f.tar.bz2
am ae3154e3: am 2899c94b: Merge "Switch init to epoll."
* commit 'ae3154e3968e991fb1e9a6b47bedd1e0819f7925': Switch init to epoll.
Diffstat (limited to 'init')
-rw-r--r--init/init.cpp60
-rw-r--r--init/init.h2
-rw-r--r--init/keychords.cpp59
-rw-r--r--init/keychords.h6
-rw-r--r--init/property_service.cpp6
-rw-r--r--init/property_service.h2
-rw-r--r--init/signal_handler.cpp8
-rw-r--r--init/signal_handler.h4
8 files changed, 60 insertions, 87 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)();
}
}
diff --git a/init/init.h b/init/init.h
index a104af6..1cabb14 100644
--- a/init/init.h
+++ b/init/init.h
@@ -155,4 +155,6 @@ int selinux_reload_policy(void);
void zap_stdio(void);
+void register_epoll_handler(int fd, void (*fn)());
+
#endif /* _INIT_INIT_H */
diff --git a/init/keychords.cpp b/init/keychords.cpp
index 27894a2..10d9573 100644
--- a/init/keychords.cpp
+++ b/init/keychords.cpp
@@ -62,37 +62,7 @@ void add_service_keycodes(struct service *svc)
}
}
-void keychord_init()
-{
- int fd, ret;
-
- service_for_each(add_service_keycodes);
-
- /* nothing to do if no services require keychords */
- if (!keychords)
- return;
-
- fd = open("/dev/keychord", O_RDWR | O_CLOEXEC);
- if (fd < 0) {
- ERROR("could not open /dev/keychord\n");
- return;
- }
-
- ret = write(fd, keychords, keychords_length);
- if (ret != keychords_length) {
- ERROR("could not configure /dev/keychord %d: %s\n", ret, strerror(errno));
- close(fd);
- fd = -1;
- }
-
- free(keychords);
- keychords = 0;
-
- keychord_fd = fd;
-}
-
-void handle_keychord()
-{
+static void handle_keychord() {
struct service *svc;
char adb_enabled[PROP_VALUE_MAX];
int ret;
@@ -117,7 +87,28 @@ void handle_keychord()
}
}
-int get_keychord_fd()
-{
- return keychord_fd;
+void keychord_init() {
+ service_for_each(add_service_keycodes);
+
+ // Nothing to do if no services require keychords.
+ if (!keychords) {
+ return;
+ }
+
+ keychord_fd = TEMP_FAILURE_RETRY(open("/dev/keychord", O_RDWR | O_CLOEXEC));
+ if (keychord_fd == -1) {
+ ERROR("could not open /dev/keychord: %s\n", strerror(errno));
+ return;
+ }
+
+ int ret = write(keychord_fd, keychords, keychords_length);
+ if (ret != keychords_length) {
+ ERROR("could not configure /dev/keychord %d: %s\n", ret, strerror(errno));
+ close(keychord_fd);
+ }
+
+ free(keychords);
+ keychords = nullptr;
+
+ register_epoll_handler(keychord_fd, handle_keychord);
}
diff --git a/init/keychords.h b/init/keychords.h
index 070b858..d2723b7 100644
--- a/init/keychords.h
+++ b/init/keychords.h
@@ -19,9 +19,7 @@
struct service;
-void add_service_keycodes(struct service *svc);
-void keychord_init(void);
-void handle_keychord(void);
-int get_keychord_fd(void);
+void add_service_keycodes(service*);
+void keychord_init();
#endif
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 94c5fd9..930ef82 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -246,7 +246,7 @@ int property_set(const char* name, const char* value) {
return rc;
}
-void handle_property_set_fd()
+static void handle_property_set_fd()
{
prop_msg msg;
int s;
@@ -527,8 +527,6 @@ void start_property_service() {
}
listen(property_set_fd, 8);
-}
-int get_property_set_fd() {
- return property_set_fd;
+ register_epoll_handler(property_set_fd, handle_property_set_fd);
}
diff --git a/init/property_service.h b/init/property_service.h
index 825a7dd..a27053d 100644
--- a/init/property_service.h
+++ b/init/property_service.h
@@ -20,7 +20,6 @@
#include <stddef.h>
#include <sys/system_properties.h>
-extern void handle_property_set_fd(void);
extern void property_init(void);
extern void property_load_boot_defaults(void);
extern void load_persist_props(void);
@@ -30,7 +29,6 @@ void get_property_workspace(int *fd, int *sz);
extern int __property_get(const char *name, char *value);
extern int property_set(const char *name, const char *value);
extern bool properties_initialized();
-int get_property_set_fd(void);
#ifndef __clang__
extern void __property_get_size_error()
diff --git a/init/signal_handler.cpp b/init/signal_handler.cpp
index 37d21bc..39a466d 100644
--- a/init/signal_handler.cpp
+++ b/init/signal_handler.cpp
@@ -147,7 +147,7 @@ static void reap_any_outstanding_children() {
}
}
-void handle_signal() {
+static void handle_signal() {
// Clear outstanding requests.
char buf[32];
read(signal_read_fd, buf, sizeof(buf));
@@ -161,7 +161,7 @@ static void SIGCHLD_handler(int) {
}
}
-void signal_init() {
+void signal_handler_init() {
// Create a signalling mechanism for SIGCHLD.
int s[2];
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, s) == -1) {
@@ -180,8 +180,6 @@ void signal_init() {
sigaction(SIGCHLD, &act, 0);
reap_any_outstanding_children();
-}
-int get_signal_fd() {
- return signal_read_fd;
+ register_epoll_handler(signal_read_fd, handle_signal);
}
diff --git a/init/signal_handler.h b/init/signal_handler.h
index b092ccb..449b4af 100644
--- a/init/signal_handler.h
+++ b/init/signal_handler.h
@@ -17,8 +17,6 @@
#ifndef _INIT_SIGNAL_HANDLER_H_
#define _INIT_SIGNAL_HANDLER_H_
-void signal_init(void);
-void handle_signal(void);
-int get_signal_fd(void);
+void signal_handler_init(void);
#endif