Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dest.c: Use monotonic time for cups_enum_dest #1084

Open
wants to merge 3 commits into
base: 2.4.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions config-scripts/cups-common.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

???


dnl See if we have libusb...
AC_ARG_ENABLE([libusb], AS_HELP_STRING([--enable-libusb], [use libusb for USB printing]))

Expand Down Expand Up @@ -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([
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be enough to check that CLOCK_MONOTONIC is defined. CUPS requires POSIX compliance.

#include <stdlib.h>
#include <time.h>
],[
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"

Expand Down
38 changes: 38 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -6465,6 +6465,7 @@ then :
fi



# Check whether --enable-libusb was given.
if test ${enable_libusb+y}
then :
Expand Down Expand Up @@ -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 <stdlib.h>
#include <time.h>

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"


Expand Down
67 changes: 61 additions & 6 deletions cups/dest.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd actually like to do away with this kind of structure here - let's just use a double to return "elapsed time" and then we can use simple math operations portably across platforms.

#elif HAVE_CLOCK_MONOTONIC
struct timespec t;
#elif __sun
hrtime_t t;
#else
struct timeval t;
#endif
} _cups_time_t;

/*
* Local functions...
Expand Down Expand Up @@ -223,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 timespec *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,
Expand Down Expand Up @@ -3400,21 +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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to use GetTickCount64, otherwise we have a 49 day wrap problem.

#elif HAVE_CLOCK_MONOTONIC
clock_gettime(CLOCK_MONOTONIC, &t->t);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if CLOCK_MONOTONIC is defined, that doesn't mean that the platform will support that clock. Check for a non-zero return and fallback on gettimeofday when it fails.

#elif __sun
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not bother with Solaris-specific functions. We don't have any Solaris testing resources.

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 timespec *t) // IO - Previous time
cups_elapsed(_cups_time_t *t) // IO - Previous time
{
int msecs; /* Milliseconds */

#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->tv_sec) + (nt.tv_nsec - t->tv_nsec) / 1000 / 1000);
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();

*t = nt;
msecs = (int)(cur - t->t);

t->t = cur;
#else
struct timeval nt;

gettimeofday(&nt, NULL);

msecs = (int)(1000 * (nt.tv_sec - t->t.tv_sec) + (nt.tv_usec - t->t.tv_usec) / 1000);

*t->t = nt;
#endif

return (msecs);
}
Expand Down Expand Up @@ -3446,7 +3501,7 @@ cups_enum_dests(
int count, /* Number of queries started */
completed, /* Number of completed queries */
remaining; /* Remainder of timeout */
struct timespec 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
Expand Down Expand Up @@ -3672,7 +3727,7 @@ cups_enum_dests(
* Get Bonjour-shared printers...
*/

clock_gettime(CLOCK_MONOTONIC, &curtime);
cups_gettimeofday(&curtime);

# ifdef HAVE_MDNSRESPONDER
if (DNSServiceCreateConnection(&data.main_ref) != kDNSServiceErr_NoError)
Expand Down
Loading