From 1ceacd71e36e1f7a1add0d95f128b77641c11521 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Thu, 21 May 2026 17:11:55 -0500 Subject: [PATCH] drop stale shm cache refs when cached segment is too small for requested shape --- frigate/util/image.py | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/frigate/util/image.py b/frigate/util/image.py index 2d2133c6b8..4054c54182 100644 --- a/frigate/util/image.py +++ b/frigate/util/image.py @@ -1089,10 +1089,32 @@ class SharedMemoryFrameManager(FrameManager): def get(self, name: str, shape) -> Optional[np.ndarray]: try: - if name in self.shm_store: - shm = self.shm_store[name] - else: + required = int(np.prod(shape)) + shm = self.shm_store.get(name) + if shm is not None and shm.size < required: + # Cached reference points at an older, smaller segment + # that was unlinked and recreated at a larger size in a + # camera add/remove cycle. Drop the stale ref so we + # reopen the current segment. + try: + shm.close() + except Exception: + pass + self.shm_store.pop(name, None) + shm = None + if shm is None: shm = UntrackedSharedMemory(name=name) + if shm.size < required: + # Transient mid-recreate state: the OS-level segment + # is still at the previous (smaller) size because the + # maintainer hasn't allocated the new one yet. Don't + # cache it (so the next call re-opens once the + # maintainer has caught up) and skip this frame. + try: + shm.close() + except Exception: + pass + return None self.shm_store[name] = shm return np.ndarray(shape, dtype=np.uint8, buffer=shm.buf) except FileNotFoundError: