summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorDavi Arnaut <davi.arnaut@oracle.com>2011-01-11 11:44:38 -0200
committerDavi Arnaut <davi.arnaut@oracle.com>2011-01-11 11:44:38 -0200
commitc4c94ea0ac2141d70cb7225cdb8f30320dc73f08 (patch)
tree066f22f8de563b315219bd939d9b591057d1c1f9 /mysys
parent0a7cfad0804ab912d185c9478872b990783932bd (diff)
downloadmariadb-git-c4c94ea0ac2141d70cb7225cdb8f30320dc73f08.tar.gz
Bug#42054: SELECT CURDATE() is returning bad value
The problem from a user point of view was that on Solaris the time related functions (e.g. NOW(), SYSDATE(), etc) would always return a fixed time. This bug was happening due to a logic in the time retrieving wrapper function which would only call the time() function every half second. This interval between calls would be calculated using the gethrtime() and the logic relied on the fact that time returned by it is monotonic. Unfortunately, due to bugs in the gethrtime() implementation, there are some cases where the time returned by it can drift (See Solaris bug id 6600939), potentially causing the interval calculation logic to fail. The solution is to retrieve the correct time whenever a drift in the time returned by gethrtime() is detected. That is, do not use the cached time whenever the values (previous and current) returned by gethrtime() are not monotonically increasing. mysys/my_getsystime.c: Do not used the cached time if gethrtime is not monotonic.
Diffstat (limited to 'mysys')
-rw-r--r--mysys/my_getsystime.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c
index b692b18bfc7..dfd99f6380d 100644
--- a/mysys/my_getsystime.c
+++ b/mysys/my_getsystime.c
@@ -170,7 +170,13 @@ ulonglong my_micro_time_and_time(time_t *time_arg)
pthread_mutex_lock(&THR_LOCK_time);
cur_gethrtime= gethrtime();
- if ((cur_gethrtime - prev_gethrtime) > DELTA_FOR_SECONDS)
+ /*
+ Due to bugs in the Solaris (x86) implementation of gethrtime(),
+ the time returned by it might not be monotonic. Don't use the
+ cached time(2) value if this is a case.
+ */
+ if ((prev_gethrtime > cur_gethrtime) ||
+ ((cur_gethrtime - prev_gethrtime) > DELTA_FOR_SECONDS))
{
cur_time= time(0);
prev_gethrtime= cur_gethrtime;