[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [Libevent-users] a dead looping bug when changing system time backward
On Tue, Apr 10, 2012 at 11:44:39AM +0800, ååé wrote:
> Hi all,
>
> I found an issue that it will trigger the timer callback dramatically
> like a dead looping when moving the system time backward for a year
> and then moving it forward to the accurate time.
AFAICT, the libevent 2.x code uses clock_gettime(CLOCK_MONOTONIC) if
available.
Does your system provide CLOCK_MONOTONIC? Most do (including the ones I use
the most, Linux and OpenBSD). One notable exception is OS X. But OS X _does_
provide a monotonic counter. If you're using OS X, try this compat wrapper:
/*
* clock_gettime()
*
* OS X doesn't implement the clock_gettime() POSIX interface, but does
* provide a monotonic clock through mach_absolute_time(). On i386 and
* x86_64 architectures this clock is in nanosecond units, but not so on
* other devices. mach_timebase_info() provides the conversion parameters.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#if __APPLE__
#include <time.h> /* struct timespec */
#include <errno.h> /* errno EINVAL */
#include <sys/time.h> /* TIMEVAL_TO_TIMESPEC struct timeval gettimeofday(3) */
#include <mach/mach_time.h> /* mach_timebase_info_data_t mach_timebase_info() mach_absolute_time() */
#define CLOCK_REALTIME 0
#define CLOCK_VIRTUAL 1
#define CLOCK_PROF 2
#define CLOCK_MONOTONIC 3
static mach_timebase_info_data_t clock_timebase = {
.numer = 1, .denom = 1,
}; /* clock_timebase */
void clock_gettime_init(void) __attribute__((constructor));
void clock_gettime_init(void) {
if (mach_timebase_info(&clock_timebase) != KERN_SUCCESS)
__builtin_abort();
} /* clock_gettime_init() */
static int clock_gettime(int clockid, struct timespec *ts) {
switch (clockid) {
case CLOCK_REALTIME: {
struct timeval tv;
if (0 != gettimeofday(&tv, 0))
return -1;
TIMEVAL_TO_TIMESPEC(&tv, ts);
return 0;
}
case CLOCK_MONOTONIC: {
unsigned long long abt;
abt = mach_absolute_time();
abt = abt * clock_timebase.numer / clock_timebase.denom;
ts->tv_sec = abt / 1000000000UL;
ts->tv_nsec = abt % 1000000000UL;
return 0;
}
default:
errno = EINVAL;
return -1;
} /* switch() */
} /* clock_gettime() */
#endif /* __APPLE__ */
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users in the body.