diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4 index 613f01ddf5..c36e9e01d6 100644 --- a/config-scripts/cups-common.m4 +++ b/config-scripts/cups-common.m4 @@ -224,6 +224,8 @@ AC_COMPILE_IFELSE([ dnl See if we have the removefile(3) function for securely removing files AC_CHECK_FUNCS([removefile]) +dnl See if + dnl See if we have libusb... AC_ARG_ENABLE([libusb], AS_HELP_STRING([--enable-libusb], [use libusb for USB printing])) @@ -448,6 +450,22 @@ AC_DEFINE_UNQUOTED([CUPS_DEFAULT_SYSTEM_AUTHKEY], ["$CUPS_DEFAULT_SYSTEM_AUTHKEY AC_SUBST([CUPS_SYSTEM_AUTHKEY]) AC_SUBST([INSTALLXPC]) +dnl Check if monotonic clock is available +AC_MSG_CHECKING([for monotonic clock]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([ + #include + #include + ],[ + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + ]) +],[ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_CLOCK_MONOTONIC) +],[ + AC_MSG_RESULT([no]) +]) + dnl Check for build components COMPONENTS="all" diff --git a/configure b/configure index f9037fddbc..ce04b013d6 100755 --- a/configure +++ b/configure @@ -6465,6 +6465,7 @@ then : fi + # Check whether --enable-libusb was given. if test ${enable_libusb+y} then : @@ -7077,6 +7078,43 @@ printf "%s\n" "#define CUPS_DEFAULT_SYSTEM_AUTHKEY \"$CUPS_DEFAULT_SYSTEM_AUTHKE +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for monotonic clock" >&5 +printf %s "checking for monotonic clock... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + +int +main (void) +{ + + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + printf "%s\n" "#define HAVE_CLOCK_MONOTONIC 1" >>confdefs.h + + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + COMPONENTS="all" diff --git a/cups/dest.c b/cups/dest.c index 3eeb509337..b2d8344506 100644 --- a/cups/dest.c +++ b/cups/dest.c @@ -16,6 +16,7 @@ #include "cups-private.h" #include "debug-internal.h" #include +#include #ifdef HAVE_NOTIFY_H # include @@ -137,6 +138,18 @@ typedef struct _cups_namedata_s cups_dest_t *dest; /* Destination */ } _cups_namedata_t; +typedef struct _cups_time_s +{ +#if _WIN32 + DWORD t; +#elif HAVE_CLOCK_MONOTONIC + struct timespec t; +#elif __sun + hrtime_t t; +#else + struct timeval t; +#endif +} _cups_time_t; /* * Local functions... @@ -222,7 +235,8 @@ static const char *cups_dnssd_resolve(cups_dest_t *dest, const char *uri, static int cups_dnssd_resolve_cb(void *context); static void cups_dnssd_unquote(char *dst, const char *src, size_t dstsize); -static int cups_elapsed(struct timeval *t); +static void cups_gettimeofday(_cups_time_t *t); +static int cups_elapsed(_cups_time_t *t); #endif /* HAVE_DNSSD */ static int cups_enum_dests(http_t *http, unsigned flags, int msec, int *cancel, cups_ptype_t type, cups_ptype_t mask, cups_dest_cb_t cb, void *user_data); static int cups_find_dest(const char *name, const char *instance, @@ -3399,22 +3413,63 @@ cups_dnssd_unquote(char *dst, /* I - Destination buffer */ } +/* + * 'cups_gettimeofday()' - Get the sharpest time possible + */ + +static void +cups_gettimeofday(_cups_time_t *t) +{ +#if _WIN32 + t->t = GetTickCount(); +#elif HAVE_CLOCK_MONOTONIC + clock_gettime(CLOCK_MONOTONIC, &t->t); +#elif __sun + t->t = gethrtime(); +#else + gettimeofday(&t->t, NULL); +#endif +} + /* * 'cups_elapsed()' - Return the elapsed time in milliseconds. */ static int /* O - Elapsed time in milliseconds */ -cups_elapsed(struct timeval *t) /* IO - Previous time */ +cups_elapsed(_cups_time_t *t) // IO - Previous time { int msecs; /* Milliseconds */ - struct timeval nt; /* New time */ +#if _WIN32 + DWORD cur = GetTickCount(); + + msecs = (int)(cur - t->t); + + t->t = cur; + +#elif HAVE_CLOCK_MONOTONIC + struct timespec nt; // New time + + clock_gettime(CLOCK_MONOTONIC, &nt); + + msecs = (int)(1000 * (nt.tv_sec - t->t.tv_sec) + (nt.tv_nsec - t->t.tv_nsec) / 1000000); + + *t->t = nt; +#elif __sun + hrtime_t cur = gethrtime(); + + msecs = (int)(cur - t->t); + + t->t = cur; +#else + struct timeval nt; gettimeofday(&nt, NULL); - msecs = (int)(1000 * (nt.tv_sec - t->tv_sec) + (nt.tv_usec - t->tv_usec) / 1000); + msecs = (int)(1000 * (nt.tv_sec - t->t.tv_sec) + (nt.tv_usec - t->t.tv_usec) / 1000); - *t = nt; + *t->t = nt; +#endif return (msecs); } @@ -3446,7 +3501,7 @@ cups_enum_dests( int count, /* Number of queries started */ completed, /* Number of completed queries */ remaining; /* Remainder of timeout */ - struct timeval curtime; /* Current time */ + _cups_time_t curtime; // Current time _cups_dnssd_data_t data; /* Data for callback */ _cups_dnssd_device_t *device; /* Current device */ # ifdef HAVE_MDNSRESPONDER @@ -3672,7 +3727,7 @@ cups_enum_dests( * Get Bonjour-shared printers... */ - gettimeofday(&curtime, NULL); + cups_gettimeofday(&curtime); # ifdef HAVE_MDNSRESPONDER if (DNSServiceCreateConnection(&data.main_ref) != kDNSServiceErr_NoError)