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:
Hiroyuki Ikezoe 2018-08-13 06:08:34 +09:00
Родитель 720a215841
Коммит db4c3c99a6
2 изменённых файлов: 15 добавлений и 9 удалений

Просмотреть файл

@ -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()