diff options
author | Sa?l Ibarra Corretg? <saghul@gmail.com> | 2013-03-24 21:33:50 +0100 |
---|---|---|
committer | Sa?l Ibarra Corretg? <saghul@gmail.com> | 2013-03-24 21:33:50 +0100 |
commit | 87133f47a4f065376c89edeb4bd61b5b93c72e77 (patch) | |
tree | aa82193340ea851702f3a6a95f53c4878f043428 | |
parent | d271236042b4eb088c10370a9e70cd6b3b6c85e1 (diff) | |
download | trollius-87133f47a4f065376c89edeb4bd61b5b93c72e77.tar.gz |
Don't skip polling even if the self-pipe is th eonly registered fd
-rw-r--r-- | tests/events_test.py | 24 | ||||
-rw-r--r-- | tulip/base_events.py | 47 |
2 files changed, 43 insertions, 28 deletions
diff --git a/tests/events_test.py b/tests/events_test.py index 7a64012..4085921 100644 --- a/tests/events_test.py +++ b/tests/events_test.py @@ -216,6 +216,26 @@ class EventLoopTestsMixin: self.event_loop.run_until_complete(tasks.Task(coro())) self.assertIsInstance(err, RuntimeError) + def test_run_once_block(self): + called = False + + def callback(): + nonlocal called + called = True + + def run(): + time.sleep(0.1) + self.event_loop.call_soon_threadsafe(callback) + + t = threading.Thread(target=run) + t0 = time.monotonic() + t.start() + self.event_loop.run_once(None) + t1 = time.monotonic() + t.join() + self.assertTrue(called) + self.assertTrue(0.09 < t1-t0 <= 0.12) + def test_call_later(self): results = [] @@ -819,9 +839,9 @@ class EventLoopTestsMixin: self.assertEqual('INITIALIZED', client.state) transport.sendto(b'xxx') - self.event_loop.run_once() + self.event_loop.run_once(None) self.assertEqual(3, server.nbytes) - self.event_loop.run_once() + self.event_loop.run_once(None) # received self.assertEqual(8, client.nbytes) diff --git a/tulip/base_events.py b/tulip/base_events.py index 0b55ee4..573807d 100644 --- a/tulip/base_events.py +++ b/tulip/base_events.py @@ -126,7 +126,7 @@ class BaseEventLoop(events.AbstractEventLoop): finally: handle.cancel() - def run_once(self, timeout=None): + def run_once(self, timeout=0): """Run through all callbacks and all I/O polls once. Calling stop() will break out of this too. @@ -503,32 +503,27 @@ class BaseEventLoop(events.AbstractEventLoop): while self._scheduled and self._scheduled[0].cancelled: heapq.heappop(self._scheduled) - # Inspect the poll queue. If there's exactly one selectable - # file descriptor, it's the self-pipe, and if there's nothing - # scheduled, we should ignore it. - if (self._scheduled or - self._selector.registered_count() > self._internal_fds): - if self._ready: - timeout = 0 - elif self._scheduled: - # Compute the desired timeout. - when = self._scheduled[0].when - deadline = max(0, when - time.monotonic()) - if timeout is None: - timeout = deadline - else: - timeout = min(timeout, deadline) - - t0 = time.monotonic() - event_list = self._selector.select(timeout) - t1 = time.monotonic() - argstr = '' if timeout is None else ' %.3f' % timeout - if t1-t0 >= 1: - level = logging.INFO + if self._ready: + timeout = 0 + elif self._scheduled: + # Compute the desired timeout. + when = self._scheduled[0].when + deadline = max(0, when - time.monotonic()) + if timeout is None: + timeout = deadline else: - level = logging.DEBUG - logging.log(level, 'poll%s took %.3f seconds', argstr, t1-t0) - self._process_events(event_list) + timeout = min(timeout, deadline) + + t0 = time.monotonic() + event_list = self._selector.select(timeout) + t1 = time.monotonic() + argstr = '' if timeout is None else ' %.3f' % timeout + if t1-t0 >= 1: + level = logging.INFO + else: + level = logging.DEBUG + logging.log(level, 'poll%s took %.3f seconds', argstr, t1-t0) + self._process_events(event_list) # Handle 'later' callbacks that are ready. now = time.monotonic() |