summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBob Foerster <robert@erafx.com>2010-11-26 16:15:36 -0500
committerChris Larson <chris_larson@mentor.com>2010-12-16 10:39:27 -0700
commit588d339f2bde8ab6547bc0c1c4e7b83310b1318f (patch)
tree06fdc72fbab138d806ab72b7800d3367edad8af5 /lib
parentbdd7813d8eecf7b6b636322e748ca6bf69118513 (diff)
downloadbitbake-588d339f2bde8ab6547bc0c1c4e7b83310b1318f.tar.gz
server: fix interrupt handling for process
SIGINT is now blocked within the server context, thus allowing the UI to fully handle all user interaction. There is no longer a need to check for KeyboardInterrupt Exceptions anywhere within the server context. Signed-off-by: Bob Foerster <robert@erafx.com> Signed-off-by: Chris Larson <chris_larson@mentor.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/bb/cooker.py15
-rw-r--r--lib/bb/event.py3
-rw-r--r--lib/bb/server/process.py64
3 files changed, 44 insertions, 38 deletions
diff --git a/lib/bb/cooker.py b/lib/bb/cooker.py
index 62c8d2803..ea362e2e2 100644
--- a/lib/bb/cooker.py
+++ b/lib/bb/cooker.py
@@ -104,6 +104,8 @@ class BBCooker:
self.command = bb.command.Command(self)
self.state = state.initial
+ self.parser = None
+
def parseConfiguration(self):
@@ -738,6 +740,10 @@ class BBCooker:
if self.state == state.running:
return
+ if self.state in (state.shutdown, state.stop):
+ self.parser.shutdown(clean=False)
+ sys.exit(1)
+
if self.state != state.parsing:
self.parseConfiguration ()
@@ -883,10 +889,9 @@ class BBCooker:
return self.appendlist[f]
return []
-
def shutdown(self):
self.state = state.shutdown
-
+
def stop(self):
self.state = state.stop
@@ -965,7 +970,7 @@ class CookerParser(object):
sync = threading.Thread(target=self.bb_cache.sync)
sync.start()
- atexit.register(lambda: sync.join())
+ multiprocessing.util.Finalize(None, sync.join, exitpriority=-100)
def load_cached(self):
for filename, appends in self.fromcache:
@@ -978,14 +983,10 @@ class CookerParser(object):
except StopIteration:
self.shutdown()
return False
- except KeyboardInterrupt:
- self.shutdown(clean=False)
- raise
except Exception as exc:
self.shutdown(clean=False)
bb.fatal('Error parsing %s: %s' % (exc.recipe, exc))
-
self.current += 1
self.virtuals += len(result)
if parsed:
diff --git a/lib/bb/event.py b/lib/bb/event.py
index 3f291ec27..647d02935 100644
--- a/lib/bb/event.py
+++ b/lib/bb/event.py
@@ -338,9 +338,10 @@ class CacheLoadProgress(Event):
class CacheLoadCompleted(Event):
"""Cache loading is complete"""
- def __init__(self, total):
+ def __init__(self, total, num_entries):
Event.__init__(self)
self.total = total
+ self.num_entries = num_entries
class DepTreeGenerated(Event):
diff --git a/lib/bb/server/process.py b/lib/bb/server/process.py
index 541c0c4d9..f3ad5da60 100644
--- a/lib/bb/server/process.py
+++ b/lib/bb/server/process.py
@@ -20,8 +20,9 @@
This module implements a multiprocessing.Process based server for bitbake.
"""
-import time
import logging
+import signal
+import time
import bb
import bb.event
from multiprocessing import Process, Event
@@ -29,31 +30,21 @@ from bb.cooker import BBCooker
logger = logging.getLogger('BitBake')
-
-class BitBakeServerCommands():
- def __init__(self, server, cooker):
- self.cooker = cooker
- self.server = server
+class ServerCommunicator():
+ def __init__(self, connection):
+ self.connection = connection
def runCommand(self, command):
- """
- Run a cooker command on the server
- """
- self.server.command_channel.send(self.cooker.command.runCommand(command))
+ # @todo try/except
+ self.connection.send(command)
- def terminateServer(self):
- """
- Trigger the server to quit
- """
- self.server.stop()
- #print "Server (cooker) exitting"
- return
-
- def ping(self):
- """
- Dummy method which can be used to check the server is still alive
- """
- return True
+ while True:
+ # don't let the user ctrl-c while we're waiting for a response
+ try:
+ result = self.connection.recv()
+ return result
+ except KeyboardInterrupt:
+ pass
class EventAdapter():
@@ -80,7 +71,6 @@ class ProcessServer(Process):
self.configuration = configuration
self.cooker = BBCooker(configuration, self.register_idle_function)
self._idlefunctions = {}
- self.commands = BitBakeServerCommands(self, self.cooker)
self.event_handle = bb.event.register_UIHhandler(self)
self.quit = False
@@ -99,12 +89,22 @@ class ProcessServer(Process):
# Ensure logging messages get sent to the UI as events
logger.addHandler(bb.event.LogHandler())
+ # Ignore SIGINT within the server, as all SIGINT handling is done by
+ # the UI and communicated to us
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
while self.keep_running.is_set():
- if self.command_channel.poll():
- command = self.command_channel.recv()
- self.commands.runCommand(command)
+ try:
+ if self.command_channel.poll():
+ command = self.command_channel.recv()
+ self.runCommand(command)
+
+ self.idle_commands(.1)
+ except Exception, exc:
+ logger.exception('Running command %s', command)
- self.idle_commands(.1)
+ self.event_queue.cancel_join_thread()
+ bb.event.unregister_UIHhandler(self.event_handle)
+ self.command_channel.close()
return
def idle_commands(self, delay):
@@ -129,7 +129,11 @@ class ProcessServer(Process):
if nextsleep is not None:
time.sleep(nextsleep)
+ def runCommand(self, command):
+ """
+ Run a cooker command on the server
+ """
+ self.command_channel.send(self.cooker.command.runCommand(command))
+
def stop(self):
self.keep_running.clear()
- bb.event.unregister_UIHhandler(self.event_handle)
- self.command_channel.close()