cpython: 76d297869859 (original) (raw)
Mercurial > cpython
changeset 95315:76d297869859
Issue #23485: Enhance and update selectors doc and test_selectors Selector.select() is now retried with the recomputed timeout when interrupted by a signal. Write an unit test with a signal handler raising an exception, and a unit with a signal handler which does not raise an exception (it does nothing). [#23485]
Victor Stinner victor.stinner@gmail.com | |
---|---|
date | Tue, 31 Mar 2015 12:08:09 +0200 |
parents | f54bc2c52dfd |
children | 475461033bb2 |
files | Doc/library/selectors.rst Lib/test/test_selectors.py |
diffstat | 2 files changed, 40 insertions(+), 3 deletions(-)[+] [-] Doc/library/selectors.rst 6 Lib/test/test_selectors.py 37 |
line wrap: on
line diff
--- a/Doc/library/selectors.rst +++ b/Doc/library/selectors.rst @@ -159,6 +159,12 @@ below: timeout has elapsed if the current process receives a signal: in this case, an empty list will be returned.
.. versionchanged:: 3.5[](#l1.7)
The selector is now retried with a recomputed timeout when interrupted[](#l1.8)
by a signal if the signal handler did not raise an exception (see[](#l1.9)
:pep:`475` for the rationale), instead of returning an empty list[](#l1.10)
of events before the timeout.[](#l1.11)
+ .. method:: close() Close the selector.
--- a/Lib/test/test_selectors.py +++ b/Lib/test/test_selectors.py @@ -357,7 +357,35 @@ class BaseSelectorTestCase(unittest.Test @unittest.skipUnless(hasattr(signal, "alarm"), "signal.alarm() required for this test")
- def test_select_interrupt_exc(self):
s = self.SELECTOR()[](#l2.9)
self.addCleanup(s.close)[](#l2.10)
rd, wr = self.make_socketpair()[](#l2.12)
class InterruptSelect(Exception):[](#l2.14)
pass[](#l2.15)
def handler(*args):[](#l2.17)
raise InterruptSelect[](#l2.18)
orig_alrm_handler = signal.signal(signal.SIGALRM, handler)[](#l2.20)
self.addCleanup(signal.signal, signal.SIGALRM, orig_alrm_handler)[](#l2.21)
self.addCleanup(signal.alarm, 0)[](#l2.22)
signal.alarm(1)[](#l2.24)
s.register(rd, selectors.EVENT_READ)[](#l2.26)
t = time()[](#l2.27)
# select() is interrupted by a signal which raises an exception[](#l2.28)
with self.assertRaises(InterruptSelect):[](#l2.29)
s.select(30)[](#l2.30)
# select() was interrupted before the timeout of 30 seconds[](#l2.31)
self.assertLess(time() - t, 5.0)[](#l2.32)
- @unittest.skipUnless(hasattr(signal, "alarm"),
"signal.alarm() required for this test")[](#l2.35)
- def test_select_interrupt_noraise(self): s = self.SELECTOR() self.addCleanup(s.close)
@@ -371,8 +399,11 @@ class BaseSelectorTestCase(unittest.Test s.register(rd, selectors.EVENT_READ) t = time()
self.assertFalse(s.select(2))[](#l2.44)
self.assertLess(time() - t, 2.5)[](#l2.45)
# select() is interrupted by a signal, but the signal handler doesn't[](#l2.46)
# raise an exception, so select() should by retries with a recomputed[](#l2.47)
# timeout[](#l2.48)
self.assertFalse(s.select(1.5))[](#l2.49)
self.assertGreaterEqual(time() - t, 1.0)[](#l2.50)