All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Purdie <richard.purdie@linuxfoundation.org>
To: bitbake-devel <bitbake-devel@lists.openembedded.org>
Subject: [PATCH] process: Improve exit handling and hangs
Date: Sat, 24 Aug 2013 13:07:20 +0100	[thread overview]
Message-ID: <1377346040.6762.186.camel@ted> (raw)

It turns out we have a number of different ways the process server termination can
hang. If we call cancel_join_thread() on the event queue, it means that it can be left
containing partial data. This means the reading of the event queue in the terminate()
function can hang, the timeout and block parameters to Queue.get() don't make any
difference.

Equally, if we don't call cancel_join_thread(), the join_thread in terminate()
will hang giving a different deadlock.

The best solution I could find is to loop over the process is_alive() after requesting
it stops,  trying to join the thread and if that fails, try and flush the event
queue again.

It wasn't clear what difference a force option should make in this case, we're
gracefully trying to empty queues and shut down regardless of whether its a SIGTERM
so I've simply removed the force option.

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---

Jason: Not sure if this or the other patch will help the hang you are
seeing or not but they seem like good changes regardless and fix real
world issues.

diff --git a/bitbake/lib/bb/server/process.py b/bitbake/lib/bb/server/process.py
index 0d4a26c..99a6bf5 100644
--- a/bitbake/lib/bb/server/process.py
+++ b/bitbake/lib/bb/server/process.py
@@ -105,7 +105,7 @@ class ProcessServer(Process, BaseImplServer):
             except Exception:
                 logger.exception('Running command %s', command)
 
-        self.event_queue.cancel_join_thread()
+        self.event_queue.close()
         bb.event.unregister_UIHhandler(self.event_handle)
         self.command_channel.close()
         self.cooker.stop()
@@ -150,27 +150,25 @@ class BitBakeProcessServerConnection(BitBakeBaseServerConnection):
         self.connection = ServerCommunicator(self.ui_channel)
         self.events = self.event_queue
 
-    def terminate(self, force = False):
+    def terminate(self):
+        def flushevents():
+            while True:
+                try:
+                    event = self.event_queue.get(block=False)
+                except (Empty, IOError):
+                    break
+                if isinstance(event, logging.LogRecord):
+                    logger.handle(event)
+
         signal.signal(signal.SIGINT, signal.SIG_IGN)
         self.procserver.stop()
-        if force:
-            self.procserver.join(0.5)
-            if self.procserver.is_alive():
-                self.procserver.terminate()
-                self.procserver.join()
-        else:
-            self.procserver.join()
-        while True:
-            try:
-                event = self.event_queue.get(block=False)
-            except (Empty, IOError):
-                break
-            if isinstance(event, logging.LogRecord):
-                logger.handle(event)
+
+        while self.procserver.is_alive():
+            flushevents()
+            self.procserver.join(0.1)
+
         self.ui_channel.close()
         self.event_queue.close()
-        if force:
-            sys.exit(1)
 
 # Wrap Queue to provide API which isn't server implementation specific
 class ProcessEventQueue(multiprocessing.queues.Queue):
@@ -203,5 +201,5 @@ class BitBakeServer(BitBakeBaseServer):
 
     def establishConnection(self):
         self.connection = BitBakeProcessServerConnection(self.serverImpl, self.ui_channel, self.event_queue)
-        signal.signal(signal.SIGTERM, lambda i, s: self.connection.terminate(force=True))
+        signal.signal(signal.SIGTERM, lambda i, s: self.connection.terminate())
         return self.connection




             reply	other threads:[~2013-08-24 12:07 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-24 12:07 Richard Purdie [this message]
2013-08-24 12:40 ` [PATCH] process: Improve exit handling and hangs Richard Purdie
2013-08-27 20:11 ` Jason Wessel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1377346040.6762.186.camel@ted \
    --to=richard.purdie@linuxfoundation.org \
    --cc=bitbake-devel@lists.openembedded.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.