Package: libasyncns0
Severity: normal
Tags: patch upstream

Hello,

Forwarding here this bug, since there's no any action from upstream:
https://bugs.freedesktop.org/show_bug.cgi?id=94849

When using libasyncns with pthreads support, it freezes entire
application, when you try to asyncns_free() instance, that have one of
its workers blocked by getaddrinfo() (worker may be blocked eg. because
of some problem with resolver servers).

An easy way to reproduce this bug is to set your nameserver in
resolv.conf to something non-existent (like 1.2.3.4), then create
asyncns resolver, make a request, and then immediately asyncns_free()
resolver. It will block the application, until worker gets network
timeout.

The problem, as I see it, lies in this code (in asyncns_free()):

    /* Now terminate them and wait until they are gone. */
    for (p = 0; p < asyncns->valid_workers; p++) {
#ifndef HAVE_PTHREAD
        kill(asyncns->workers[p], SIGTERM);
        for (;;) {
            if (waitpid(asyncns->workers[p], NULL, 0) >= 0 || errno != EINTR)
                break;
        }
#else
        for (;;) {
            if (pthread_join(asyncns->workers[p], NULL) != EINTR)
                break;
        }
#endif
    }

So, when pthreads are not in use, it kill()'s worker, then wait()'s for
it. When they are used - it just pthread_join()'s them, which, AFAICS,
is equal to just wait(). I'm no expert on threading, but I've found,
that pthread_cancel() just before waiting cycle solves this problem.
Please, consider including this fix (or any other, that resolves the
problem) into the upstream.

Patch, that fixes the problem for me (not sure, how to attach the file 
in reportbug, thus inserting plaintext):

--- a/libasyncns/asyncns.c      2016-03-19 19:13:00.774406379 +0200
+++ b/libasyncns/asyncns.c      2016-03-19 19:13:02.378415461 +0200
@@ -865,6 +865,7 @@
                 break;
         }
 #else
+        pthread_cancel(asyncns->workers[p]);
         for (;;) {
             if (pthread_join(asyncns->workers[p], NULL) != EINTR)
                 break;

-- System Information:
Debian Release: 9.0
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64
 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.9.0-2-amd64 (SMP w/4 CPU cores)
Locale: LANG=uk_UA.UTF-8, LC_CTYPE=uk_UA.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Reply via email to