summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSa?l Ibarra Corretg? <saghul@gmail.com>2013-03-24 21:33:50 +0100
committerSa?l Ibarra Corretg? <saghul@gmail.com>2013-03-24 21:33:50 +0100
commit87133f47a4f065376c89edeb4bd61b5b93c72e77 (patch)
treeaa82193340ea851702f3a6a95f53c4878f043428
parentd271236042b4eb088c10370a9e70cd6b3b6c85e1 (diff)
downloadtrollius-87133f47a4f065376c89edeb4bd61b5b93c72e77.tar.gz
Don't skip polling even if the self-pipe is th eonly registered fd
-rw-r--r--tests/events_test.py24
-rw-r--r--tulip/base_events.py47
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()