зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1481699 - Do not process any further data after we started shutting down the ADB server. r=jdescottes
In the genuine adb binary, when it received 'host:kill' command, it exits the server process soon [1]. Whereas, in our mock adb.py which is based on SocketServer.TCPServer in python, when we call SocketServer.TCPServer.shutdown() in the case of 'kill-server' command, the server process doesn't exit soon since the shutdown() function just sets a flag [2] and serve_forever() polls it [3] every |poll_interval| seconds, |poll_interval| is 0.5 seconds by default. Thus it's possible that new incoming requests are processed during polling. This is the real cause of the race condition that the adb server still keeps alive when 'adb kill-server' finished. So we don't need to the workaround for the race condition. [1]4039051d6d/adb/adb.cpp (1049)
[2]65b5ef02ec/Lib/socketserver.py (L248)
[3] https://docs.python.org/2/library/socketserver.html#SocketServer.BaseServer.serve_forever Differential Revision: https://phabricator.services.mozilla.com/D3169
This commit is contained in:
Родитель
720a215841
Коммит
db4c3c99a6
|
@ -130,12 +130,6 @@ const ADB = {
|
|||
return; // We didn't start the server, nothing to do
|
||||
}
|
||||
await this.kill();
|
||||
// Make sure the ADB server stops listening because kill() above doesn't
|
||||
// mean that the ADB server stops, it means that 'adb kill-server' command
|
||||
// just finished, so that it's possible that the ADB server is still alive.
|
||||
await this._waitUntil(async () => {
|
||||
return !await check();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,12 +33,16 @@ class ADBRequestHandler(SocketServer.BaseRequestHandler):
|
|||
sent_length = sent_length + sent
|
||||
|
||||
def handle(self):
|
||||
if server.is_shuttingdown:
|
||||
return
|
||||
|
||||
while True:
|
||||
data = self.request.recv(4096)
|
||||
if 'kill-server' in data:
|
||||
def shutdown(server):
|
||||
server.shutdown()
|
||||
thread.exit()
|
||||
server.is_shuttingdown = True
|
||||
self.sendData('')
|
||||
self.request.close()
|
||||
thread.start_new_thread(shutdown, (server, ))
|
||||
|
@ -51,6 +55,16 @@ class ADBRequestHandler(SocketServer.BaseRequestHandler):
|
|||
self.sendData('1234567890\tdevice')
|
||||
break
|
||||
|
||||
class ADBServer(SocketServer.TCPServer):
|
||||
def __init__(self, server_address):
|
||||
# Create a SocketServer with bind_and_activate 'False' to set
|
||||
# allow_reuse_address before binding.
|
||||
SocketServer.TCPServer.__init__(self, \
|
||||
server_address, \
|
||||
ADBRequestHandler, \
|
||||
bind_and_activate = False)
|
||||
self.is_shuttingdown = False
|
||||
|
||||
if len(sys.argv) == 2:
|
||||
if sys.argv[1] == 'start-server':
|
||||
# daemonize
|
||||
|
@ -60,9 +74,7 @@ if len(sys.argv) == 2:
|
|||
if os.fork() > 0:
|
||||
sys.exit(0)
|
||||
|
||||
# Create a SocketServer with 'False' for bind_and_activate to set
|
||||
# allow_reuse_address before binding.
|
||||
server = SocketServer.TCPServer((HOST, PORT), ADBRequestHandler, False)
|
||||
server = ADBServer((HOST, PORT))
|
||||
server.allow_reuse_address = True
|
||||
server.server_bind()
|
||||
server.server_activate()
|
||||
|
|
Загрузка…
Ссылка в новой задаче