mirror of
https://git.yoctoproject.org/poky
synced 2026-06-02 13:29:49 +00:00
bitbake: prserv/serv: Improve process exit handling
The server shutdown is currenlty laggy and race prone. This patch: * adds a waitpid so that no zombie server is left around if its not running in daemon mode. * adds a quit "sentinal" using a pipe so that we're not sitting in a socket poll() until timeout in order just to quit. * use a select() call to poll the socket and the pipe for a quit signal. The net result of this change is that the prserv exits with the cooker server and it does so immediately and doesn't wait for the select/poll calls to timeout. This makes bitbake a lot more responsive for startup/shutdown and doesn't cause UI timeout errors as often when prserv is used. (Bitbake rev: 0b5a837477d18442caf97dd0fa14a806c54f5842) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
@@ -10,6 +10,7 @@ import bb.server.xmlrpcclient
|
|||||||
import prserv
|
import prserv
|
||||||
import prserv.db
|
import prserv.db
|
||||||
import errno
|
import errno
|
||||||
|
import select
|
||||||
|
|
||||||
logger = logging.getLogger("BitBake.PRserv")
|
logger = logging.getLogger("BitBake.PRserv")
|
||||||
|
|
||||||
@@ -59,6 +60,8 @@ class PRServer(SimpleXMLRPCServer):
|
|||||||
self.register_function(self.importone, "importone")
|
self.register_function(self.importone, "importone")
|
||||||
self.register_introspection_functions()
|
self.register_introspection_functions()
|
||||||
|
|
||||||
|
self.quitpipein, self.quitpipeout = os.pipe()
|
||||||
|
|
||||||
self.requestqueue = queue.Queue()
|
self.requestqueue = queue.Queue()
|
||||||
self.handlerthread = threading.Thread(target = self.process_request_thread)
|
self.handlerthread = threading.Thread(target = self.process_request_thread)
|
||||||
self.handlerthread.daemon = False
|
self.handlerthread.daemon = False
|
||||||
@@ -153,11 +156,16 @@ class PRServer(SimpleXMLRPCServer):
|
|||||||
|
|
||||||
def quit(self):
|
def quit(self):
|
||||||
self.quit=True
|
self.quit=True
|
||||||
|
os.write(self.quitpipeout, b"q")
|
||||||
|
os.close(self.quitpipeout)
|
||||||
return
|
return
|
||||||
|
|
||||||
def work_forever(self,):
|
def work_forever(self,):
|
||||||
self.quit = False
|
self.quit = False
|
||||||
self.timeout = 0.5
|
# This timeout applies to the poll in TCPServer, we need the select
|
||||||
|
# below to wake on our quit pipe closing. We only ever call into handle_request
|
||||||
|
# if there is data there.
|
||||||
|
self.timeout = 0.01
|
||||||
|
|
||||||
bb.utils.set_process_name("PRServ")
|
bb.utils.set_process_name("PRServ")
|
||||||
|
|
||||||
@@ -170,11 +178,16 @@ class PRServer(SimpleXMLRPCServer):
|
|||||||
|
|
||||||
self.handlerthread.start()
|
self.handlerthread.start()
|
||||||
while not self.quit:
|
while not self.quit:
|
||||||
self.handle_request()
|
ready = select.select([self.fileno(), self.quitpipein], [], [], 30)
|
||||||
|
if self.quit:
|
||||||
|
break
|
||||||
|
if self.fileno() in ready[0]:
|
||||||
|
self.handle_request()
|
||||||
self.handlerthread.join()
|
self.handlerthread.join()
|
||||||
self.db.disconnect()
|
self.db.disconnect()
|
||||||
logger.info("PRServer: stopping...")
|
logger.info("PRServer: stopping...")
|
||||||
self.server_close()
|
self.server_close()
|
||||||
|
os.close(self.quitpipein)
|
||||||
return
|
return
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
@@ -182,6 +195,7 @@ class PRServer(SimpleXMLRPCServer):
|
|||||||
pid = self.daemonize()
|
pid = self.daemonize()
|
||||||
else:
|
else:
|
||||||
pid = self.fork()
|
pid = self.fork()
|
||||||
|
self.pid = pid
|
||||||
|
|
||||||
# Ensure both the parent sees this and the child from the work_forever log entry above
|
# Ensure both the parent sees this and the child from the work_forever log entry above
|
||||||
logger.info("Started PRServer with DBfile: %s, IP: %s, PORT: %s, PID: %s" %
|
logger.info("Started PRServer with DBfile: %s, IP: %s, PORT: %s, PID: %s" %
|
||||||
@@ -472,6 +486,7 @@ def auto_shutdown(d=None):
|
|||||||
PRServerConnection(host, port).terminate()
|
PRServerConnection(host, port).terminate()
|
||||||
except:
|
except:
|
||||||
logger.critical("Stop PRService %s:%d failed" % (host,port))
|
logger.critical("Stop PRService %s:%d failed" % (host,port))
|
||||||
|
os.waitpid(singleton.prserv.pid, 0)
|
||||||
singleton = None
|
singleton = None
|
||||||
|
|
||||||
def ping(host, port):
|
def ping(host, port):
|
||||||
|
|||||||
Reference in New Issue
Block a user