From 77ddcd5a3f0de96b6e14fe0dea9cc57e970ee858 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Thu, 23 Mar 2017 16:54:38 -0700 Subject: [PATCH] init: Prevent spin loop while waiting for exec or property Currently, when we are waiting for an exec service or a property, if there are either any services to be restarted or any more commands to be run, we set the epoll_timeout to handle these events. However, we don't actually restart and processes or execute any commands while waiting, so this essentially turns this waiting into a spin loop, particularly in the common case of having more commands to execute, where epoll_timeout is set to 0. The change only sets epoll_timeout if we're not waiting. Note that the only way to stop waiting for an exec service or a property is for a signal or property to be delivered to init, which happens through the epoll fds, so it's safe to indefinitely wait for epoll to return. Test: Boot bullhead Change-Id: Iae3b217eb28182038b464fd39df8e7d27b5e23ff --- init/init.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/init/init.cpp b/init/init.cpp index 0ce1c05d7..23448d609 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -1322,22 +1322,24 @@ int main(int argc, char** argv) { am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers"); while (true) { - if (!(waiting_for_exec || waiting_for_prop)) { - am.ExecuteOneCommand(); - restart_processes(); - } - // By default, sleep until something happens. int epoll_timeout_ms = -1; - // If there's a process that needs restarting, wake up in time for that. - if (process_needs_restart_at != 0) { - epoll_timeout_ms = (process_needs_restart_at - time(nullptr)) * 1000; - if (epoll_timeout_ms < 0) epoll_timeout_ms = 0; + if (!(waiting_for_exec || waiting_for_prop)) { + am.ExecuteOneCommand(); } + if (!(waiting_for_exec || waiting_for_prop)) { + restart_processes(); - // If there's more work to do, wake up again immediately. - if (am.HasMoreCommands()) epoll_timeout_ms = 0; + // If there's a process that needs restarting, wake up in time for that. + if (process_needs_restart_at != 0) { + epoll_timeout_ms = (process_needs_restart_at - time(nullptr)) * 1000; + if (epoll_timeout_ms < 0) epoll_timeout_ms = 0; + } + + // If there's more work to do, wake up again immediately. + if (am.HasMoreCommands()) epoll_timeout_ms = 0; + } epoll_event ev; int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms));