(original) (raw)
diff -r 83e110399f3c Lib/selectors.py --- a/Lib/selectors.py Fri Jan 31 10:55:55 2014 +0100 +++ b/Lib/selectors.py Fri Jan 31 11:24:30 2014 +0100 @@ -41,6 +41,35 @@ def _fileobj_to_fd(fileobj): raise ValueError("Invalid file descriptor: {}".format(fd)) return fd +if sys.platform == 'linux': + def _get_resolution(c_struct_res): + try: + release = os.uname().release + release = release.split('-', 1)[0] + release = tuple(map(int, release.split('.'))) + if release < (2, 6, 28): + # Get the number of clock ticks in the kernel (the "HZ" + # constant), usually 100, 250 or 1000 + clock_ticks = os.sysconfig('SC_CLK_TCK') + kernel_timeout_res = 1 / clock_ticks + + # On Linux older than 2.6.28, select(), poll() and epoll() use + # kernel jiffies and so a resolution of 1/HZ + # http://lwn.net/Articles/296578/ + # https://lkml.org/lkml/2008/9/20/136 + # + # Since Linux 2.6.28, the kernel uses hrtimes for timeouts: + # https://www.kernel.org/doc/Documentation/timers/hrtimers.txt + return max(kernel_timeout_res, c_struct_res) + except ValueError: + # failed to parse the kernel release or to get SC_CLK_TCK + pass + return c_struct_res +else: + def _get_resolution(c_struct_res): + return c_struct_res + + SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data']) """Object used to associate a file object to its backing file descriptor, @@ -290,7 +319,7 @@ class SelectSelector(_BaseSelectorImpl): @property def resolution(self): - return 1e-6 + return _get_resolution(1e-6) def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) @@ -346,7 +375,7 @@ if hasattr(select, 'poll'): @property def resolution(self): - return 1e-3 + return _get_resolution(1e-3) def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) @@ -400,7 +429,7 @@ if hasattr(select, 'epoll'): @property def resolution(self): - return 1e-3 + return _get_resolution(1e-3) def fileno(self): return self._epoll.fileno()