am 2899c94b: Merge "Switch init to epoll."

* commit '2899c94b9d962c308ef71ee10809c61ac39e0ce5':
  Switch init to epoll.
This commit is contained in:
Elliott Hughes 2015-04-25 05:10:59 +00:00 committed by Android Git Automerger
commit ae3154e396
8 changed files with 60 additions and 87 deletions

View file

@ -25,8 +25,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/epoll.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/poll.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
@ -82,6 +82,17 @@ static const char *ENV[32];
bool waiting_for_exec = false; 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) { void service::NotifyStateChange(const char* new_state) {
if (!properties_initialized()) { if (!properties_initialized()) {
// If properties aren't available yet, we can't set them. // 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("/dev/__properties__");
restorecon_recursive("/sys"); 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(); property_load_boot_defaults();
start_property_service(); start_property_service();
@ -1071,27 +1088,12 @@ int main(int argc, char** argv) {
// Run all property triggers based on current state of the properties. // Run all property triggers based on current state of the properties.
queue_builtin_action(queue_property_triggers_action, "queue_property_triggers"); 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) { while (true) {
if (!waiting_for_exec) { if (!waiting_for_exec) {
execute_one_command(); execute_one_command();
restart_processes(); 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; int timeout = -1;
if (process_needs_restart) { if (process_needs_restart) {
timeout = (process_needs_restart - gettime()) * 1000; timeout = (process_needs_restart - gettime()) * 1000;
@ -1105,24 +1107,12 @@ int main(int argc, char** argv) {
bootchart_sample(&timeout); bootchart_sample(&timeout);
int nr = TEMP_FAILURE_RETRY(poll(ufds, fd_count, timeout)); epoll_event ev;
if (nr <= 0) { int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
if (nr == -1) { if (nr == -1) {
ERROR("poll failed: %s\n", strerror(errno)); ERROR("epoll_wait failed: %s\n", strerror(errno));
} } else if (nr == 1) {
continue; ((void (*)()) ev.data.ptr)();
}
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();
}
}
} }
} }

View file

@ -155,4 +155,6 @@ int selinux_reload_policy(void);
void zap_stdio(void); void zap_stdio(void);
void register_epoll_handler(int fd, void (*fn)());
#endif /* _INIT_INIT_H */ #endif /* _INIT_INIT_H */

View file

@ -62,37 +62,7 @@ void add_service_keycodes(struct service *svc)
} }
} }
void keychord_init() static void handle_keychord() {
{
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()
{
struct service *svc; struct service *svc;
char adb_enabled[PROP_VALUE_MAX]; char adb_enabled[PROP_VALUE_MAX];
int ret; int ret;
@ -117,7 +87,28 @@ void handle_keychord()
} }
} }
int get_keychord_fd() void keychord_init() {
{ service_for_each(add_service_keycodes);
return keychord_fd;
// 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);
} }

View file

@ -19,9 +19,7 @@
struct service; struct service;
void add_service_keycodes(struct service *svc); void add_service_keycodes(service*);
void keychord_init(void); void keychord_init();
void handle_keychord(void);
int get_keychord_fd(void);
#endif #endif

View file

@ -246,7 +246,7 @@ int property_set(const char* name, const char* value) {
return rc; return rc;
} }
void handle_property_set_fd() static void handle_property_set_fd()
{ {
prop_msg msg; prop_msg msg;
int s; int s;
@ -527,8 +527,6 @@ void start_property_service() {
} }
listen(property_set_fd, 8); listen(property_set_fd, 8);
}
int get_property_set_fd() { register_epoll_handler(property_set_fd, handle_property_set_fd);
return property_set_fd;
} }

View file

@ -20,7 +20,6 @@
#include <stddef.h> #include <stddef.h>
#include <sys/system_properties.h> #include <sys/system_properties.h>
extern void handle_property_set_fd(void);
extern void property_init(void); extern void property_init(void);
extern void property_load_boot_defaults(void); extern void property_load_boot_defaults(void);
extern void load_persist_props(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_get(const char *name, char *value);
extern int property_set(const char *name, const char *value); extern int property_set(const char *name, const char *value);
extern bool properties_initialized(); extern bool properties_initialized();
int get_property_set_fd(void);
#ifndef __clang__ #ifndef __clang__
extern void __property_get_size_error() extern void __property_get_size_error()

View file

@ -147,7 +147,7 @@ static void reap_any_outstanding_children() {
} }
} }
void handle_signal() { static void handle_signal() {
// Clear outstanding requests. // Clear outstanding requests.
char buf[32]; char buf[32];
read(signal_read_fd, buf, sizeof(buf)); 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. // Create a signalling mechanism for SIGCHLD.
int s[2]; int s[2];
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, s) == -1) { if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, s) == -1) {
@ -180,8 +180,6 @@ void signal_init() {
sigaction(SIGCHLD, &act, 0); sigaction(SIGCHLD, &act, 0);
reap_any_outstanding_children(); reap_any_outstanding_children();
}
int get_signal_fd() { register_epoll_handler(signal_read_fd, handle_signal);
return signal_read_fd;
} }

View file

@ -17,8 +17,6 @@
#ifndef _INIT_SIGNAL_HANDLER_H_ #ifndef _INIT_SIGNAL_HANDLER_H_
#define _INIT_SIGNAL_HANDLER_H_ #define _INIT_SIGNAL_HANDLER_H_
void signal_init(void); void signal_handler_init(void);
void handle_signal(void);
int get_signal_fd(void);
#endif #endif