SNIClient: prevent hang on exit if waiting on devices from SNI

This commit is contained in:
Fabian Dill 2022-06-12 03:20:03 +02:00 committed by Fabian Dill
parent e7ea827f02
commit 0869a2acc3
1 changed files with 18 additions and 11 deletions

View File

@ -78,7 +78,10 @@ class SNIClientCommandProcessor(ClientCommandProcessor):
snes_device_number = int(options[1])
self.ctx.snes_reconnect_address = None
asyncio.create_task(snes_connect(self.ctx, snes_address, snes_device_number), name="SNES Connect")
if self.ctx.snes_connect_task:
self.ctx.snes_connect_task.cancel()
self.ctx.snes_connect_task = asyncio.create_task(snes_connect(self.ctx, snes_address, snes_device_number),
name="SNES Connect")
return True
def _cmd_snes_close(self) -> bool:
@ -115,6 +118,7 @@ class Context(CommonContext):
command_processor = SNIClientCommandProcessor
game = "A Link to the Past"
items_handling = None # set in game_watcher
snes_connect_task: typing.Optional[asyncio.Task] = None
def __init__(self, snes_address, server_address, password):
super(Context, self).__init__(server_address, password)
@ -181,6 +185,11 @@ class Context(CommonContext):
if not currently_dead:
self.death_state = DeathState.alive
async def shutdown(self):
await super(Context, self).shutdown()
if self.snes_connect_task:
await self.snes_connect_task
def on_package(self, cmd: str, args: dict):
if cmd in {"Connected", "RoomUpdate"}:
if "checked_locations" in args and args["checked_locations"]:
@ -653,17 +662,18 @@ async def get_snes_devices(ctx: Context) -> typing.List[str]:
}
await socket.send(dumps(DeviceList_Request))
reply = loads(await socket.recv())
devices = reply['Results'] if 'Results' in reply and len(reply['Results']) > 0 else None
reply: dict = loads(await socket.recv())
devices: typing.List[str] = reply['Results'] if 'Results' in reply and len(reply['Results']) > 0 else []
if not devices:
snes_logger.info('No SNES device found. Please connect a SNES device to SNI.')
while not devices:
await asyncio.sleep(1)
while not devices and not ctx.exit_event.is_set():
await asyncio.sleep(0.1)
await socket.send(dumps(DeviceList_Request))
reply = loads(await socket.recv())
devices = reply['Results'] if 'Results' in reply and len(reply['Results']) > 0 else None
await verify_snes_app(socket)
devices = reply['Results'] if 'Results' in reply and len(reply['Results']) > 0 else []
if devices:
await verify_snes_app(socket)
await socket.close()
return sorted(devices)
@ -1319,7 +1329,7 @@ async def main():
ctx.run_gui()
ctx.run_cli()
snes_connect_task = asyncio.create_task(snes_connect(ctx, ctx.snes_address), name="SNES Connect")
ctx.snes_connect_task = asyncio.create_task(snes_connect(ctx, ctx.snes_address), name="SNES Connect")
watcher_task = asyncio.create_task(game_watcher(ctx), name="GameWatcher")
await ctx.exit_event.wait()
@ -1328,15 +1338,12 @@ async def main():
ctx.snes_reconnect_address = None
if ctx.snes_socket is not None and not ctx.snes_socket.closed:
await ctx.snes_socket.close()
if snes_connect_task:
snes_connect_task.cancel()
await watcher_task
await ctx.shutdown()
def get_alttp_settings(romfile: str):
lastSettings = Utils.get_adjuster_settings(GAME_ALTTP)
adjusted = False
adjustedromfile = ''
if lastSettings:
choice = 'no'