hww hidapi usage: try to mitigate some thread-safety issues
related: #6097
This commit is contained in:
@@ -46,7 +46,7 @@ class BitBox02Client(HardwareClientBase):
|
||||
# handler is a BitBox02_Handler, importing it would lead to a circular dependency
|
||||
def __init__(self, handler: Any, device: Device, config: SimpleConfig, *, plugin: HW_PluginBase):
|
||||
HardwareClientBase.__init__(self, plugin=plugin)
|
||||
self.bitbox02_device = None
|
||||
self.bitbox02_device = None # type: Optional[bitbox02.BitBox02]
|
||||
self.handler = handler
|
||||
self.device_descriptor = device
|
||||
self.config = config
|
||||
@@ -73,10 +73,11 @@ class BitBox02Client(HardwareClientBase):
|
||||
return True
|
||||
|
||||
def close(self):
|
||||
try:
|
||||
self.bitbox02_device.close()
|
||||
except:
|
||||
pass
|
||||
with self.device_manager().hid_lock:
|
||||
try:
|
||||
self.bitbox02_device.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
def has_usable_connection_with_device(self) -> bool:
|
||||
if self.bitbox_hid_info is None:
|
||||
@@ -91,7 +92,8 @@ class BitBox02Client(HardwareClientBase):
|
||||
res = device_response()
|
||||
except:
|
||||
# Close the hid device on exception
|
||||
hid_device.close()
|
||||
with self.device_manager().hid_lock:
|
||||
hid_device.close()
|
||||
raise
|
||||
finally:
|
||||
self.handler.finished()
|
||||
@@ -155,8 +157,9 @@ class BitBox02Client(HardwareClientBase):
|
||||
return set_noise_privkey(privkey)
|
||||
|
||||
if self.bitbox02_device is None:
|
||||
hid_device = hid.device()
|
||||
hid_device.open_path(self.bitbox_hid_info["path"])
|
||||
with self.device_manager().hid_lock:
|
||||
hid_device = hid.device()
|
||||
hid_device.open_path(self.bitbox_hid_info["path"])
|
||||
|
||||
self.bitbox02_device = bitbox02.BitBox02(
|
||||
transport=u2fhid.U2FHid(hid_device),
|
||||
|
||||
@@ -72,9 +72,9 @@ class CKCCClient(HardwareClientBase):
|
||||
self.dev = ElectrumColdcardDevice(dev_path, encrypt=True)
|
||||
else:
|
||||
# open the real HID device
|
||||
import hid
|
||||
hd = hid.device(path=dev_path)
|
||||
hd.open_path(dev_path)
|
||||
with self.device_manager().hid_lock:
|
||||
hd = hid.device(path=dev_path)
|
||||
hd.open_path(dev_path)
|
||||
|
||||
self.dev = ElectrumColdcardDevice(dev=hd, encrypt=True)
|
||||
|
||||
@@ -127,7 +127,8 @@ class CKCCClient(HardwareClientBase):
|
||||
|
||||
def close(self):
|
||||
# close the HID device (so can be reused)
|
||||
self.dev.close()
|
||||
with self.device_manager().hid_lock:
|
||||
self.dev.close()
|
||||
self.dev = None
|
||||
|
||||
def is_initialized(self):
|
||||
|
||||
@@ -77,10 +77,11 @@ class DigitalBitbox_Client(HardwareClientBase):
|
||||
|
||||
def close(self):
|
||||
if self.opened:
|
||||
try:
|
||||
self.dbb_hid.close()
|
||||
except:
|
||||
pass
|
||||
with self.device_manager().hid_lock:
|
||||
try:
|
||||
self.dbb_hid.close()
|
||||
except:
|
||||
pass
|
||||
self.opened = False
|
||||
|
||||
|
||||
@@ -681,8 +682,9 @@ class DigitalBitboxPlugin(HW_PluginBase):
|
||||
|
||||
|
||||
def get_dbb_device(self, device):
|
||||
dev = hid.device()
|
||||
dev.open_path(device.path)
|
||||
with self.device_manager().hid_lock:
|
||||
dev = hid.device()
|
||||
dev.open_path(device.path)
|
||||
return dev
|
||||
|
||||
|
||||
|
||||
@@ -196,6 +196,9 @@ class HardwareClientBase:
|
||||
def __init__(self, *, plugin: 'HW_PluginBase'):
|
||||
self.plugin = plugin
|
||||
|
||||
def device_manager(self) -> 'DeviceMgr':
|
||||
return self.plugin.device_manager()
|
||||
|
||||
def is_pairable(self) -> bool:
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
@@ -74,7 +74,8 @@ class Ledger_Client(HardwareClientBase):
|
||||
return True
|
||||
|
||||
def close(self):
|
||||
self.dongleObject.dongle.close()
|
||||
with self.device_manager().hid_lock:
|
||||
self.dongleObject.dongle.close()
|
||||
|
||||
def timeout(self, cutoff):
|
||||
pass
|
||||
@@ -184,13 +185,13 @@ class Ledger_Client(HardwareClientBase):
|
||||
self.segwitSupported = self.nativeSegwitSupported or (firmwareInfo['specialVersion'] == 0x20 and versiontuple(firmware) >= versiontuple(SEGWIT_SUPPORT_SPECIAL))
|
||||
|
||||
if not checkFirmware(firmwareInfo):
|
||||
self.dongleObject.dongle.close()
|
||||
self.close()
|
||||
raise UserFacingException(MSG_NEEDS_FW_UPDATE_GENERIC)
|
||||
try:
|
||||
self.dongleObject.getOperationMode()
|
||||
except BTChipException as e:
|
||||
if (e.sw == 0x6985):
|
||||
self.dongleObject.dongle.close()
|
||||
self.close()
|
||||
self.handler.get_setup( )
|
||||
# Acquire the new client on the next run
|
||||
else:
|
||||
@@ -593,9 +594,10 @@ class LedgerPlugin(HW_PluginBase):
|
||||
ledger = True
|
||||
else:
|
||||
return None # non-compatible interface of a Nano S or Blue
|
||||
dev = hid.device()
|
||||
dev.open_path(device.path)
|
||||
dev.set_nonblocking(True)
|
||||
with self.device_manager().hid_lock:
|
||||
dev = hid.device()
|
||||
dev.open_path(device.path)
|
||||
dev.set_nonblocking(True)
|
||||
return HIDDongleHIDAPI(dev, ledger, BTCHIP_DEBUG)
|
||||
|
||||
def create_client(self, device, handler):
|
||||
|
||||
Reference in New Issue
Block a user