File 0003-Avahi-fixes-for-cupsEnumDests.patch of Package cups.17820
From 3fae3b337df0be1a766857be741173d8a9915da7 Mon Sep 17 00:00:00 2001
From: Michael R Sweet <michael.r.sweet@gmail.com>
Date: Thu, 20 Apr 2017 10:12:40 -0400
Subject: [PATCH] Avahi fixes for cupsEnumDests (Issue #4989)
Also fix timeouts to track elapsed time so the timeout is more accurate.
---
cups/dest.c | 70 ++++++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 46 insertions(+), 24 deletions(-)
diff --git a/cups/dest.c b/cups/dest.c
index c1a0913..48758bf 100644
--- a/cups/dest.c
+++ b/cups/dest.c
@@ -60,6 +60,10 @@
# define kUseLastPrinter CFSTR("UseLastPrinter")
#endif /* __APPLE__ */
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+# define _CUPS_DNSSD_MAXTIME 500 /* Milliseconds for maximum quantum of time */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
+
/*
* Types...
@@ -211,6 +215,7 @@ static int cups_dnssd_resolve_cb(void *context);
static void cups_dnssd_unquote(char *dst, const char *src,
size_t dstsize);
#endif /* HAVE_DNSSD || HAVE_AVAHI */
+static int cups_elapsed(struct timeval *t);
static int cups_find_dest(const char *name, const char *instance,
int num_dests, cups_dest_t *dests, int prev,
int *rdiff);
@@ -942,6 +947,7 @@ cupsEnumDests(
int count, /* Number of queries started */
completed, /* Number of completed queries */
remaining; /* Remainder of timeout */
+ struct timeval curtime; /* Current time */
_cups_dnssd_data_t data; /* Data for callback */
_cups_dnssd_device_t *device; /* Current device */
# ifdef HAVE_DNSSD
@@ -1129,15 +1135,12 @@ cupsEnumDests(
return (1);
}
- data.browsers ++;
- ipp_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC,
- AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL,
- 0, cups_dnssd_browse_cb, &data);
+ data.browsers = 1;
+ ipp_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL, 0, cups_dnssd_browse_cb, &data);
+
# ifdef HAVE_SSL
data.browsers ++;
- ipps_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC,
- AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL,
- 0, cups_dnssd_browse_cb, &data);
+ ipps_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL, 0, cups_dnssd_browse_cb, &data);
# endif /* HAVE_SSL */
# endif /* HAVE_DNSSD */
@@ -1152,19 +1155,23 @@ cupsEnumDests(
* Check for input...
*/
+ DEBUG_printf(("1cupsEnumDests: remaining=%d", remaining));
+
+ cups_elapsed(&curtime);
+
# ifdef HAVE_DNSSD
# ifdef HAVE_POLL
pfd.fd = main_fd;
pfd.events = POLLIN;
- nfds = poll(&pfd, 1, remaining > 500 ? 500 : remaining);
+ nfds = poll(&pfd, 1, remaining > _CUPS_DNSSD_MAXTIME ? _CUPS_DNSSD_MAXTIME : remaining);
# else
FD_ZERO(&input);
FD_SET(main_fd, &input);
timeout.tv_sec = 0;
- timeout.tv_usec = remaining > 500 ? 500000 : remaining * 1000;
+ timeout.tv_usec = 1000 * (remaining > _CUPS_DNSSD_MAXTIME ? _CUPS_DNSSD_MAXTIME : remaining);
nfds = select(main_fd + 1, &input, NULL, NULL, &timeout);
# endif /* HAVE_POLL */
@@ -1175,7 +1182,7 @@ cupsEnumDests(
# else /* HAVE_AVAHI */
data.got_data = 0;
- if ((error = avahi_simple_poll_iterate(data.simple_poll, 1000)) > 0)
+ if ((error = avahi_simple_poll_iterate(data.simple_poll, _CUPS_DNSSD_MAXTIME)) > 0)
{
/*
* We've been told to exit the loop. Perhaps the connection to
@@ -1188,7 +1195,7 @@ cupsEnumDests(
DEBUG_printf(("1cupsEnumDests: got_data=%d", data.got_data));
# endif /* HAVE_DNSSD */
- remaining -= 500;
+ remaining -= cups_elapsed(&curtime);
for (device = (_cups_dnssd_device_t *)cupsArrayFirst(data.devices),
count = 0, completed = 0;
@@ -1227,17 +1234,9 @@ cupsEnumDests(
}
# else /* HAVE_AVAHI */
- if ((device->ref = avahi_record_browser_new(data.client,
- AVAHI_IF_UNSPEC,
- AVAHI_PROTO_UNSPEC,
- device->fullName,
- AVAHI_DNS_CLASS_IN,
- AVAHI_DNS_TYPE_TXT,
- 0,
- cups_dnssd_query_cb,
- &data)) != NULL)
+ if ((device->ref = avahi_record_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, device->fullName, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT, 0, cups_dnssd_query_cb, &data)) != NULL)
{
- DEBUG_printf(("1cupsEnumDests: browser ref=%p", device->ref));
+ DEBUG_printf(("1cupsEnumDests: Query ref=%p", device->ref));
count ++;
}
else
@@ -1252,6 +1251,8 @@ cupsEnumDests(
{
completed ++;
+ DEBUG_printf(("1cupsEnumDests: Query for \"%s\" is complete.", device->fullName));
+
if ((device->type & mask) == type)
{
DEBUG_printf(("1cupsEnumDests: Add callback for \"%s\".", device->dest.name));
@@ -1267,12 +1268,12 @@ cupsEnumDests(
}
# ifdef HAVE_AVAHI
- DEBUG_printf(("1cupsEnumDests: browsers=%d, completed=%d, count=%d, devices count=%d", data.browsers, completed, count, cupsArrayCount(data.devices)));
+ DEBUG_printf(("1cupsEnumDests: remaining=%d, browsers=%d, completed=%d, count=%d, devices count=%d", remaining, data.browsers, completed, count, cupsArrayCount(data.devices)));
if (data.browsers == 0 && completed == cupsArrayCount(data.devices))
break;
# else
- DEBUG_printf(("1cupsEnumDests: completed=%d, count=%d, devices count=%d", completed, count, cupsArrayCount(data.devices)));
+ DEBUG_printf(("1cupsEnumDests: remaining=%d, completed=%d, count=%d, devices count=%d", remaining, completed, count, cupsArrayCount(data.devices)));
if (completed == cupsArrayCount(data.devices))
break;
@@ -3243,7 +3244,7 @@ cups_dnssd_poll_cb(
(void)timeout;
- val = poll(pollfds, num_pollfds, 500);
+ val = poll(pollfds, num_pollfds, _CUPS_DNSSD_MAXTIME);
DEBUG_printf(("cups_dnssd_poll_cb: poll() returned %d", val));
@@ -3740,6 +3741,27 @@ cups_dnssd_queue_name(
/*
+ * 'cups_elapsed()' - Return the elapsed time in milliseconds.
+ */
+
+static int /* O - Elapsed time in milliseconds */
+cups_elapsed(struct timeval *t) /* IO - Previous time */
+{
+ int msecs; /* Milliseconds */
+ struct timeval nt; /* New time */
+
+
+ gettimeofday(&nt, NULL);
+
+ msecs = 1000 * (nt.tv_sec - t->tv_sec) + (nt.tv_usec - t->tv_usec) / 1000;
+
+ *t = nt;
+
+ return (msecs);
+}
+
+
+/*
* 'cups_find_dest()' - Find a destination using a binary search.
*/