From 990d43cb82ed95cf16d5bfb688cfc39b29defd8b Mon Sep 17 00:00:00 2001 From: Tao Wu Date: Thu, 26 Oct 2017 10:43:10 -0700 Subject: [PATCH] Fix one race condition between start and stop. For a oneshot service, if start happens immediately after stop, the service could be still in stopping status and then start won't do anything. This fix this race condition. Test: manual - see reproduce instructions in bug. Bug: 68020256 Change-Id: I20202fa346f1949a8bda3d90deedc8b6a6d814d3 --- init/service.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/init/service.cpp b/init/service.cpp index 765b61e56..889df6366 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -706,14 +706,20 @@ Result Service::ExecStart() { } Result Service::Start() { + bool disabled = (flags_ & (SVC_DISABLED | SVC_RESET)); // Starting a service removes it from the disabled or reset state and // immediately takes it out of the restarting state if it was in there. flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START)); // Running processes require no additional work --- if they're in the // process of exiting, we've ensured that they will immediately restart - // on exit, unless they are ONESHOT. + // on exit, unless they are ONESHOT. For ONESHOT service, if it's in + // stopping status, we just set SVC_RESTART flag so it will get restarted + // in Reap(). if (flags_ & SVC_RUNNING) { + if ((flags_ & SVC_ONESHOT) && disabled) { + flags_ |= SVC_RESTART; + } // It is not an error to try to start a service that is already running. return Success(); }