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
|