summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Liechti <cliechti@gmx.net>2016-09-02 22:32:37 +0200
committerChris Liechti <cliechti@gmx.net>2016-09-02 22:32:37 +0200
commit514f76c7e5265a7db79514271e4c3d8438ba53e9 (patch)
treeb3dc4843feeaa93091290dfdb3fc56d34cf473fe
parentf01972586624a8240a42daeeb452c19001d78ba4 (diff)
downloadpyserial-git-514f76c7e5265a7db79514271e4c3d8438ba53e9.tar.gz
serialutil: use monotonic clock for timeouts, if available
-rw-r--r--serial/serialutil.py25
1 files changed, 18 insertions, 7 deletions
diff --git a/serial/serialutil.py b/serial/serialutil.py
index 2ed2787..9775469 100644
--- a/serial/serialutil.py
+++ b/serial/serialutil.py
@@ -106,22 +106,33 @@ portNotOpenError = SerialException('Attempting to use a port that is not open')
class Timeout(object):
"""\
- Timeout implementation with time.time(). This is compatible with all
- Python versions but has issues if the clock is adjusted while the
- timeout is running.
+ Abstraction for timeout operations. Using time.monotonic() if available
+ or time.time() in all other cases.
"""
+ if hasattr(time, 'monotonic'):
+ # Timeout implementation with time.monotonic(). This function is only
+ # supported by Python 3.3 and above. It returns a time in seconds
+ # (float) just as time.time(), but is not affected by system clock
+ # adjustments.
+ TIME = time.monotonic
+ else:
+ # Timeout implementation with time.time(). This is compatible with all
+ # Python versions but has issues if the clock is adjusted while the
+ # timeout is running.
+ TIME = time.time
+
def __init__(self, duration):
"""Initialize a timeout with given duration"""
self.is_infinite = (duration is None)
self.is_non_blocking = (duration == 0)
if duration is not None:
- self.target_time = time.time() + duration
+ self.target_time = self.TIME() + duration
else:
self.target_time = None
def expired(self):
"""Return a boolean if the timeout has expired"""
- return self.target_time is not None and time.time() > self.target_time
+ return self.target_time is not None and self.TIME() > self.target_time
def time_left(self):
"""Return how many seconds are left until the timeout expires"""
@@ -130,10 +141,10 @@ class Timeout(object):
elif self.is_infinite:
return None
else:
- return max(0, self.target_time - time.time())
+ return max(0, self.target_time - self.TIME())
def restart(self, duration):
- self.target_time = time.time() + duration
+ self.target_time = self.TIME() + duration
class SerialBase(io.RawIOBase):