Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: GlasgowEmbedded/glasgow
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: c103a8fc7945
Choose a base ref
...
head repository: GlasgowEmbedded/glasgow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 431f985c71e4
Choose a head ref
  • 2 commits
  • 4 files changed
  • 1 contributor

Commits on Aug 28, 2019

  1. device.hardware: shut down libusb polling thread.

    Not doing this can cause a hang at interpreter shutdown because
    python-libusb1 calls libusb_close() in __del__, which causes libusb1
    to take a lock, which might have been taken by the daemon poller
    thread, which might have already been killed (without releasing
    the lock) by the time __del__ is called.
    whitequark committed Aug 28, 2019
    Copy the full SHA
    4de7004 View commit details
  2. Copy the full SHA
    431f985 View commit details
Showing with 23 additions and 13 deletions.
  1. +6 −6 software/glasgow/access/direct/demultiplexer.py
  2. +1 −1 software/glasgow/applet/__init__.py
  3. +5 −0 software/glasgow/cli.py
  4. +11 −6 software/glasgow/device/hardware.py
12 changes: 6 additions & 6 deletions software/glasgow/access/direct/demultiplexer.py
Original file line number Diff line number Diff line change
@@ -64,10 +64,10 @@ def __init__(self, device, pipe_count):
super().__init__(device)
self._claimed = set()

for config in device.usb.getDevice().iterConfigurations():
for config in device.usb_handle.getDevice().iterConfigurations():
if config.getNumInterfaces() == pipe_count:
try:
device.usb.setConfiguration(config.getConfigurationValue())
device.usb_handle.setConfiguration(config.getConfigurationValue())
except usb1.USBErrorInvalidParam:
# Neither WinUSB, nor libusbK, nor libusb0 allow selecting any configuration
# that is not the 1st one. This is a limitation of the KMDF USB target.
@@ -149,8 +149,8 @@ def __init__(self, device, applet, mux_interface,
self._pipe_num = mux_interface._pipe_num
self._addr_reset = mux_interface._addr_reset

config_num = self.device.usb.getConfiguration()
for config in self.device.usb.getDevice().iterConfigurations():
config_num = self.device.usb_handle.getConfiguration()
for config in self.device.usb_handle.getDevice().iterConfigurations():
if config.getConfigurationValue() == config_num:
break

@@ -171,7 +171,7 @@ def __init__(self, device, applet, mux_interface,
self._out_packet_size = packet_size
assert self._endpoint_in != None and self._endpoint_out != None

self._interface = self.device.usb.claimInterface(self._pipe_num)
self._interface = self.device.usb_handle.claimInterface(self._pipe_num)
self._in_tasks = TaskQueue()
self._in_buffer = ChunkedFIFO()
self._out_tasks = TaskQueue()
@@ -193,7 +193,7 @@ async def reset(self):
await self.device.write_register(self._addr_reset, 1)

self.logger.trace("FIFO: synchronizing buffers")
self.device.usb.setInterfaceAltSetting(self._pipe_num, 1)
self.device.usb_handle.setInterfaceAltSetting(self._pipe_num, 1)
self._in_buffer .clear()
self._out_buffer.clear()

2 changes: 1 addition & 1 deletion software/glasgow/applet/__init__.py
Original file line number Diff line number Diff line change
@@ -354,7 +354,7 @@ def run_test():

finally:
if mode == "record":
self.device.usb.close()
self.device.close()

return wrapper

5 changes: 5 additions & 0 deletions software/glasgow/cli.py
Original file line number Diff line number Diff line change
@@ -415,6 +415,7 @@ async def _main():
args = get_argparser().parse_args()
create_logger(args)

device = None
try:
# TODO(py3.7): use importlib.resources
firmware_filename = os.path.join(os.path.dirname(__file__), "glasgow.ihex")
@@ -771,6 +772,10 @@ def startTest(test):
applet.logger.error(e)
return 1

finally:
if device is not None:
device.close()

return 0


17 changes: 11 additions & 6 deletions software/glasgow/device/hardware.py
Original file line number Diff line number Diff line change
@@ -45,11 +45,11 @@
class _PollerThread(threading.Thread):
def __init__(self, context):
super().__init__()
self.daemon = True
self.done = False
self.context = context

def run(self):
while True:
while not self.done:
self.context.handleEvents()


@@ -128,22 +128,27 @@ def __init__(self, serial=None, firmware_filename=None, *, _factory_rev=None):
.format(serial))

if serial is None:
self.revision, self.usb = next(iter(handles.values()))
self.revision, self.usb_handle = next(iter(handles.values()))
else:
self.revision, self.usb = handles[serial]
self.revision, self.usb_handle = handles[serial]
try:
self.usb.setAutoDetachKernelDriver(True)
self.usb_handle.setAutoDetachKernelDriver(True)
except usb1.USBErrorNotSupported:
pass

def close(self):
self.usb_poller.done = True
self.usb_handle.close()
self.usb_context.close()

async def _do_transfer(self, is_read, setup):
# libusb transfer cancellation is asynchronous, and moreover, it is necessary to wait for
# all transfers to finish cancelling before closing the event loop. To do this, use
# separate futures for result and cancel.
cancel_future = asyncio.Future()
result_future = asyncio.Future()

transfer = self.usb.getTransfer()
transfer = self.usb_handle.getTransfer()
setup(transfer)

def usb_callback(transfer):