Rev 6174: Re-order the loop a bit. Move the exception handling into the loop, so that we can handle EINTR. in http://bazaar.launchpad.net/~jameinel/bzr/drop-idle-connections-824797
John Arbash Meinel
john at arbash-meinel.com
Wed Sep 21 11:47:59 UTC 2011
At http://bazaar.launchpad.net/~jameinel/bzr/drop-idle-connections-824797
------------------------------------------------------------
revno: 6174
revision-id: john at arbash-meinel.com-20110921114746-rxal7pr14l1a3gjn
parent: john at arbash-meinel.com-20110919105225-cn62n2zi3aj5efdm
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: drop-idle-connections-824797
timestamp: Wed 2011-09-21 13:47:46 +0200
message:
Re-order the loop a bit. Move the exception handling into the loop, so that we can handle EINTR.
Break out of the loop on 'xs'.
Clean up the code a bit, remove comments in favor of doc strings, and hopefully
reasonably easy-to-understand structure.
-------------- next part --------------
=== modified file 'bzrlib/smart/medium.py'
--- a/bzrlib/smart/medium.py 2011-09-19 10:52:25 +0000
+++ b/bzrlib/smart/medium.py 2011-09-21 11:47:46 +0000
@@ -282,37 +282,30 @@
return protocol
def _wait_on_descriptor(self, fd, timeout_seconds):
- """select() on a file descriptor, waiting for nonblocking read()"""
- # Use local variables to handle when the interpreter is shutting down
- try:
- # It looks like during the test suite, we close the server-side
- # socket as part of 'shut down this server'. Depending on how
- # we race with select.select, that either
- # 1) Raises socket.error(EBADF) immediately
- # 2) Occasionally (1 in 1000 or so) raises select.error(EBADF)
- # 3) 1-in-3 or so times out, calling select.select immediately
- # afterwards seems to raise EBADF.
- # I think what happens is select.select is unable to see the
- # status of a file that is closed after it starts 'sleeping'.
- t_end = time.time() + timeout_seconds
- poll_timeout = min(timeout_seconds, self._client_poll_timeout)
- rs = []
- while not rs and time.time() < t_end:
+ """select() on a file descriptor, waiting for nonblocking read()
+
+ :return: Did we time out before fd is ready to read? (Note that ready
+ to read may be either that there is data to be read, or that the
+ descriptor is already closed, or there is a pending error.)
+ """
+ t_end = time.time() + timeout_seconds
+ poll_timeout = min(timeout_seconds, self._client_poll_timeout)
+ rs = xs = None
+ while not rs and not xs and time.time() < t_end:
+ try:
rs, _, xs = select.select([fd], [], [fd], poll_timeout)
- except (select.error, socket.error) as e:
- err = getattr(e, 'errno', None)
- if err is None:
- # select.error doesn't have 'errno', it just has args[0]
- if getattr(e, 'args', None) is not None:
+ except (select.error, socket.error) as e:
+ err = getattr(e, 'errno', None)
+ if err is None and getattr(e, 'args', None) is not None:
+ # select.error doesn't have 'errno', it just has args[0]
err = e.args[0]
- if err in _bad_file_descriptor:
- # If we are told at this point that socket is no longer a valid
- # socket, just return 'without timeout'
- return False
- raise
+ if err in _bad_file_descriptor:
+ return False # Not a socket indicates read() will fail
+ elif err == errno.EINTR:
+ # Interrupted, keep looping.
+ continue
+ raise
if rs or xs:
- # Either we can read without blocking, or there is a pending error.
- # Either way, we didn't time out, so try to read from it.
return False
return True
More information about the bazaar-commits
mailing list