2
0
mirror of https://opendev.org/x/pyghmi synced 2025-01-27 19:37:44 +00:00

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
This commit is contained in:
Jarrod Johnson 2016-03-26 13:32:26 -04:00
parent 3d2da22dd2
commit 8d41ce6331

View File

@ -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,