From 8aecc6959a3923db173306c2523daba8cdcc62b9 Mon Sep 17 00:00:00 2001 From: Markus Hilger Date: Fri, 14 Aug 2026 14:07:49 +0200 Subject: [PATCH] Do not let a logout come back round into its own notification Telling a keepalive that the session is gone can end up back in logout, because reporting it is how a console gives up its claim. The inner pass finished by clearing the register of keepalives while the outer was still walking it, so the next entry was looked up on None. Two entries is what an XCC has, the console's and the oem handler's. Take the callbacks and give up the register before notifying anyone. --- .../aiohmi/ipmi/private/session.py | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/confluent_server/aiohmi/ipmi/private/session.py b/confluent_server/aiohmi/ipmi/private/session.py index 6dfc0a1a..30caa535 100644 --- a/confluent_server/aiohmi/ipmi/private/session.py +++ b/confluent_server/aiohmi/ipmi/private/session.py @@ -1987,16 +1987,19 @@ class Session(object): self.onlogpayload = None self.logging = False if self._customkeepalives: - for ka in list(self._customkeepalives): - # Be thorough and notify parties through their custom - # keepalives. In practice, this *should* be the same, but - # if a code somehow makes duplicate SOL handlers, - # this would notify all the handlers rather than just the - # last one to take ownership - if self._customkeepalives[ka][1] is None: + # Be thorough and notify parties through their custom + # keepalives. In practice, this *should* be the same, but + # if a code somehow makes duplicate SOL handlers, + # this would notify all the handlers rather than just the + # last one to take ownership + # Take the callbacks and give this up first: notifying one can + # come back round through here and clear it mid walk + callbacks = [ka[1] for ka in self._customkeepalives.values()] + self._customkeepalives = None + for callback in callbacks: + if callback is None: continue - await self._customkeepalives[ka][1]( - {'error': 'Session Disconnected'}) + await callback({'error': 'Session Disconnected'}) self._customkeepalives = None if not self.broken: self.broken = True