Skip to content

Commit 1428bee

Browse files
committed
Fix threading bug in DNS-SD API (Issue #33)
1 parent 6dd63f3 commit 1428bee

4 files changed

Lines changed: 38 additions & 8 deletions

File tree

cups/dest.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ static size_t cups_get_dests(const char *filename, const char *match_name, cons
143143
static char *cups_make_string(ipp_attribute_t *attr, char *buffer, size_t bufsize);
144144
static bool cups_name_cb(_cups_namedata_t *data, unsigned flags, cups_dest_t *dest);
145145
static void cups_queue_name(char *name, const char *serviceName, size_t namesize);
146+
static void dnssd_error_cb(void *cb_data, const char *message);
146147

147148

148149
/*
@@ -3149,7 +3150,7 @@ cups_enum_dests(
31493150

31503151
gettimeofday(&curtime, NULL);
31513152

3152-
if ((dnssd = cupsDNSSDNew(NULL, NULL)) == NULL)
3153+
if ((dnssd = cupsDNSSDNew(dnssd_error_cb, NULL)) == NULL)
31533154
{
31543155
DEBUG_puts("1cups_enum_dests: Unable to create service browser, returning 0.");
31553156

@@ -3811,3 +3812,17 @@ cups_queue_name(
38113812

38123813
*nameptr = '\0';
38133814
}
3815+
3816+
3817+
//
3818+
// 'dnssd_error_cb()' - Report an error.
3819+
//
3820+
3821+
static void
3822+
dnssd_error_cb(void *cb_data, // I - Callback data (unused)
3823+
const char *message) // I - Message
3824+
{
3825+
(void)cb_data;
3826+
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0);
3827+
}
3828+

cups/dnssd.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DNS-SD API functions for CUPS.
33
//
4-
// Copyright © 2022 by OpenPrinting.
4+
// Copyright © 2022-2023 by OpenPrinting.
55
//
66
// Licensed under Apache License v2.0. See the file "LICENSE" for more
77
// information.
@@ -409,12 +409,14 @@ cupsDNSSDDelete(cups_dnssd_t *dnssd) // I - DNS-SD context
409409

410410
#ifdef HAVE_MDNSRESPONDER
411411
cupsThreadCancel(dnssd->monitor);
412+
cupsThreadWait(dnssd->monitor);
412413
DNSServiceRefDeallocate(dnssd->ref);
413414

414415
#elif _WIN32
415416

416417
#else // HAVE_AVAHI
417418
cupsThreadCancel(dnssd->monitor);
419+
cupsThreadWait(dnssd->monitor);
418420
avahi_simple_poll_free(dnssd->poll);
419421
#endif // HAVE_MDNSRESPONDER
420422

@@ -562,7 +564,6 @@ cupsDNSSDNew(
562564
return (NULL);
563565
}
564566

565-
cupsThreadDetach(dnssd->monitor);
566567
DEBUG_printf(("2cupsDNSSDNew: dnssd->monitor=%p", (void *)dnssd->monitor));
567568

568569
#elif _WIN32
@@ -603,7 +604,6 @@ cupsDNSSDNew(
603604
return (NULL);
604605
}
605606

606-
cupsThreadDetach(dnssd->monitor);
607607
DEBUG_printf(("2cupsDNSSDNew: dnssd->monitor=%p", (void *)dnssd->monitor));
608608
#endif // HAVE_MDNSRESPONDER
609609

@@ -1631,9 +1631,21 @@ static void * // O - Return value (always `NULL`)
16311631
mdns_monitor(cups_dnssd_t *dnssd) // I - DNS-SD context
16321632
{
16331633
DNSServiceErrorType error; // Current error
1634+
struct pollfd polldata; // Polling data
1635+
1636+
polldata.fd = DNSServiceRefSockFD(dnssd->ref);
1637+
polldata.events = POLLERR | POLLHUP | POLLIN;
16341638

16351639
for (;;)
16361640
{
1641+
# ifndef _WIN32
1642+
if (poll(&polldata, 1, 1000) < 0 && errno != EINTR && errno != EAGAIN)
1643+
break;
1644+
1645+
if (!(polldata.revents & POLLIN))
1646+
continue;
1647+
# endif // !_WIN32
1648+
16371649
if ((error = DNSServiceProcessResult(dnssd->ref)) != kDNSServiceErr_NoError)
16381650
{
16391651
report_error(dnssd, "Unable to read response from DNS-SD service: %s", mdns_strerror(error));

cups/testgetdests.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ main(int argc, // I - Number of command-line arguments
4040
if (argc == 2)
4141
count = strtoul(argv[1], NULL, 10);
4242
else
43-
count = 1;
43+
count = 5;
4444

4545
// Run tests...
4646
while (count > 0)
@@ -51,7 +51,10 @@ main(int argc, // I - Number of command-line arguments
5151
gettimeofday(&end, NULL);
5252
secs = end.tv_sec - start.tv_sec + 0.000001 * (end.tv_usec - start.tv_usec);
5353

54-
testEndMessage(secs < 2.0, "%u printers in %.3f seconds", (unsigned)num_dests, secs);
54+
if (cupsLastError() != IPP_STATUS_OK)
55+
testEndMessage(false, "%s", cupsLastErrorString());
56+
else
57+
testEndMessage(secs < 2.0, "%u printers in %.3f seconds", (unsigned)num_dests, secs);
5558

5659
cupsFreeDests(num_dests, dests);
5760

@@ -61,5 +64,5 @@ main(int argc, // I - Number of command-line arguments
6164
sleep(1);
6265
}
6366

64-
return (0);
67+
return (testsPassed ? 0 : 1);
6568
}

cups/thread.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// Threading primitives for CUPS.
33
//
4-
// Copyright © 2021-2022 by OpenPrinting.
4+
// Copyright © 2021-2023 by OpenPrinting.
55
// Copyright © 2009-2018 by Apple Inc.
66
//
77
// Licensed under Apache License v2.0. See the file "LICENSE" for more

0 commit comments

Comments
 (0)