]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
bitbake: hashserv: Switch from threads to multiprocessing
authorRichard Purdie <richard.purdie@linuxfoundation.org>
Wed, 31 Jul 2019 09:49:39 +0000 (10:49 +0100)
committerRichard Purdie <richard.purdie@linuxfoundation.org>
Tue, 6 Aug 2019 10:21:32 +0000 (11:21 +0100)
There were hard to debug lockups when trying to use threading to start
hashserv as a thread. Switch to multiprocessing which doesn't show the
same locking problems.

(Bitbake rev: be23d887c8e244f1ef961298fbc9214d0fd0968a)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
bitbake/lib/bb/cooker.py
bitbake/lib/hashserv/__init__.py
bitbake/lib/hashserv/tests.py

index 84f25ec94ebed5d2f14804a52474f04428872cc0..6e1d59bb3a628f4d434fce3d9501ba0092277755 100644 (file)
@@ -193,6 +193,8 @@ class BBCooker:
         bb.parse.BBHandler.cached_statements = {}
 
         self.ui_cmdline = None
+        self.hashserv = None
+        self.hashservport = None
 
         self.initConfigurationData()
 
@@ -231,8 +233,6 @@ class BBCooker:
         self.state = state.initial
 
         self.parser = None
-        self.hashserv = None
-        self.hashservport = None
 
         signal.signal(signal.SIGTERM, self.sigterm_exception)
         # Let SIGHUP exit as SIGTERM
@@ -372,12 +372,13 @@ class BBCooker:
         self.data.setVar('BB_CMDLINE', self.ui_cmdline)
 
         if self.data.getVar("BB_HASHSERVE") == "localhost:0":
-            dbfile = (self.data.getVar("PERSISTENT_DIR") or self.data.getVar("CACHE")) + "/hashserv.db"
-            self.hashserv = hashserv.create_server(('localhost', 0), dbfile, '')
-            self.hashservport = "localhost:" + str(self.hashserv.server_port)
-            thread = threading.Thread(target=self.hashserv.serve_forever)
-            thread.daemon = True
-            thread.start()
+            if not self.hashserv:
+                dbfile = (self.data.getVar("PERSISTENT_DIR") or self.data.getVar("CACHE")) + "/hashserv.db"
+                self.hashserv = hashserv.create_server(('localhost', 0), dbfile, '')
+                self.hashservport = "localhost:" + str(self.hashserv.server_port)
+                self.hashserv.process = multiprocessing.Process(target=self.hashserv.serve_forever)
+                self.hashserv.process.daemon = True
+                self.hashserv.process.start()
             self.data.setVar("BB_HASHSERVE", self.hashservport)
 
         #
@@ -1658,7 +1659,8 @@ class BBCooker:
     def post_serve(self):
         prserv.serv.auto_shutdown()
         if self.hashserv:
-            self.hashserv.shutdown()
+            self.hashserv.process.terminate()
+            self.hashserv.process.join()
         bb.event.fire(CookerExit(), self.data)
 
     def shutdown(self, force = False):
index 86aa7e9de629276747d6f99df6c3d6647ba75efc..1d5e08ee5a89264cc1761e73a04a67bdc2344548 100644 (file)
@@ -13,6 +13,7 @@ import logging
 import socketserver
 import queue
 import threading
+import signal
 from datetime import datetime
 
 logger = logging.getLogger('hashserv')
@@ -147,8 +148,14 @@ class ThreadedHTTPServer(HTTPServer):
         self.handlerthread.daemon = False
 
         self.handlerthread.start()
+
+        signal.signal(signal.SIGTERM, self.sigterm_exception)
         super().serve_forever()
 
+    def sigterm_exception(self, signum, stackframe):
+        self.server_close()
+        os._exit(0)
+
     def process_request_thread(self):
         while not self.quit:
             try:
@@ -163,6 +170,7 @@ class ThreadedHTTPServer(HTTPServer):
                 self.handle_error(request, client_address)
             finally:
                 self.shutdown_request(request)
+        os._exit(0)
 
     def process_request(self, request, client_address):
         self.requestqueue.put((request, client_address))
@@ -208,6 +216,8 @@ def create_server(addr, dbname, prefix=''):
         cursor.execute('CREATE INDEX IF NOT EXISTS taskhash_lookup ON tasks_v2 (method, taskhash)')
         cursor.execute('CREATE INDEX IF NOT EXISTS outhash_lookup ON tasks_v2 (method, outhash)')
 
-    logger.info('Starting server on %s', addr)
+    ret = ThreadedHTTPServer(addr, Handler)
+
+    logger.info('Starting server on %s\n', ret.server_port)
 
-    return ThreadedHTTPServer(addr, Handler)
+    return ret
index 15f4a52ee961e175cf32cf7bbfc800bd9b7bd0fc..6845b53884ac2a5317c6087f8b778cc1401c15a0 100644 (file)
@@ -6,7 +6,7 @@
 #
 
 import unittest
-import threading
+import multiprocessing
 import sqlite3
 import hashlib
 import urllib.request
@@ -21,16 +21,16 @@ class TestHashEquivalenceServer(unittest.TestCase):
         self.dbfile = tempfile.NamedTemporaryFile(prefix="bb-hashserv-db-")
         self.server = create_server(('localhost', 0), self.dbfile.name)
         self.server_addr = 'http://localhost:%d' % self.server.socket.getsockname()[1]
-        self.server_thread = threading.Thread(target=self.server.serve_forever)
+        self.server_thread = multiprocessing.Process(target=self.server.serve_forever)
+        self.server_thread.daemon = True
         self.server_thread.start()
 
     def tearDown(self):
         # Shutdown server
         s = getattr(self, 'server', None)
         if s is not None:
-            self.server.shutdown()
+            self.server_thread.terminate()
             self.server_thread.join()
-            self.server.server_close()
 
     def send_get(self, path):
         url = '%s/%s' % (self.server_addr, path)