18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Collin Jackson <collinj@webkit.org> 3231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2009 Apple Inc. All Rights Reserved. 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DNS.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "KURL.h" 31231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Timer.h" 32d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/HashSet.h> 33231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <wtf/RetainPtr.h> 34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <wtf/StdLibExtras.h> 35f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include <wtf/text/StringHash.h> 36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 37231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if PLATFORM(WIN) 38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "LoaderRunLoopCF.h" 392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <CFNetwork/CFNetwork.h> 40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 42f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if defined(BUILDING_ON_LEOPARD) 43f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <SystemConfiguration/SystemConfiguration.h> 44f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 45f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#ifdef BUILDING_ON_TIGER 47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// This function is available on Tiger, but not declared in the CFRunLoop.h header on Tiger. 48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockextern "C" CFRunLoopRef CFRunLoopGetMain(); 49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// When resolve queue is empty, we fire async resolution requests immediately (which is important if the prefetch is triggered by hovering). 54231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// But during page parsing, we should coalesce identical requests to avoid stressing out CFHost. 55231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockconst int namesToResolveImmediately = 4; 56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 57231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// Coalesce prefetch requests for this long before sending them out. 5806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenconst double coalesceDelayInSeconds = 1.0; 5906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 6006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen// Sending many DNS requests at once can overwhelm some gateways. CFHost doesn't currently throttle for us, see <rdar://8105550>. 6106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenconst int maxSimultaneousRequests = 8; 62231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 63231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// For a page has links to many outside sites, it is likely that the system DNS resolver won't be able to cache them all anyway, and we don't want 6406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen// to negatively affect other applications' performance by pushing their cached entries out. 65231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// If we end up with lots of names to prefetch, some will be dropped. 6606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenconst int maxRequestsToQueue = 64; 6706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 6806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen// If there were queued names that couldn't be sent simultaneously, check the state of resolvers after this delay. 6906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenconst double retryResolvingInSeconds = 0.1; 70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 71f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic bool proxyIsEnabledInSystemPreferences() 72f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 73f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Don't do DNS prefetch if proxies are involved. For many proxy types, the user agent is never exposed 74f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // to the IP address during normal operation. Querying an internal DNS server may not help performance, 75f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // as it doesn't necessarily look up the actual external IP. Also, if DNS returns a fake internal address, 76f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // local caches may keep it even after re-connecting to another network. 77f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 78f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if !defined(BUILDING_ON_LEOPARD) 79f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch RetainPtr<CFDictionaryRef> proxySettings(AdoptCF, CFNetworkCopySystemProxySettings()); 80f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#else 81f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch RetainPtr<CFDictionaryRef> proxySettings(AdoptCF, SCDynamicStoreCopyProxies(0)); 82f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 83f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!proxySettings) 84f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return false; 85f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 86f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch static CFURLRef httpCFURL = KURL(ParsedURLString, "http://example.com/").createCFURL(); 87f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch static CFURLRef httpsCFURL = KURL(ParsedURLString, "https://example.com/").createCFURL(); 88f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 89f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch RetainPtr<CFArrayRef> httpProxyArray(AdoptCF, CFNetworkCopyProxiesForURL(httpCFURL, proxySettings.get())); 90f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch RetainPtr<CFArrayRef> httpsProxyArray(AdoptCF, CFNetworkCopyProxiesForURL(httpsCFURL, proxySettings.get())); 91f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 92f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch CFIndex httpProxyCount = CFArrayGetCount(httpProxyArray.get()); 93f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch CFIndex httpsProxyCount = CFArrayGetCount(httpsProxyArray.get()); 94f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (httpProxyCount == 1 && CFEqual(CFDictionaryGetValue(static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(httpProxyArray.get(), 0)), kCFProxyTypeKey), kCFProxyTypeNone)) 95f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch httpProxyCount = 0; 96f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (httpsProxyCount == 1 && CFEqual(CFDictionaryGetValue(static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(httpsProxyArray.get(), 0)), kCFProxyTypeKey), kCFProxyTypeNone)) 97f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch httpsProxyCount = 0; 98f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 99f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return httpProxyCount || httpsProxyCount; 100f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 101f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockclass DNSResolveQueue : public TimerBase { 103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockpublic: 104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static DNSResolveQueue& shared(); 105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block void add(const String&); 106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block void decrementRequestCount(); 107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockprivate: 109231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block DNSResolveQueue(); 110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 111231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block void resolve(const String&); 112231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block virtual void fired(); 113231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block HashSet<String> m_names; 114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block int m_requestsInFlight; 115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}; 116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 117231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockDNSResolveQueue::DNSResolveQueue() 118231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block : m_requestsInFlight(0) 119231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 120231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockDNSResolveQueue& DNSResolveQueue::shared() 123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block DEFINE_STATIC_LOCAL(DNSResolveQueue, names, ()); 125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return names; 126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 127231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 128231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid DNSResolveQueue::add(const String& name) 129231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 130231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If there are no names queued, and few enough are in flight, resolve immediately (the mouse may be over a link). 131231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_names.size()) { 132f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (proxyIsEnabledInSystemPreferences()) 133f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 134f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (atomicIncrement(&m_requestsInFlight) <= namesToResolveImmediately) { 136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block resolve(name); 137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 138231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 139231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block atomicDecrement(&m_requestsInFlight); 140231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 14106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 14206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // It's better to not prefetch some names than to clog the queue. 14306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // Dropping the newest names, because on a single page, these are likely to be below oldest ones. 14406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (m_names.size() < maxRequestsToQueue) { 14506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_names.add(name); 14606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (!isActive()) 14706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen startOneShot(coalesceDelayInSeconds); 14806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 149231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 150231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 151231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid DNSResolveQueue::decrementRequestCount() 152231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 153231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block atomicDecrement(&m_requestsInFlight); 154231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 155231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 156231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid DNSResolveQueue::fired() 157231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 158f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (proxyIsEnabledInSystemPreferences()) { 159f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_names.clear(); 160f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 161f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 162f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 16306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen int requestsAllowed = maxSimultaneousRequests - m_requestsInFlight; 164231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 16506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen for (; !m_names.isEmpty() && requestsAllowed > 0; --requestsAllowed) { 166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block atomicIncrement(&m_requestsInFlight); 16706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen HashSet<String>::iterator currentName = m_names.begin(); 16806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen resolve(*currentName); 16906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_names.remove(currentName); 170231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 171231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 17206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (!m_names.isEmpty()) 17306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen startOneShot(retryResolvingInSeconds); 174231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 175231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 176231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic void clientCallback(CFHostRef theHost, CFHostInfoType, const CFStreamError*, void*) 177231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 178231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block DNSResolveQueue::shared().decrementRequestCount(); // It's ok to call shared() from a secondary thread, the static variable has already been initialized by now. 179231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block CFRelease(theHost); 180231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 181231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 182231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid DNSResolveQueue::resolve(const String& hostname) 183231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 184231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(isMainThread()); 185231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 186231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RetainPtr<CFStringRef> hostnameCF(AdoptCF, hostname.createCFString()); 187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RetainPtr<CFHostRef> host(AdoptCF, CFHostCreateWithName(0, hostnameCF.get())); 188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!host) { 189231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block atomicDecrement(&m_requestsInFlight); 190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block CFHostClientContext context = { 0, 0, 0, 0, 0 }; 193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Boolean result = CFHostSetClient(host.get(), clientCallback, &context); 194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT_UNUSED(result, result); 195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if !PLATFORM(WIN) 196231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block CFHostScheduleWithRunLoop(host.get(), CFRunLoopGetMain(), kCFRunLoopCommonModes); 197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#else 198231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // On Windows, we run a separate thread with CFRunLoop, which is where clientCallback will be called. 199643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CFHostScheduleWithRunLoop(host.get(), loaderRunLoop(), kCFRunLoopDefaultMode); 200231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 201231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block CFHostStartInfoResolution(host.get(), kCFHostAddresses, 0); 202231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block host.releaseRef(); // The host will be released from clientCallback(). 203231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 204231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 205231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid prefetchDNS(const String& hostname) 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 207231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(isMainThread()); 208231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (hostname.isEmpty()) 209231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 210231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block DNSResolveQueue::shared().add(hostname); 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 214