1
0
mirror of https://github.com/ARM-software/devlib.git synced 2025-01-31 02:00:45 +00:00

utils/android: Make AdbConnection.active_connections thread safe

Add a lock to serialize access to the dictionary.
This commit is contained in:
Douglas Raillard 2022-08-12 18:21:37 +01:00 committed by Marc Bonnici
parent b988e245d9
commit be734140b3

View File

@ -30,6 +30,7 @@ import tempfile
import time import time
import uuid import uuid
import zipfile import zipfile
import threading
from collections import defaultdict from collections import defaultdict
from io import StringIO from io import StringIO
@ -258,7 +259,7 @@ class AdbConnection(ConnectionBase):
# maintains the count of parallel active connections to a device, so that # maintains the count of parallel active connections to a device, so that
# adb disconnect is not invoked untill all connections are closed # adb disconnect is not invoked untill all connections are closed
active_connections = defaultdict(int) active_connections = (threading.Lock(), defaultdict(int))
# Track connected as root status per device # Track connected as root status per device
_connected_as_root = defaultdict(lambda: None) _connected_as_root = defaultdict(lambda: None)
default_timeout = 10 default_timeout = 10
@ -301,7 +302,10 @@ class AdbConnection(ConnectionBase):
'poll_period': transfer_poll_period, 'poll_period': transfer_poll_period,
} }
self.transfer_mgr = PopenTransferManager(self, **transfer_opts) if poll_transfers else None self.transfer_mgr = PopenTransferManager(self, **transfer_opts) if poll_transfers else None
AdbConnection.active_connections[self.device] += 1 lock, nr_active = AdbConnection.active_connections
with lock:
nr_active[self.device] += 1
if self.adb_as_root: if self.adb_as_root:
try: try:
self.adb_root(enable=True) self.adb_root(enable=True)
@ -377,12 +381,17 @@ class AdbConnection(ConnectionBase):
return bg_cmd return bg_cmd
def _close(self): def _close(self):
AdbConnection.active_connections[self.device] -= 1 lock, nr_active = AdbConnection.active_connections
if AdbConnection.active_connections[self.device] <= 0: with lock:
nr_active[self.device] -= 1
disconnect = nr_active[self.device] <= 0
if disconnect:
del nr_active[self.device]
if disconnect:
if self.adb_as_root: if self.adb_as_root:
self.adb_root(enable=False) self.adb_root(enable=False)
adb_disconnect(self.device, self.adb_server) adb_disconnect(self.device, self.adb_server)
del AdbConnection.active_connections[self.device]
def cancel_running_command(self): def cancel_running_command(self):
# adbd multiplexes commands so that they don't interfer with each # adbd multiplexes commands so that they don't interfer with each
@ -391,7 +400,11 @@ class AdbConnection(ConnectionBase):
pass pass
def adb_root(self, enable=True): def adb_root(self, enable=True):
if AdbConnection.active_connections[self.device] > 1: lock, nr_active = AdbConnection.active_connections
with lock:
can_root = nr_active[self.device] <= 1
if not can_root:
raise AdbRootError('Can only restart adb server if no other connection is active') raise AdbRootError('Can only restart adb server if no other connection is active')
cmd = 'root' if enable else 'unroot' cmd = 'root' if enable else 'unroot'