btlewrap
btlewrap copied to clipboard
gatttool timeout handler does not cleanup subprocesses
The timeout handler in connection.wait_for_notification()
(and other gatttool functions) does something like:
with Popen(cmd, shell=True, ...) as process:
try:
...
except TimeoutExpired:
os.killpg(process.pid, signal.SIGINT)
Because its using shell=True
it sends the SIGINT to the /bin/sh
process instead of gatttool
, which ignores it. The SIGINT needs to be sent directly to the gatttool
process. Since the processes are not cleaned up, they build up over time. Often one of them might still have a lock on something, so all subsequent instances of gatttool
fail.
This can be easily fixed by removing the shell=True
and passing the arguments as a list. e.g.
cmd = ['gatttool', '--device', self._mac, ...]
with Popen(cmd, shell=True, ...) as process:
...
Then process.pid
will be that of the gatttool
process.