mirror of
https://github.com/openvswitch/ovs
synced 2025-10-19 14:37:21 +00:00
Python's time.time() function uses the system wall clock. However, if NTP resets the wall clock to be a time in the past, then this causes any applications that poll block based on time, such as ovs-xapi-sync, to poll block indefinitely since the time is unexpectedly negative. This patch fixes the issue by using time.monotonic() if Python's version >= 3.3. Otherwise, the timeval module calls out to the librt C shared library and uses the clock_gettime function with CLOCK_MONOTONIC. Note this is only enabled on Linux-based platforms. This has been tested on Ubuntu 12.04 and Redhat 6.4. Bug #1189434 Signed-off-by: Ryan Wilson <wryan@nicira.com> Acked-by: Ethan Jackson <ethan@nicira.com>
59 lines
1.6 KiB
Python
59 lines
1.6 KiB
Python
# Copyright (c) 2009, 2010 Nicira, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at:
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import ctypes
|
|
import sys
|
|
import time
|
|
|
|
LIBRT = 'librt.so.1'
|
|
CLOCK_MONOTONIC = 1
|
|
|
|
class timespec(ctypes.Structure):
|
|
_fields_ = [
|
|
('tv_sec', ctypes.c_long),
|
|
('tv_nsec', ctypes.c_long),
|
|
]
|
|
|
|
try:
|
|
librt = ctypes.CDLL(LIBRT)
|
|
clock_gettime = librt.clock_gettime
|
|
clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(timespec)]
|
|
except:
|
|
# Librt shared library could not be loaded
|
|
librt = None
|
|
|
|
def monotonic():
|
|
if not librt:
|
|
return time.time()
|
|
|
|
t = timespec()
|
|
if clock_gettime(CLOCK_MONOTONIC, ctypes.pointer(t)) == 0:
|
|
return t.tv_sec + t.tv_nsec * 1e-9
|
|
# Kernel does not support CLOCK_MONOTONIC
|
|
return time.time()
|
|
|
|
# Use time.monotonic() if Python version >= 3.3
|
|
if not hasattr(time, 'monotonic'):
|
|
time.monotonic = monotonic
|
|
|
|
def msec():
|
|
"""Returns the current time, as the amount of time since the epoch, in
|
|
milliseconds, as a float."""
|
|
return time.monotonic() * 1000.0
|
|
|
|
|
|
def postfork():
|
|
# Just a stub for now
|
|
pass
|