Revision dfdc4060

b/lib/http/__init__.py
361 361
      else:
362 362
        wait_for_event = event_poll
363 363

  
364
      event = utils.WaitForSocketCondition(sock, wait_for_event, timeout)
364
      event = utils.WaitForFdCondition(sock, wait_for_event, timeout)
365 365
      if event is None:
366 366
        raise HttpSocketTimeout()
367 367

  
b/lib/http/client.py
250 250

  
251 251
    if not connected:
252 252
      # Wait for connection
253
      event = utils.WaitForSocketCondition(self.sock, select.POLLOUT,
254
                                           self.CONNECT_TIMEOUT)
253
      event = utils.WaitForFdCondition(self.sock, select.POLLOUT,
254
                                       self.CONNECT_TIMEOUT)
255 255
      if event is None:
256 256
        raise http.HttpError("Timeout while connecting to server")
257 257

  
b/lib/utils.py
1497 1497
    return False
1498 1498

  
1499 1499

  
1500
def WaitForSocketCondition(sock, event, timeout):
1500
def SingleWaitForFdCondition(fdobj, event, timeout):
1501 1501
  """Waits for a condition to occur on the socket.
1502 1502

  
1503
  @type sock: socket
1504
  @param sock: Wait for events on this socket
1505
  @type event: int
1503
  Immediately returns at the first interruption.
1504

  
1505
  @type fdobj: integer or object supporting a fileno() method
1506
  @param fdobj: entity to wait for events on
1507
  @type event: integer
1506 1508
  @param event: ORed condition (see select module)
1507 1509
  @type timeout: float or None
1508 1510
  @param timeout: Timeout in seconds
......
1518 1520
    timeout *= 1000
1519 1521

  
1520 1522
  poller = select.poll()
1521
  poller.register(sock, event)
1523
  poller.register(fdobj, event)
1522 1524
  try:
1523
    while True:
1524
      # TODO: If the main thread receives a signal and we have no timeout, we
1525
      # could wait forever. This should check a global "quit" flag or
1526
      # something every so often.
1527
      io_events = poller.poll(timeout)
1528
      if not io_events:
1529
        # Timeout
1530
        return None
1531
      for (_, evcond) in io_events:
1532
        if evcond & check:
1533
          return evcond
1534
  finally:
1535
    poller.unregister(sock)
1525
    # TODO: If the main thread receives a signal and we have no timeout, we
1526
    # could wait forever. This should check a global "quit" flag or something
1527
    # every so often.
1528
    io_events = poller.poll(timeout)
1529
  except select.error, err:
1530
    if err[0] != errno.EINTR:
1531
      raise
1532
    io_events = []
1533
  if io_events and io_events[0][1] & check:
1534
    return io_events[0][1]
1535
  else:
1536
    return None
1537

  
1538

  
1539
class FdConditionWaiterHelper(object):
1540
  """Retry helper for WaitForFdCondition.
1541

  
1542
  This class contains the retried and wait functions that make sure
1543
  WaitForFdCondition can continue waiting until the timeout is actually
1544
  expired.
1545

  
1546
  """
1547

  
1548
  def __init__(self, timeout):
1549
    self.timeout = timeout
1550

  
1551
  def Poll(self, fdobj, event):
1552
    result = SingleWaitForFdCondition(fdobj, event, self.timeout)
1553
    if result is None:
1554
      raise RetryAgain()
1555
    else:
1556
      return result
1557

  
1558
  def UpdateTimeout(self, timeout):
1559
    self.timeout = timeout
1560

  
1561

  
1562
def WaitForFdCondition(fdobj, event, timeout):
1563
  """Waits for a condition to occur on the socket.
1564

  
1565
  Retries until the timeout is expired, even if interrupted.
1566

  
1567
  @type fdobj: integer or object supporting a fileno() method
1568
  @param fdobj: entity to wait for events on
1569
  @type event: integer
1570
  @param event: ORed condition (see select module)
1571
  @type timeout: float or None
1572
  @param timeout: Timeout in seconds
1573
  @rtype: int or None
1574
  @return: None for timeout, otherwise occured conditions
1575

  
1576
  """
1577
  if timeout is not None:
1578
    retrywaiter = FdConditionWaiterHelper(timeout)
1579
    result = Retry(retrywaiter.Poll, RETRY_REMAINING_TIME, timeout,
1580
                   args=(fdobj, event), wait_fn=retrywaiter.UpdateTimeout)
1581
  else:
1582
    result = None
1583
    while result is None:
1584
      result = SingleWaitForFdCondition(fdobj, event, timeout)
1585
  return result
1536 1586

  
1537 1587

  
1538 1588
def partition(seq, pred=bool): # # pylint: disable-msg=W0622

Also available in: Unified diff