init: Combine two if-statements
Combine two if-statements. This change is fine because:
* The code between the two if-statements does not queue actions.
* If an action is queued from another thread then WakeMainInitThread()
is called after the action has been queued.
Bug: 266255006
Change-Id: Id4b9565ff4fdb3ee2a2bbca316c8c78e0f2d38dd
Signed-off-by: Bart Van Assche <bvanassche@google.com>
diff --git a/init/init.cpp b/init/init.cpp
index c965fe6..05a8a9c 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -1109,8 +1109,11 @@
// Restore prio before main loop
setpriority(PRIO_PROCESS, 0, 0);
while (true) {
- // By default, sleep until something happens.
- std::optional<std::chrono::milliseconds> epoll_timeout;
+ // By default, sleep until something happens. Do not convert far_future into
+ // std::chrono::milliseconds because that would trigger an overflow. The unit of boot_clock
+ // is 1ns.
+ const boot_clock::time_point far_future = boot_clock::time_point::max();
+ boot_clock::time_point next_action_time = far_future;
auto shutdown_command = shutdown_state.CheckShutdown();
if (shutdown_command) {
@@ -1122,23 +1125,28 @@
if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) {
am.ExecuteOneCommand();
+ // If there's more work to do, wake up again immediately.
+ if (am.HasMoreCommands()) {
+ next_action_time = boot_clock::now();
+ }
}
+ // Since the above code examined pending actions, no new actions must be
+ // queued by the code between this line and the Epoll::Wait() call below
+ // without calling WakeMainInitThread().
if (!IsShuttingDown()) {
auto next_process_action_time = HandleProcessActions();
// If there's a process that needs restarting, wake up in time for that.
if (next_process_action_time) {
- epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(
- *next_process_action_time - boot_clock::now());
- if (epoll_timeout < 0ms) epoll_timeout = 0ms;
+ next_action_time = std::min(next_action_time, *next_process_action_time);
}
}
- if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) {
- // If there's more work to do, wake up again immediately.
- if (am.HasMoreCommands()) epoll_timeout = 0ms;
+ std::optional<std::chrono::milliseconds> epoll_timeout;
+ if (next_action_time != far_future) {
+ epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(
+ std::max(next_action_time - boot_clock::now(), 0ns));
}
-
auto epoll_result = epoll.Wait(epoll_timeout);
if (!epoll_result.ok()) {
LOG(ERROR) << epoll_result.error();