diff --git a/CHANGELOG.md b/CHANGELOG.md index cc553efe5..12094e2fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Added in-place preamp recovery when I2C writes fail persistently * Fixed all loopback dmix devices sharing one ipc_key in asound.conf, which made loopback playback devices intermittently fail to open with EINVAL (#957) * Disabled USB autosuspend for the CM6206 USB audio device + * Fixed LMS stream shutdown force-killing the wrong process group * Web App * Add warning for older versions of the webapp running on newer backends diff --git a/amplipi/streams/lms.py b/amplipi/streams/lms.py index db9b097f5..9e615f3f7 100644 --- a/amplipi/streams/lms.py +++ b/amplipi/streams/lms.py @@ -90,9 +90,9 @@ def _activate(self, vsrc: int): meta_args.extend(["--server", f"{self.server}"]) if self.port is not None: meta_args.extend(["--port", f"{self.port}"]) - self.meta_proc = subprocess.Popen(args=meta_args, stdout=sys.stdout, stderr=sys.stderr) + self.meta_proc = subprocess.Popen(args=meta_args, stdout=sys.stdout, stderr=sys.stderr, preexec_fn=os.setpgrp) - self.proc = subprocess.Popen(args=lms_args) + self.proc = subprocess.Popen(args=lms_args, preexec_fn=os.setpgrp) except Exception as exc: logger.exception(f'error starting lms: {exc}') @@ -106,7 +106,10 @@ def _deactivate(self): except Exception as e: logger.exception(f"failed to gracefully terminate LMS stream {self.name}: {e}") logger.warning(f"forcefully killing LMS stream {self.name}") - os.killpg(self.proc.pid, signal.SIGKILL) + try: + os.killpg(os.getpgid(self.proc.pid), signal.SIGKILL) + except ProcessLookupError: + pass self.proc.communicate(timeout=3) if self.meta_proc is not None: @@ -116,7 +119,10 @@ def _deactivate(self): except Exception as e: logger.exception(f"failed to gracefully terminate LMS meta proc for {self.name}: {e}") logger.warning(f"forcefully killing LMS meta proc for {self.name}") - os.killpg(self.meta_proc.pid, signal.SIGKILL) + try: + os.killpg(os.getpgid(self.meta_proc.pid), signal.SIGKILL) + except ProcessLookupError: + pass self.meta_proc.communicate(timeout=3) self.proc = None