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.
This commit is contained in:
parent
f6ac56664d
commit
14a896be5d
|
@ -67,6 +67,8 @@ final class EventDriverDNS_GAI(Events : EventDriverEvents, Signals : EventDriver
|
||||||
auto handle = getFreeHandle();
|
auto handle = getFreeHandle();
|
||||||
if (handle > m_maxHandle) m_maxHandle = handle;
|
if (handle > m_maxHandle) m_maxHandle = handle;
|
||||||
|
|
||||||
|
assert(on_lookup_finished !is null, "Null callback passed to lookupHost");
|
||||||
|
|
||||||
setupEvent();
|
setupEvent();
|
||||||
|
|
||||||
assert(!m_lookups[handle].result);
|
assert(!m_lookups[handle].result);
|
||||||
|
@ -105,6 +107,8 @@ final class EventDriverDNS_GAI(Events : EventDriverEvents, Signals : EventDriver
|
||||||
if (m_lookup.retcode == -1)
|
if (m_lookup.retcode == -1)
|
||||||
version (CRuntime_Glibc) version (linux) __res_init();
|
version (CRuntime_Glibc) version (linux) __res_init();
|
||||||
|
|
||||||
|
assert(m_lookup.retcode != 0 || m_lookup.result !is null);
|
||||||
|
|
||||||
atomicStore(m_lookup.done, true);
|
atomicStore(m_lookup.done, true);
|
||||||
atomicFence(); // synchronize the other fields in m_lookup with the main thread
|
atomicFence(); // synchronize the other fields in m_lookup with the main thread
|
||||||
m_events.trigger(m_event, true);
|
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
|
// synchronize the other fields in m_lookup with the lookup thread
|
||||||
atomicFence();
|
atomicFence();
|
||||||
|
|
||||||
try {
|
if (l.thread !is null) {
|
||||||
l.thread.join();
|
try {
|
||||||
destroy(l.thread);
|
l.thread.join();
|
||||||
} catch (Exception e) {
|
destroy(l.thread);
|
||||||
debug (EventCoreLogDNS) print("Failed to join DNS thread: %s", e.msg);
|
} catch (Exception e) {
|
||||||
|
debug (EventCoreLogDNS) print("Failed to join DNS thread: %s", e.msg);
|
||||||
|
}
|
||||||
|
l.thread = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l.callback) {
|
if (l.callback) {
|
||||||
|
@ -161,6 +168,7 @@ final class EventDriverDNS_GAI(Events : EventDriverEvents, Signals : EventDriver
|
||||||
l.callback = null;
|
l.callback = null;
|
||||||
l.result = null;
|
l.result = null;
|
||||||
l.retcode = 0;
|
l.retcode = 0;
|
||||||
|
l.done = false;
|
||||||
if (i == m_maxHandle) m_maxHandle = lastmax;
|
if (i == m_maxHandle) m_maxHandle = lastmax;
|
||||||
m_events.loop.m_waiterCount--;
|
m_events.loop.m_waiterCount--;
|
||||||
passToDNSCallback(cast(DNSLookupID)cast(int)i, cb, status, ai);
|
passToDNSCallback(cast(DNSLookupID)cast(int)i, cb, status, ai);
|
||||||
|
|
Loading…
Reference in a new issue