From 8d41ce633114f6dfb0f9cf8ce0e85fdf76b6a830 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Sat, 26 Mar 2016 13:32:26 -0400 Subject: [PATCH] Avoid stall waiting on incommand It was possible for multiple command requests to be pending. While pending, if a waiter was awoken first, *then* the satisfied command, then the waiter will stall in the next iteration, recovering only after the failsafe mechanism kicks in. Address by having the instance clearing incommand set() the next event in line. Change-Id: I8dbd08027596b4acccace6599f996ad547a47768 --- pyghmi/ipmi/private/session.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pyghmi/ipmi/private/session.py b/pyghmi/ipmi/private/session.py index 533c61a8..f1c9684c 100644 --- a/pyghmi/ipmi/private/session.py +++ b/pyghmi/ipmi/private/session.py @@ -125,8 +125,10 @@ def define_worker(): sessionqueue = collections.deque([]) -def _io_wait(timeout, myaddr=None): +def _io_wait(timeout, myaddr=None, evq=None): evt = threading.Event() + if evq is not None: + evq.append(evt) deadline = timeout + _monotonic_time() ioqueue.append((deadline, evt, myaddr)) # Unfortunately, at least with eventlet patched threading, the wait() @@ -406,6 +408,8 @@ class Session(object): self.cleaningup = False self.lastpayload = None self._customkeepalives = None + self.evq = collections.deque([]) # queue of events denoting line to + # run a cmd self.bmc = bmc self.broken = False # a private queue for packets for which this session handler @@ -625,7 +629,7 @@ class Session(object): def _cmdwait(self): while self._isincommand(): - _io_wait(self._isincommand(), self.sockaddr) + _io_wait(self._isincommand(), self.sockaddr, self.evq) def awaitresponse(self, retry): while retry and self.lastresponse is None and self.logged: @@ -676,6 +680,8 @@ class Session(object): self.incommand = False if retry and lastresponse is None: raise exc.IpmiException('Session no longer connected') + if self.evq: + self.evq.popleft().set() return lastresponse def _send_ipmi_net_payload(self, netfn=None, command=None, data=(), code=0,