summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/asyncio-eventloop.rst13
-rw-r--r--Doc/library/selectors.rst4
-rw-r--r--Lib/asyncio/base_events.py13
-rw-r--r--Lib/asyncio/proactor_events.py1
-rw-r--r--Lib/asyncio/selector_events.py1
-rw-r--r--Lib/selectors.py21
-rw-r--r--Lib/test/test_asyncio/test_base_events.py3
-rw-r--r--Lib/test/test_asyncio/test_events.py23
-rw-r--r--Lib/test/test_selectors.py5
9 files changed, 10 insertions, 74 deletions
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst
index 6c3c2df..507d5e3 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -118,19 +118,6 @@ Which clock is used depends on the (platform-specific) event loop
implementation; ideally it is a monotonic clock. This will generally be
a different clock than :func:`time.time`.
-The granularity of the event loop depends on the resolution of the
-:meth:`~BaseEventLoop.time` method and the resolution of the selector. It is
-usually between 1 ms and 16 ms. For example, a granularity of 1 ms means that
-in the best case, the difference between the expected delay and the real
-elapsed time is between -1 ms and +1 ms: a call scheduled in 1 nanosecond may
-be called in 1 ms, and a call scheduled in 100 ms may be called in 99 ms.
-
-The granularity is the best difference in theory. In practice, it depends on
-the system load and the the time taken by tasks executed by the event loop.
-For example, if a task blocks the event loop for 1 second, all tasks scheduled
-in this second will be delayed. The :ref:`Handle correctly blocking functions
-<asyncio-handle-blocking>` section explains how to avoid such issue.
-
.. method:: BaseEventLoop.call_later(delay, callback, *args)
diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst
index 4c322bd..98377c8 100644
--- a/Doc/library/selectors.rst
+++ b/Doc/library/selectors.rst
@@ -98,10 +98,6 @@ below:
:class:`BaseSelector` and its concrete implementations support the
:term:`context manager` protocol.
- .. attribute:: resolution
-
- Resolution of the selector in seconds.
-
.. method:: register(fileobj, events, data=None)
Register a file object for selection, monitoring it for I/O events.
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index b9de8c7..db57ee8 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -96,7 +96,6 @@ class BaseEventLoop(events.AbstractEventLoop):
self._default_executor = None
self._internal_fds = 0
self._running = False
- self._granularity = time.get_clock_info('monotonic').resolution
def _make_socket_transport(self, sock, protocol, waiter=None, *,
extra=None, server=None):
@@ -634,21 +633,11 @@ class BaseEventLoop(events.AbstractEventLoop):
else:
logger.log(level, 'poll took %.3f seconds', t1-t0)
else:
- t0 = self.time()
event_list = self._selector.select(timeout)
- dt = self.time() - t0
- if timeout and not event_list and dt < timeout:
- print("%s.select(%.3f ms) took %.3f ms (granularity=%.3f ms, resolution=%.3f ms)"
- % (self._selector.__class__.__name__,
- timeout * 1e3,
- dt * 1e3,
- self._granularity * 1e3,
- self._selector.resolution * 1e3),
- file=sys.__stderr__)
self._process_events(event_list)
# Handle 'later' callbacks that are ready.
- now = self.time() + self._granularity
+ now = self.time()
while self._scheduled:
handle = self._scheduled[0]
if handle._when > now:
diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py
index 6b5707c..74566b2 100644
--- a/Lib/asyncio/proactor_events.py
+++ b/Lib/asyncio/proactor_events.py
@@ -365,7 +365,6 @@ class BaseProactorEventLoop(base_events.BaseEventLoop):
self._selector = proactor # convenient alias
self._self_reading_future = None
self._accept_futures = {} # socket file descriptor => Future
- self._granularity = max(proactor.resolution, self._granularity)
proactor.set_loop(self)
self._make_self_pipe()
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
index 3690145..202c14b 100644
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -36,7 +36,6 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
selector = selectors.DefaultSelector()
logger.debug('Using selector: %s', selector.__class__.__name__)
self._selector = selector
- self._granularity = max(selector.resolution, self._granularity)
self._make_self_pipe()
def _make_socket_transport(self, sock, protocol, waiter=None, *,
diff --git a/Lib/selectors.py b/Lib/selectors.py
index 056e45c..bb2a45a 100644
--- a/Lib/selectors.py
+++ b/Lib/selectors.py
@@ -83,11 +83,6 @@ class BaseSelector(metaclass=ABCMeta):
performant implementation on the current platform.
"""
- @abstractproperty
- def resolution(self):
- """Resolution of the selector in seconds"""
- return None
-
@abstractmethod
def register(self, fileobj, events, data=None):
"""Register a file object.
@@ -289,10 +284,6 @@ class SelectSelector(_BaseSelectorImpl):
self._readers = set()
self._writers = set()
- @property
- def resolution(self):
- return 1e-6
-
def register(self, fileobj, events, data=None):
key = super().register(fileobj, events, data)
if events & EVENT_READ:
@@ -345,10 +336,6 @@ if hasattr(select, 'poll'):
super().__init__()
self._poll = select.poll()
- @property
- def resolution(self):
- return 1e-3
-
def register(self, fileobj, events, data=None):
key = super().register(fileobj, events, data)
poll_events = 0
@@ -400,10 +387,6 @@ if hasattr(select, 'epoll'):
super().__init__()
self._epoll = select.epoll()
- @property
- def resolution(self):
- return 1e-3
-
def fileno(self):
return self._epoll.fileno()
@@ -468,10 +451,6 @@ if hasattr(select, 'kqueue'):
super().__init__()
self._kqueue = select.kqueue()
- @property
- def resolution(self):
- return 1e-9
-
def fileno(self):
return self._kqueue.fileno()
diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
index 0d90d3f..5b05684 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -124,7 +124,8 @@ class BaseEventLoopTests(unittest.TestCase):
self.loop.run_forever()
dt = self.loop.time() - t0
- self.assertGreaterEqual(dt, delay - self.loop._granularity, dt)
+ # 50 ms: maximum granularity of the event loop
+ self.assertGreaterEqual(dt, delay - 0.050, dt)
# tolerate a difference of +800 ms because some Python buildbots
# are really slow
self.assertLessEqual(dt, 0.9, dt)
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index c11d20f..c2988c0 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -1170,28 +1170,19 @@ class EventLoopTestsMixin:
orig_run_once = self.loop._run_once
self.loop._run_once_counter = 0
self.loop._run_once = _run_once
- calls = []
@asyncio.coroutine
def wait():
loop = self.loop
- calls.append(loop._run_once_counter)
- yield from asyncio.sleep(loop._granularity * 10, loop=loop)
- calls.append(loop._run_once_counter)
- yield from asyncio.sleep(loop._granularity / 10, loop=loop)
- calls.append(loop._run_once_counter)
+ yield from asyncio.sleep(1e-2, loop=loop)
+ yield from asyncio.sleep(1e-4, loop=loop)
self.loop.run_until_complete(wait())
- calls.append(self.loop._run_once_counter)
- self.assertEqual(calls, [1, 3, 5, 6])
-
- def test_granularity(self):
- granularity = self.loop._granularity
- self.assertGreater(granularity, 0.0)
- # Worst expected granularity: 1 ms on Linux (limited by poll/epoll
- # resolution), 15.6 ms on Windows (limited by time.monotonic
- # resolution)
- self.assertLess(granularity, 0.050)
+ # The ideal number of call is 6, but on some platforms, the selector
+ # may sleep at little bit less than timeout depending on the resolution
+ # of the clock used by the kernel. Tolerate 2 useless calls on these
+ # platforms.
+ self.assertLessEqual(self.loop._run_once_counter, 8)
class SubprocessTestsMixin:
diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py
index 5e55eee..34edd76 100644
--- a/Lib/test/test_selectors.py
+++ b/Lib/test/test_selectors.py
@@ -363,11 +363,6 @@ class BaseSelectorTestCase(unittest.TestCase):
self.assertFalse(s.select(2))
self.assertLess(time() - t, 2.5)
- def test_resolution(self):
- s = self.SELECTOR()
- self.assertIsInstance(s.resolution, (int, float))
- self.assertGreater(s.resolution, 0.0)
-
class ScalableSelectorMixIn: