* commit '2b57981b05a3771bfce01e801581442e4b63299f': Switch init to epoll.
This commit is contained in:
commit
a81ee72c2e
8 changed files with 60 additions and 87 deletions
|
@ -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)();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue