From: Zdenek Dohnal Date: Thu, 4 Jan 2024 12:58:42 +0000 (+0100) Subject: dnssd.c: Fix deadlock in `cups_enum_dests()` X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F857%2Fhead;p=thirdparty%2Fcups.git dnssd.c: Fix deadlock in `cups_enum_dests()` Deadlock happens when we are about to destroy DNSSD struct by the end of `cups_enum_dests()`. The main thread locks the mutex when the other thread is in avahi poll callback at function `poll()` and unlocked the mutex before - the other thread tries to lock the mutex once poll timeout expires, but it cannot because it was locked by the main thread and wait there. Meanwhile the main thread tries to cancel the other thread, but the function where the other thread is not a cancellation point, thus the cancel event is ignored and the main thread thread waits indefinitely for the end of the other thread. We can make the other thread asynchronous (which would cancel the thread immediately) or release the mutex earlier in `cupsDNSSDDelete()`. The commit does the latter. Fixes CI for Linux --- diff --git a/cups/dnssd.c b/cups/dnssd.c index 4daa4169e6..45c9f57ac9 100644 --- a/cups/dnssd.c +++ b/cups/dnssd.c @@ -434,6 +434,8 @@ cupsDNSSDDelete(cups_dnssd_t *dnssd) // I - DNS-SD context cupsArrayDelete(dnssd->resolves); cupsArrayDelete(dnssd->services); + cupsMutexUnlock(&dnssd->mutex); + #ifdef HAVE_MDNSRESPONDER cupsThreadCancel(dnssd->monitor); cupsThreadWait(dnssd->monitor); @@ -447,7 +449,6 @@ cupsDNSSDDelete(cups_dnssd_t *dnssd) // I - DNS-SD context avahi_simple_poll_free(dnssd->poll); #endif // HAVE_MDNSRESPONDER - cupsMutexUnlock(&dnssd->mutex); cupsMutexDestroy(&dnssd->mutex); free(dnssd); }