@@ -149,7 +149,7 @@  class BBCooker:
     Manages one bitbake build run
     """
 
-    def __init__(self, featureSet=None, idleCallBackRegister=None):
+    def __init__(self, featureSet=None, idleCallBackRegister=None, waitIdle=None):
         self.recipecaches = None
         self.eventlog = None
         self.skiplist = {}
@@ -164,6 +164,7 @@  class BBCooker:
         self.configuration = bb.cookerdata.CookerConfiguration()
 
         self.idleCallBackRegister = idleCallBackRegister
+        self.waitIdle = waitIdle
 
         bb.debug(1, "BBCooker starting %s" % time.time())
         sys.stdout.flush()
@@ -1753,7 +1754,7 @@  class BBCooker:
         return
 
     def post_serve(self):
-        self.shutdown(force=True)
+        self.shutdown(force=True, idle=False)
         prserv.serv.auto_shutdown()
         if hasattr(bb.parse, "siggen"):
             bb.parse.siggen.exit()
@@ -1763,12 +1764,15 @@  class BBCooker:
         if hasattr(self, "data"):
             bb.event.fire(CookerExit(), self.data)
 
-    def shutdown(self, force = False):
+    def shutdown(self, force=False, idle=True):
         if force:
             self.state = state.forceshutdown
         else:
             self.state = state.shutdown
 
+        if idle:
+            self.waitIdle(30)
+
         if self.parser:
             self.parser.shutdown(clean=not force)
             self.parser.final_cleanup()
@@ -150,6 +150,11 @@  class ProcessServer():
 
         return ret
 
+    def wait_for_idle(self, timeout=30):
+        # Wait for the idle loop to have cleared (30s max)
+        self.is_idle.clear()
+        self.is_idle.wait(timeout=timeout)
+
     def main(self):
         self.cooker.pre_serve()
 
@@ -174,8 +179,7 @@  class ProcessServer():
                 self.controllersock = False
             if self.haveui:
                 # Wait for the idle loop to have cleared (30s max)
-                self.is_idle.clear()
-                self.is_idle.wait(timeout=30)
+                self.wait_for_idle(30)
                 if self.cooker.command.currentAsyncCommand is not None:
                     serverlog("Idle loop didn't finish queued commands after 30s, exiting.")
                     self.quit = True
@@ -309,7 +313,7 @@  class ProcessServer():
         self.sock.close()
 
         try:
-            self.cooker.shutdown(True)
+            self.cooker.shutdown(True, idle=False)
             self.cooker.notifier.stop()
             self.cooker.confignotifier.stop()
         except:
@@ -607,7 +611,7 @@  def execServer(lockfd, readypipeinfd, lockname, sockname, server_timeout, xmlrpc
         writer = ConnectionWriter(readypipeinfd)
         try:
             featureset = []
-            cooker = bb.cooker.BBCooker(featureset, server.register_idle_function)
+            cooker = bb.cooker.BBCooker(featureset, server.register_idle_function, server.wait_for_idle)
             cooker.configuration.profile = profile
         except bb.BBHandledException:
             return None
 
  
When the cooker shutdown method is called, ensure we clean up any active idle handlers before we exit as these could have trees of processes in them and these need to be notified and reaped. Ensure at actual shutdown when the idle loop has been terminated we don't trigger the idle loop call though as it will no longer be active at that point. Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> --- lib/bb/cooker.py | 10 +++++++--- lib/bb/server/process.py | 12 ++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-)