Revision dfdc4060 lib/utils.py
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