docs: def wait_for_rsp(cls, timeout=None, callout=True):
          """IPMI Session Event loop iteration
  
          This watches for any activity on IPMI handles and handles registered
          by register_handle_callback.  Callers are satisfied in the order that
          packets return from network, not in the order of calling.
  
          :param timeout: Maximum time to wait for data to come across.  If
                          unspecified, will autodetect based on earliest timeout
          """
          global iosockets
          # Assume:
          # Instance A sends request to packet B
          # Then Instance C sends request to BMC D
          # BMC D was faster, so data comes back before BMC B
          # Instance C gets to go ahead of Instance A, because
          # Instance C can get work done, but instance A cannot
  
          curtime = _monotonic_time()
          # There ar a number of parties that each has their own timeout
          # The caller can specify a deadline in timeout argument
          # each session with active outbound payload has callback to
          # handle retry/timout error
          # each session that is 'alive' wants to send a keepalive ever so often.
          # We want to make sure the most strict request is honored and block for
          # no more time than that, so that whatever part(ies) need to service in
          # a deadline, will be honored
          if timeout != 0:
              with util.protect(WAITING_SESSIONS):
                  for session, parms in dictitems(cls.waiting_sessions):
                      if parms['timeout'] <= curtime:
                          timeout = 0  # exit after one guaranteed pass
                          break
                      if (timeout is not None and
                              timeout < parms['timeout'] - curtime):
                          continue  # timeout smaller than the current session
                          # needs
                      timeout = parms['timeout'] - curtime  # set new timeout
                      # value
              with util.protect(KEEPALIVE_SESSIONS):
                  for session, parms in dictitems(cls.keepalive_sessions):
                      if parms['timeout'] <= curtime:
                          timeout = 0
                          break
                      if (timeout is not None and
                              timeout < parms['timeout'] - curtime):
                          continue
                      timeout = parms['timeout'] - curtime
          # If the loop above found no sessions wanting *and* the caller had no
          # timeout, exit function. In this case there is no way a session
          # could be waiting so we can always return 0
          while cls.iterwaiters:
              waiter = cls.iterwaiters.pop()
              waiter({'success': True})
              # cause a quick exit from the event loop iteration for calling code
              # to be able to reasonably set up for the next iteration before
              # a long select comes along
              if timeout is not None:
                  timeout = 0
          if timeout is None:
              return 0
          if _poller(timeout=timeout):
              while sessionqueue:
                  relsession = sessionqueue.popleft()
                  relsession.process_pktqueue()
          sessionstodel = []
          sessionstokeepalive = []
          with util.protect(KEEPALIVE_SESSIONS):
              for session, parms in dictitems(cls.keepalive_sessions):
                  # if the session is busy inside a command, defer invoking
                  # keepalive until incommand is no longer the case
                  if parms['timeout'] < curtime and not session._isincommand():
                      cls.keepalive_sessions[session]['timeout'] = \
                          _monotonic_time() + MAX_IDLE - (random.random() * 4.9)
                      sessionstokeepalive.append(session)
          for session in sessionstokeepalive:
              session._keepalive()
          with util.protect(WAITING_SESSIONS):
              for session, parms in dictitems(cls.waiting_sessions):
                  if parms['timeout'] < curtime:  # timeout has expired, time to
                      # give up on it and trigger timeout
                      # response in the respective session
                      # defer deletion until after loop
                      sessionstodel.append(session)
                      # to avoid confusing the for loop
              for session in sessionstodel:
                  cls.waiting_sessions.pop(session, None)
              # one loop iteration to make sure recursion doesn't induce
              # redundant timeouts
              for session in sessionstodel:
                  session._timedout()
              return len(cls.waiting_sessions)