]> code.ossystems Code Review - openembedded-core.git/commitdiff
Queue up events before the UI is spawned
authorChris Larson <chris_larson@mentor.com>
Tue, 28 Sep 2010 15:24:55 +0000 (08:24 -0700)
committerRichard Purdie <rpurdie@linux.intel.com>
Tue, 4 Jan 2011 14:46:37 +0000 (14:46 +0000)
- Queue up any events fired to the UI before the UI exists
- At exit, check if UIs exist, and if not, flush the queue of LogRecords to
  the console directly.
- When establishing a connection from the UI to the server, flush the queue of
  events to the queue in the server connection, so the UI will receive them
  when it begins its event loop.

(Bitbake rev: 73488aeb317ed306f2ecf99cc9d3708526a5933c)

Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
bitbake/lib/bb/cooker.py
bitbake/lib/bb/event.py
bitbake/lib/bb/server/none.py
bitbake/lib/bb/server/xmlrpc.py

index c1e2105c5e8ba0ea2189f6c9585bd71a3c59fcda..7adda09fdedff9f6968a40f763d7e2cdab4b19d9 100644 (file)
@@ -494,69 +494,71 @@ class BBCooker:
             path, _ = os.path.split(path)
 
     def parseConfigurationFiles(self, files):
-        try:
-            data = self.configuration.data
-
-            bb.parse.init_parser(data, self.configuration.dump_signatures)
-            for f in files:
-                data = bb.parse.handle(f, data)
+        def _parse(f, data):
+            try:
+                return bb.parse.handle(f, data)
+            except (IOError, bb.parse.ParseError) as exc:
+                parselog.critical("Unable to parse %s: %s" % (f, exc))
+                sys.exit(1)
+        data = self.configuration.data
 
-            layerconf = self._findLayerConf()
-            if layerconf:
-                parselog.debug(2, "Found bblayers.conf (%s)", layerconf)
-                data = bb.parse.handle(layerconf, data)
+        bb.parse.init_parser(data, self.configuration.dump_signatures)
+        for f in files:
+            data = _parse(f, data)
 
-                layers = (bb.data.getVar('BBLAYERS', data, True) or "").split()
+        layerconf = self._findLayerConf()
+        if layerconf:
+            parselog.debug(2, "Found bblayers.conf (%s)", layerconf)
+            data = _parse(layerconf, data)
 
-                data = bb.data.createCopy(data)
-                for layer in layers:
-                    parselog.debug(2, "Adding layer %s", layer)
-                    bb.data.setVar('LAYERDIR', layer, data)
-                    data = bb.parse.handle(os.path.join(layer, "conf", "layer.conf"), data)
+            layers = (bb.data.getVar('BBLAYERS', data, True) or "").split()
 
-                    # XXX: Hack, relies on the local keys of the datasmart
-                    # instance being stored in the 'dict' attribute and makes
-                    # assumptions about how variable expansion works, but
-                    # there's no better way to force an expansion of a single
-                    # variable across the datastore today, and this at least
-                    # lets us reference LAYERDIR without having to immediately
-                    # eval all our variables that use it.
-                    for key in data.dict:
-                        if key != "_data":
-                            value = data.getVar(key, False)
-                            if value and "${LAYERDIR}" in value:
-                                data.setVar(key, value.replace("${LAYERDIR}", layer))
+            data = bb.data.createCopy(data)
+            for layer in layers:
+                parselog.debug(2, "Adding layer %s", layer)
+                bb.data.setVar('LAYERDIR', layer, data)
+                data = _parse(os.path.join(layer, "conf", "layer.conf"), data)
 
-                bb.data.delVar('LAYERDIR', data)
+                # XXX: Hack, relies on the local keys of the datasmart
+                # instance being stored in the 'dict' attribute and makes
+                # assumptions about how variable expansion works, but
+                # there's no better way to force an expansion of a single
+                # variable across the datastore today, and this at least
+                # lets us reference LAYERDIR without having to immediately
+                # eval all our variables that use it.
+                for key in data.dict:
+                    if key != "_data":
+                        value = data.getVar(key, False)
+                        if value and "${LAYERDIR}" in value:
+                            data.setVar(key, value.replace("${LAYERDIR}", layer))
 
-            if not data.getVar("BBPATH", True):
-                raise SystemExit("The BBPATH variable is not set")
+            bb.data.delVar('LAYERDIR', data)
 
-            data = bb.parse.handle(os.path.join("conf", "bitbake.conf"), data)
+        if not data.getVar("BBPATH", True):
+            raise SystemExit("The BBPATH variable is not set")
 
-            self.configuration.data = data
+        data = _parse(os.path.join("conf", "bitbake.conf"), data)
 
