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

target: Use tls_property() to manage a thread-local connection

This frees the connection to have to handle threading issues, since each thread
using the Target will have its own connection. The connection will be garbage
collected when the thread using it dies, avoiding connection leaks.
This commit is contained in:
Douglas RAILLARD 2020-01-15 17:16:47 +00:00 committed by Marc Bonnici
parent 922686a348
commit 9d5d70564f

View File

@ -53,7 +53,7 @@ from devlib.utils.android import AdbConnection, AndroidProperties, LogcatMonitor
from devlib.utils.misc import memoized, isiterable, convert_new_lines from devlib.utils.misc import memoized, isiterable, convert_new_lines
from devlib.utils.misc import commonprefix, merge_lists from devlib.utils.misc import commonprefix, merge_lists
from devlib.utils.misc import ABI_MAP, get_cpu_name, ranges_to_list from devlib.utils.misc import ABI_MAP, get_cpu_name, ranges_to_list
from devlib.utils.misc import batch_contextmanager from devlib.utils.misc import batch_contextmanager, tls_property
from devlib.utils.types import integer, boolean, bitmask, identifier, caseless_string, bytes_regex from devlib.utils.types import integer, boolean, bitmask, identifier, caseless_string, bytes_regex
@ -214,22 +214,19 @@ class Target(object):
cmd = "cat /proc/self/smaps | {0} grep KernelPageSize | {0} head -n 1 | {0} awk '{{ print $2 }}'" cmd = "cat /proc/self/smaps | {0} grep KernelPageSize | {0} head -n 1 | {0} awk '{{ print $2 }}'"
return int(self.execute(cmd.format(self.busybox))) return int(self.execute(cmd.format(self.busybox)))
@property
def conn(self):
if self._connections:
tid = id(threading.current_thread())
if tid not in self._connections:
self._connections[tid] = self.get_connection()
return self._connections[tid]
else:
return None
@property @property
def shutils(self): def shutils(self):
if self._shutils is None: if self._shutils is None:
self._setup_shutils() self._setup_shutils()
return self._shutils return self._shutils
@tls_property
def _conn(self):
return self.get_connection()
# Add a basic property that does not require calling to get the value
conn = _conn.basic_property
def __init__(self, def __init__(self,
connection_settings=None, connection_settings=None,
platform=None, platform=None,
@ -242,6 +239,7 @@ class Target(object):
conn_cls=None, conn_cls=None,
is_container=False is_container=False
): ):
self._is_rooted = None self._is_rooted = None
self.connection_settings = connection_settings or {} self.connection_settings = connection_settings or {}
# Set self.platform: either it's given directly (by platform argument) # Set self.platform: either it's given directly (by platform argument)
@ -271,7 +269,6 @@ class Target(object):
self._installed_binaries = {} self._installed_binaries = {}
self._installed_modules = {} self._installed_modules = {}
self._cache = {} self._cache = {}
self._connections = {}
self._shutils = None self._shutils = None
self._file_transfer_cache = None self._file_transfer_cache = None
self.busybox = None self.busybox = None
@ -290,8 +287,9 @@ class Target(object):
def connect(self, timeout=None, check_boot_completed=True): def connect(self, timeout=None, check_boot_completed=True):
self.platform.init_target_connection(self) self.platform.init_target_connection(self)
tid = id(threading.current_thread()) # Forcefully set the thread-local value for the connection, with the
self._connections[tid] = self.get_connection(timeout=timeout) # timeout we want
self.conn = self.get_connection(timeout=timeout)
if check_boot_completed: if check_boot_completed:
self.wait_boot_complete(timeout) self.wait_boot_complete(timeout)
self._resolve_paths() self._resolve_paths()
@ -304,9 +302,9 @@ class Target(object):
self._install_module(get_module('bl')) self._install_module(get_module('bl'))
def disconnect(self): def disconnect(self):
for conn in self._connections.values(): connections = self._conn.get_all_values()
for conn in connections:
conn.close() conn.close()
self._connections = {}
def get_connection(self, timeout=None): def get_connection(self, timeout=None):
if self.conn_cls is None: if self.conn_cls is None: