From 14a896be5d1c50fc818428bd582ec043b28cce24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Fri, 25 Oct 2019 09:27:22 +0200 Subject: [PATCH] Attempt to fix crash in thread based DNS lookup. Depending on the timing of starting and finishing DNS queries, `Thread.join` could be called on an instance that had already been `destroy`ed. To avoid this, the thread instance is now explicitly set to null, as well as resetting the "done" field to avoid redundant work for unused slots. See vibe-d/vibe.d#2378. --- source/eventcore/drivers/posix/dns.d | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/source/eventcore/drivers/posix/dns.d b/source/eventcore/drivers/posix/dns.d index 196455c..e9e131b 100644 --- a/source/eventcore/drivers/posix/dns.d +++ b/source/eventcore/drivers/posix/dns.d @@ -67,6 +67,8 @@ final class EventDriverDNS_GAI(Events : EventDriverEvents, Signals : EventDriver auto handle = getFreeHandle(); if (handle > m_maxHandle) m_maxHandle = handle; + assert(on_lookup_finished !is null, "Null callback passed to lookupHost"); + setupEvent(); assert(!m_lookups[handle].result); @@ -105,6 +107,8 @@ final class EventDriverDNS_GAI(Events : EventDriverEvents, Signals : EventDriver if (m_lookup.retcode == -1) version (CRuntime_Glibc) version (linux) __res_init(); + assert(m_lookup.retcode != 0 || m_lookup.result !is null); + atomicStore(m_lookup.done, true); atomicFence(); // synchronize the other fields in m_lookup with the main thread m_events.trigger(m_event, true); @@ -141,11 +145,14 @@ final class EventDriverDNS_GAI(Events : EventDriverEvents, Signals : EventDriver // synchronize the other fields in m_lookup with the lookup thread atomicFence(); - try { - l.thread.join(); - destroy(l.thread); - } catch (Exception e) { - debug (EventCoreLogDNS) print("Failed to join DNS thread: %s", e.msg); + if (l.thread !is null) { + try { + l.thread.join(); + destroy(l.thread); + } catch (Exception e) { + debug (EventCoreLogDNS) print("Failed to join DNS thread: %s", e.msg); + } + l.thread = null; } if (l.callback) { @@ -161,6 +168,7 @@ final class EventDriverDNS_GAI(Events : EventDriverEvents, Signals : EventDriver l.callback = null; l.result = null; l.retcode = 0; + l.done = false; if (i == m_maxHandle) m_maxHandle = lastmax; m_events.loop.m_waiterCount--; passToDNSCallback(cast(DNSLookupID)cast(int)i, cb, status, ai);