-            # Handle any INHERITs and inherit the base class
-            inherits  = ["base"] + (bb.data.getVar('INHERIT', self.configuration.data, True ) or "").split()
-            for inherit in inherits:
-                self.configuration.data = bb.parse.handle(os.path.join('classes', '%s.bbclass' % inherit), self.configuration.data, True )
+        self.configuration.data = data
 
-            # Nomally we only register event handlers at the end of parsing .bb files
-            # We register any handlers we've found so far here...
-            for var in bb.data.getVar('__BBHANDLERS', self.configuration.data) or []:
-                bb.event.register(var, bb.data.getVar(var, self.configuration.data))
+        # Handle any INHERITs and inherit the base class
+        inherits  = ["base"] + (bb.data.getVar('INHERIT', self.configuration.data, True ) or "").split()
+        for inherit in inherits:
+            self.configuration.data = _parse(os.path.join('classes', '%s.bbclass' % inherit), self.configuration.data, True )
 
-            if bb.data.getVar("BB_WORKERCONTEXT", self.configuration.data) is None:
-                bb.fetch.fetcher_init(self.configuration.data)
-            bb.codeparser.parser_cache_init(self.configuration.data)
+        # Nomally we only register event handlers at the end of parsing .bb files
+        # We register any handlers we've found so far here...
+        for var in bb.data.getVar('__BBHANDLERS', self.configuration.data) or []:
+            bb.event.register(var, bb.data.getVar(var, self.configuration.data))
 
-            bb.parse.init_parser(data, self.configuration.dump_signatures)
+        if bb.data.getVar("BB_WORKERCONTEXT", self.configuration.data) is None:
+            bb.fetch.fetcher_init(self.configuration.data)
+        bb.codeparser.parser_cache_init(self.configuration.data)
 
-            bb.event.fire(bb.event.ConfigParsed(), self.configuration.data)
+        bb.parse.init_parser(data, self.configuration.dump_signatures)
 
-        except (IOError, bb.parse.ParseError):
-            parselog.exception("Error when parsing %s", files)
-            sys.exit(1)
+        bb.event.fire(bb.event.ConfigParsed(), self.configuration.data)
 
     def handleCollections( self, collections ):
         """Handle collections"""
@@ -899,7 +901,7 @@ class BBCooker:
             if not base in self.appendlist:
                self.appendlist[base] = []
             self.appendlist[base].append(f)
+
         return (bbfiles, masked)
 
     def get_file_appends(self, fn):
@@ -909,7 +911,7 @@ class BBCooker:
         """
         f = os.path.basename(fn)
         if f in self.appendlist:
-            return self.appendlist[f] 
+            return self.appendlist[f]
         return []
 
     def pre_serve(self):
index f3efae9bdf844037cdc868741de22cb5da32e18d..fb355089a326371511d171e2f2a6b76b23be7718 100644 (file)
@@ -26,6 +26,7 @@ import os, sys
 import warnings
 import pickle
 import logging
+import atexit
 import bb.utils
 
 # This is the pid for which we should generate the event. This is set when
@@ -74,7 +75,27 @@ def fire_class_handlers(event, d):
             h(event)
         del event.data
 
+ui_queue = []
+@atexit.register
+def print_ui_queue():
+    """If we're exiting before a UI has been spawned, display any queued
+    LogRecords to the console."""
+    logger = logging.getLogger("BitBake")
+    if not _ui_handlers:
+        console = logging.StreamHandler(sys.stdout)
+        console.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
+        logger.handlers = [console]
+        while ui_queue:
+            event, d = ui_queue.pop()
+            if isinstance(event, logging.LogRecord):
+                logger.handle(event)
+
 def fire_ui_handlers(event, d):
+    if not _ui_handlers:
+        # No UI handlers registered yet, queue up the messages
+        ui_queue.append((event, d))
+        return
+
     errors = []
     for h in _ui_handlers:
         #print "Sending event %s" % event
index dafb2feba9d38224f696b910ff28a86a77a53412..2708807dfcf6957b3555831a568e5918dc0d8690 100644 (file)
@@ -174,6 +174,8 @@ class BitBakeServerConnection():
         self.server = serverinfo.server
         self.connection = serverinfo.commands
         self.events = bb.server.none.BBUIEventQueue(self.server)
+        for event in bb.event.ui_queue:
+            self.events.queue_event(event)
 
     def terminate(self):
         try:
index c2bfe121764be684411d5c679980bd9e15a1367a..0d03e308d0ff753672fb6a18a7f3098b4fb23407 100644 (file)
@@ -243,6 +243,8 @@ class BitBakeServerConnection():
         t = BBTransport()
         self.connection = xmlrpclib.Server("http://%s:%s" % (serverinfo.host, serverinfo.port), transport=t, allow_none=True)
         self.events = uievent.BBUIEventQueue(self.connection)
+        for event in bb.event.ui_queue:
+            self.events.queue_event(event)
 
     def terminate(self):
         # Don't wait for server indefinitely