Investigating leaks in bug 463263, backout bug 453403.

This commit is contained in:
Justin Dolske 2008-11-05 12:55:38 -08:00
Родитель b549566787 39782a280e
Коммит f2b2bbee33
18 изменённых файлов: 59 добавлений и 348 удалений

Просмотреть файл

@ -102,8 +102,6 @@
#include "nsIDocumentLoader.h"
#include "nsICachingChannel.h"
#include "nsICacheEntryDescriptor.h"
#include "nsGenericHTMLElement.h"
#include "nsHTMLDNSPrefetch.h"
PRLogModuleInfo* gContentSinkLogModuleInfo;
@ -724,10 +722,6 @@ nsContentSink::ProcessLink(nsIContent* aElement,
PrefetchHref(aHref, aElement, hasPrefetch);
}
if ((!aHref.IsEmpty()) && linkTypes.IndexOf(NS_LITERAL_STRING("dns-prefetch")) != -1) {
PrefetchDNS(aHref);
}
// is it a stylesheet link?
if (linkTypes.IndexOf(NS_LITERAL_STRING("stylesheet")) == -1) {
return NS_OK;
@ -859,23 +853,6 @@ nsContentSink::PrefetchHref(const nsAString &aHref,
}
}
void
nsContentSink::PrefetchDNS(const nsAString &aHref)
{
nsAutoString hostname;
if (StringBeginsWith(aHref, NS_LITERAL_STRING("//"))) {
hostname = Substring(aHref, 2);
}
else
nsGenericHTMLElement::GetHostnameFromHrefString(aHref, hostname);
nsRefPtr<nsHTMLDNSPrefetch> prefetch = new nsHTMLDNSPrefetch(hostname, mDocument);
if (prefetch) {
prefetch->PrefetchLow();
}
}
nsresult
nsContentSink::GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey)
{

Просмотреть файл

@ -192,10 +192,6 @@ protected:
void PrefetchHref(const nsAString &aHref, nsIContent *aSource,
PRBool aExplicit);
// aHref can either be the usual URI format or of the form "//www.hostname.com"
// without a scheme.
void PrefetchDNS(const nsAString &aHref);
// Gets the cache key (used to identify items in a cache) of the channel.
nsresult GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey);

Просмотреть файл

@ -6572,7 +6572,6 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
"content-language",
"content-disposition",
"refresh",
"x-dns-prefetch-control",
// add more http headers if you need
// XXXbz don't add content-location support without reading bug
// 238654 and its dependencies/dups first.

Просмотреть файл

@ -987,7 +987,6 @@ GK_ATOM(headerWindowTarget, "window-target")
GK_ATOM(withParam, "with-param")
GK_ATOM(wizard, "wizard")
GK_ATOM(wrap, "wrap")
GK_ATOM(headerDNSPrefetchControl,"x-dns-prefetch-control")
GK_ATOM(xml, "xml")
GK_ATOM(xmlns, "xmlns")
GK_ATOM(xmp, "xmp")

Просмотреть файл

@ -83,7 +83,6 @@ EXPORTS = \
CPPSRCS = \
nsClientRect.cpp \
nsHTMLDNSPrefetch.cpp \
nsGenericHTMLElement.cpp \
nsFormSubmission.cpp \
nsImageMapUtils.cpp \

Просмотреть файл

@ -64,8 +64,6 @@
#include "nsIPresShell.h"
#include "nsIDocument.h"
#include "nsHTMLDNSPrefetch.h"
nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult);
class nsHTMLAnchorElement : public nsGenericHTMLElement,
@ -137,26 +135,11 @@ public:
protected:
// The cached visited state
nsLinkState mLinkState;
void PrefetchDNS();
};
NS_IMPL_NS_NEW_HTML_ELEMENT(Anchor)
void
nsHTMLAnchorElement::PrefetchDNS()
{
nsCOMPtr<nsIURI> hrefURI;
GetHrefURI(getter_AddRefs(hrefURI));
if (hrefURI) {
nsRefPtr<nsHTMLDNSPrefetch> prefetch =
new nsHTMLDNSPrefetch(hrefURI, GetOwnerDoc());
if (prefetch)
prefetch->PrefetchLow();
}
}
nsHTMLAnchorElement::nsHTMLAnchorElement(nsINodeInfo *aNodeInfo)
: nsGenericHTMLElement(aNodeInfo),
@ -229,7 +212,6 @@ nsHTMLAnchorElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
RegUnRegAccessKey(PR_TRUE);
}
PrefetchDNS();
return rv;
}

Просмотреть файл

@ -2950,13 +2950,6 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
PrefetchHref(hrefVal, element, hasPrefetch);
}
}
if (linkTypes.IndexOf(NS_LITERAL_STRING("dns-prefetch")) != -1) {
nsAutoString hrefVal;
element->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
if (!hrefVal.IsEmpty()) {
PrefetchDNS(hrefVal);
}
}
}
}
}

Просмотреть файл

@ -657,18 +657,6 @@ nsXMLContentSink::CloseElement(nsIContent* aContent)
mScriptLoader->AddExecuteBlocker();
}
}
// Look for <link rel="dns-prefetch" href="hostname">
if (nodeInfo->Equals(nsGkAtoms::link, kNameSpaceID_XHTML)) {
nsAutoString relVal;
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal);
if (relVal.EqualsLiteral("dns-prefetch")) {
nsAutoString hrefVal;
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
if (!hrefVal.IsEmpty()) {
PrefetchDNS(hrefVal);
}
}
}
}
return rv;

Просмотреть файл

@ -83,7 +83,6 @@
#include "nsXMLHttpRequest.h"
#include "nsIFocusEventSuppressor.h"
#include "nsDOMThreadService.h"
#include "nsHTMLDNSPrefetch.h"
#ifdef MOZ_XUL
#include "nsXULPopupManager.h"
@ -186,12 +185,6 @@ nsLayoutStatics::Initialize()
return rv;
}
rv = nsHTMLDNSPrefetch::Initialize();
if (NS_FAILED(rv)) {
NS_ERROR("Could not initialize HTML DNS prefetch");
return rv;
}
#ifdef MOZ_XUL
rv = nsXULContentUtils::Init();
if (NS_FAILED(rv)) {
@ -287,7 +280,6 @@ nsLayoutStatics::Shutdown()
CSSLoaderImpl::Shutdown();
nsCSSRuleProcessor::FreeSystemMetrics();
nsTextFrameTextRunCache::Shutdown();
nsHTMLDNSPrefetch::Shutdown();
nsCSSRendering::Shutdown();
#ifdef DEBUG
nsFrame::DisplayReflowShutdown();

Просмотреть файл

@ -272,14 +272,6 @@
#define NS_ERROR_UNKNOWN_HOST \
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 30)
/**
* A low or medium priority DNS lookup failed because the pending
* queue was already full. High priorty (the default) always
* makes room
*/
#define NS_ERROR_DNS_LOOKUP_QUEUE_FULL \
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 33)
/**
* The lookup of a proxy hostname failed.
*

Просмотреть файл

@ -93,7 +93,6 @@ CPPSRCS = \
nsNetStrings.cpp \
nsBase64Encoder.cpp \
nsSerializationHelper.cpp \
nsDNSPrefetch.cpp \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)

Просмотреть файл

@ -59,7 +59,6 @@
#include "nsDiskCacheDeviceSQL.h"
#include "nsMimeTypes.h"
#include "nsNetStrings.h"
#include "nsDNSPrefetch.h"
#include "nsNetCID.h"
@ -620,13 +619,10 @@ static void nsNetShutdown(nsIModule *neckoModule)
#ifdef XP_MACOSX
net_ShutdownURLHelperOSX();
#endif
// Release necko strings
delete gNetStrings;
gNetStrings = nsnull;
// Release DNS service reference.
nsDNSPrefetch::Shutdown();
}
static const nsModuleComponentInfo gNetModuleInfo[] = {

Просмотреть файл

@ -46,7 +46,7 @@ interface nsIDNSListener;
/**
* nsIDNSService
*/
[scriptable, uuid(ee4d9f1d-4f99-4384-b547-29da735f8b6e)]
[scriptable, uuid(3ac9e611-e6b6-44b5-b312-c040e65b2929)]
interface nsIDNSService : nsISupports
{
/**
@ -107,11 +107,4 @@ interface nsIDNSService : nsISupports
* if set, the canonical name of the specified host will be queried.
*/
const unsigned long RESOLVE_CANONICAL_NAME = (1 << 1);
/**
* if set, the query is given lower priority. Medium takes precedence
* if both are used.
*/
const unsigned long RESOLVE_PRIORITY_MEDIUM = (1 << 2);
const unsigned long RESOLVE_PRIORITY_LOW = (1 << 3);
};

Просмотреть файл

@ -50,7 +50,6 @@
#include "nsAutoPtr.h"
#include "nsNetCID.h"
#include "nsNetError.h"
#include "nsDNSPrefetch.h"
#include "prsystem.h"
#include "prnetdb.h"
#include "prmon.h"
@ -62,7 +61,6 @@ static const char kPrefDnsCacheExpiration[] = "network.dnsCacheExpiration";
static const char kPrefEnableIDN[] = "network.enableIDN";
static const char kPrefIPv4OnlyDomains[] = "network.dns.ipv4OnlyDomains";
static const char kPrefDisableIPv6[] = "network.dns.disableIPv6";
static const char kPrefDisablePrefetch[] = "network.dns.disablePrefetch";
//-----------------------------------------------------------------------------
@ -323,12 +321,10 @@ nsDNSService::Init()
PRBool firstTime = (mLock == nsnull);
// prefs
PRUint32 maxCacheEntries = 400;
PRUint32 maxCacheLifetime = 3; // minutes
PRUint32 maxCacheEntries = 20;
PRUint32 maxCacheLifetime = 1; // minutes
PRBool enableIDN = PR_TRUE;
PRBool disableIPv6 = PR_FALSE;
PRBool disablePrefetch = PR_FALSE;
nsAdoptingCString ipv4OnlyDomains;
// read prefs
@ -344,7 +340,6 @@ nsDNSService::Init()
prefs->GetBoolPref(kPrefEnableIDN, &enableIDN);
prefs->GetBoolPref(kPrefDisableIPv6, &disableIPv6);
prefs->GetCharPref(kPrefIPv4OnlyDomains, getter_Copies(ipv4OnlyDomains));
prefs->GetBoolPref(kPrefDisablePrefetch, &disablePrefetch);
}
if (firstTime) {
@ -359,7 +354,6 @@ nsDNSService::Init()
prefs->AddObserver(kPrefEnableIDN, this, PR_FALSE);
prefs->AddObserver(kPrefIPv4OnlyDomains, this, PR_FALSE);
prefs->AddObserver(kPrefDisableIPv6, this, PR_FALSE);
prefs->AddObserver(kPrefDisablePrefetch, this, PR_FALSE);
}
}
@ -380,10 +374,8 @@ nsDNSService::Init()
mIDN = idn;
mIPv4OnlyDomains = ipv4OnlyDomains; // exchanges buffer ownership
mDisableIPv6 = disableIPv6;
mDisablePrefetch = disablePrefetch;
}
nsDNSPrefetch::Initialize(this);
return rv;
}
@ -414,10 +406,6 @@ nsDNSService::AsyncResolve(const nsACString &hostname,
nsCOMPtr<nsIIDNService> idn;
{
nsAutoLock lock(mLock);
if (mDisablePrefetch && (flags & (RESOLVE_PRIORITY_LOW | RESOLVE_PRIORITY_MEDIUM)))
return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
res = mResolver;
idn = mIDN;
}

Просмотреть файл

@ -68,5 +68,4 @@ private:
// a per-domain basis and work around broken DNS servers. See bug 68796.
nsAdoptingCString mIPv4OnlyDomains;
PRBool mDisableIPv6;
PRBool mDisablePrefetch;
};

Просмотреть файл

@ -68,28 +68,8 @@
//----------------------------------------------------------------------------
// Use a persistent thread pool in order to avoid spinning up new threads all the time.
// In particular, thread creation results in a res_init() call from libc which is
// quite expensive.
//
// The pool dynamically grows between 0 and MAX_RESOLVER_THREADS in size. New requests
// go first to an idle thread. If that cannot be found and there are fewer than MAX_RESOLVER_THREADS
// currently in the pool a new thread is created for high priority requests. If
// the new request is at a lower priority a new thread will only be created if
// there are fewer than HighThreadThreshold currently outstanding. If a thread cannot be
// created or an idle thread located for the request it is queued.
//
// When the pool is greater than HighThreadThreshold in size a thread will be destroyed after
// ShortIdleTimeoutSeconds of idle time. Smaller pools use LongIdleTimeoutSeconds for a
// timeout period.
#define MAX_NON_PRIORITY_REQUESTS 150
#define HighThreadThreshold 4
#define LongIdleTimeoutSeconds 300 // for threads 1 -> HighThreadThreshold
#define ShortIdleTimeoutSeconds 60 // for threads HighThreadThreshold+1 -> MAX_RESOLVER_THREADS
PR_STATIC_ASSERT (HighThreadThreshold <= MAX_RESOLVER_THREADS);
#define MAX_THREADS 8
#define IDLE_TIMEOUT PR_SecondsToInterval(60)
//----------------------------------------------------------------------------
@ -204,7 +184,6 @@ nsHostRecord::Create(const nsHostKey *key, nsHostRecord **result)
rec->addr = nsnull;
rec->expiration = NowInMinutes();
rec->resolving = PR_FALSE;
rec->onQueue = PR_FALSE;
PR_INIT_CLIST(rec);
PR_INIT_CLIST(&rec->callbacks);
rec->negative = PR_FALSE;
@ -329,26 +308,14 @@ nsHostResolver::nsHostResolver(PRUint32 maxCacheEntries,
, mMaxCacheLifetime(maxCacheLifetime)
, mLock(nsnull)
, mIdleThreadCV(nsnull)
, mNumIdleThreads(0)
, mHaveIdleThread(PR_FALSE)
, mThreadCount(0)
, mAnyPriorityThreadCount(0)
, mEvictionQSize(0)
, mPendingCount(0)
, mShutdown(PR_TRUE)
{
mCreationTime = PR_Now();
PR_INIT_CLIST(&mHighQ);
PR_INIT_CLIST(&mMediumQ);
PR_INIT_CLIST(&mLowQ);
PR_INIT_CLIST(&mPendingQ);
PR_INIT_CLIST(&mEvictionQ);
mHighPriorityInfo.self = this;
mHighPriorityInfo.onlyHighPriority = PR_TRUE;
mAnyPriorityInfo.self = this;
mAnyPriorityInfo.onlyHighPriority = PR_FALSE;
mLongIdleTimeout = PR_SecondsToInterval(LongIdleTimeoutSeconds);
mShortIdleTimeout = PR_SecondsToInterval(ShortIdleTimeoutSeconds);
}
nsHostResolver::~nsHostResolver()
@ -392,29 +359,13 @@ nsHostResolver::Init()
return NS_OK;
}
void
nsHostResolver::ClearPendingQueue(PRCList *aPendingQ)
{
// loop through pending queue, erroring out pending lookups.
if (!PR_CLIST_IS_EMPTY(aPendingQ)) {
PRCList *node = aPendingQ->next;
while (node != aPendingQ) {
nsHostRecord *rec = static_cast<nsHostRecord *>(node);
node = node->next;
OnLookupComplete(rec, NS_ERROR_ABORT, nsnull);
}
}
}
void
nsHostResolver::Shutdown()
{
LOG(("nsHostResolver::Shutdown\n"));
PRCList pendingQHigh, pendingQMed, pendingQLow, evictionQ;
PR_INIT_CLIST(&pendingQHigh);
PR_INIT_CLIST(&pendingQMed);
PR_INIT_CLIST(&pendingQLow);
PRCList pendingQ, evictionQ;
PR_INIT_CLIST(&pendingQ);
PR_INIT_CLIST(&evictionQ);
{
@ -422,23 +373,26 @@ nsHostResolver::Shutdown()
mShutdown = PR_TRUE;
MoveCList(mHighQ, pendingQHigh);
MoveCList(mMediumQ, pendingQMed);
MoveCList(mLowQ, pendingQLow);
MoveCList(mPendingQ, pendingQ);
MoveCList(mEvictionQ, evictionQ);
mEvictionQSize = 0;
mPendingCount = 0;
if (mNumIdleThreads)
if (mHaveIdleThread)
PR_NotifyCondVar(mIdleThreadCV);
// empty host database
PL_DHashTableEnumerate(&mDB, HostDB_RemoveEntry, nsnull);
}
ClearPendingQueue(&pendingQHigh);
ClearPendingQueue(&pendingQMed);
ClearPendingQueue(&pendingQLow);
// loop through pending queue, erroring out pending lookups.
if (!PR_CLIST_IS_EMPTY(&pendingQ)) {
PRCList *node = pendingQ.next;
while (node != &pendingQ) {
nsHostRecord *rec = static_cast<nsHostRecord *>(node);
node = node->next;
OnLookupComplete(rec, NS_ERROR_ABORT, nsnull);
}
}
if (!PR_CLIST_IS_EMPTY(&evictionQ)) {
PRCList *node = evictionQ.next;
@ -451,33 +405,6 @@ nsHostResolver::Shutdown()
}
static inline PRBool
IsHighPriority(PRUint16 flags)
{
return !(flags & (nsHostResolver::RES_PRIORITY_LOW | nsHostResolver::RES_PRIORITY_MEDIUM));
}
static inline PRBool
IsMediumPriority(PRUint16 flags)
{
return flags & nsHostResolver::RES_PRIORITY_MEDIUM;
}
static inline PRBool
IsLowPriority(PRUint16 flags)
{
return flags & nsHostResolver::RES_PRIORITY_LOW;
}
void
nsHostResolver::MoveQueue(nsHostRecord *aRec, PRCList &aDestQ)
{
NS_ASSERTION(aRec->onQueue, "Moving Host Record Not Currently Queued");
PR_REMOVE_LINK(aRec);
PR_APPEND_LINK(aRec, &aDestQ);
}
nsresult
nsHostResolver::ResolveHost(const char *host,
PRUint16 flags,
@ -557,15 +484,9 @@ nsHostResolver::ResolveHost(const char *host,
// put reference to host record on stack...
result = he->rec;
}
else if (mPendingCount >= MAX_NON_PRIORITY_REQUESTS &&
!IsHighPriority(flags) &&
!he->rec->resolving) {
// This is a lower priority request and we are swamped, so refuse it.
rv = NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
}
// otherwise, hit the resolver...
else {
// Add callback to the list of pending callbacks.
// add callback to the list of pending callbacks
PR_APPEND_LINK(callback, &he->rec->callbacks);
if (!he->rec->resolving) {
@ -574,21 +495,6 @@ nsHostResolver::ResolveHost(const char *host,
if (NS_FAILED(rv))
PR_REMOVE_AND_INIT_LINK(callback);
}
else if (he->rec->onQueue) {
// Consider the case where we are on a pending queue of
// lower priority than the request is being made at.
// In that case we should upgrade to the higher queue.
if (IsHighPriority(flags) && !IsHighPriority(he->rec->flags)) {
// Move from (low|med) to high.
MoveQueue(he->rec, mHighQ);
he->rec->flags = flags;
} else if (IsMediumPriority(flags) && IsLowPriority(he->rec->flags)) {
// Move from low to med.
MoveQueue(he->rec, mMediumQ);
he->rec->flags = flags;
}
}
}
}
}
@ -637,57 +543,35 @@ nsHostResolver::IssueLookup(nsHostRecord *rec)
{
NS_ASSERTION(!rec->resolving, "record is already being resolved");
// Add rec to one of the pending queues, possibly removing it from mEvictionQ.
// If rec is on mEvictionQ, then we can just move the owning
// reference over to the new active queue.
// add rec to mPendingQ, possibly removing it from mEvictionQ.
// if rec is on mEvictionQ, then we can just move the owning
// reference over to mPendingQ.
if (rec->next == rec)
NS_ADDREF(rec);
else {
PR_REMOVE_LINK(rec);
mEvictionQSize--;
}
if (IsHighPriority(rec->flags))
PR_APPEND_LINK(rec, &mHighQ);
else if (IsMediumPriority(rec->flags))
PR_APPEND_LINK(rec, &mMediumQ);
else
PR_APPEND_LINK(rec, &mLowQ);
mPendingCount++;
PR_APPEND_LINK(rec, &mPendingQ);
rec->resolving = PR_TRUE;
rec->onQueue = PR_TRUE;
if (mNumIdleThreads) {
if (mHaveIdleThread) {
// wake up idle thread to process this lookup
PR_NotifyCondVar(mIdleThreadCV);
}
else if ((mThreadCount < HighThreadThreshold) ||
(IsHighPriority(rec->flags) && mThreadCount < MAX_RESOLVER_THREADS)) {
else if (mThreadCount < MAX_THREADS) {
// dispatch new worker thread
NS_ADDREF_THIS(); // owning reference passed to thread
struct nsHostResolverThreadInfo *info;
if (mAnyPriorityThreadCount < HighThreadThreshold) {
info = &mAnyPriorityInfo;
mAnyPriorityThreadCount++;
}
else
info = &mHighPriorityInfo;
mThreadCount++;
PRThread *thr = PR_CreateThread(PR_SYSTEM_THREAD,
ThreadFunc,
info,
this,
PR_PRIORITY_NORMAL,
PR_GLOBAL_THREAD,
PR_UNJOINABLE_THREAD,
0);
if (!thr) {
mThreadCount--;
if (info == &mAnyPriorityInfo)
mAnyPriorityThreadCount--;
NS_RELEASE_THIS();
return NS_ERROR_OUT_OF_MEMORY;
}
@ -700,54 +584,25 @@ nsHostResolver::IssueLookup(nsHostRecord *rec)
return NS_OK;
}
void
nsHostResolver::DeQueue(PRCList &aQ, nsHostRecord **aResult)
{
*aResult = static_cast<nsHostRecord *>(aQ.next);
PR_REMOVE_AND_INIT_LINK(*aResult);
mPendingCount--;
(*aResult)->onQueue = PR_FALSE;
}
PRBool
nsHostResolver::GetHostToLookup(nsHostRecord **result, struct nsHostResolverThreadInfo *aID)
nsHostResolver::GetHostToLookup(nsHostRecord **result)
{
nsAutoLock lock(mLock);
PRIntervalTime start = PR_IntervalNow(), timeout;
while (!mShutdown) {
// remove next record from Q; hand over owning reference. Check high, then med, then low
if (!PR_CLIST_IS_EMPTY(&mHighQ)) {
DeQueue (mHighQ, result);
return PR_TRUE;
}
if (! aID->onlyHighPriority) {
if (!PR_CLIST_IS_EMPTY(&mMediumQ)) {
DeQueue (mMediumQ, result);
return PR_TRUE;
}
if (!PR_CLIST_IS_EMPTY(&mLowQ)) {
DeQueue (mLowQ, result);
return PR_TRUE;
}
}
timeout = (mNumIdleThreads >= HighThreadThreshold) ? mShortIdleTimeout : mLongIdleTimeout;
// wait for one or more of the following to occur:
// (1) the pending queue has a host record to process
// (2) the shutdown flag has been set
// (3) the thread has been idle for too long
//
// PR_WaitCondVar will return when any of these conditions is true.
PRIntervalTime start = PR_IntervalNow(), timeout = IDLE_TIMEOUT;
//
// wait for one or more of the following to occur:
// (1) the pending queue has a host record to process
// (2) the shutdown flag has been set
// (3) the thread has been idle for too long
//
// PR_WaitCondVar will return when any of these conditions is true.
//
while (PR_CLIST_IS_EMPTY(&mPendingQ) && !mHaveIdleThread && !mShutdown) {
// become the idle thread and wait for a lookup
mNumIdleThreads++;
mHaveIdleThread = PR_TRUE;
PR_WaitCondVar(mIdleThreadCV, timeout);
mNumIdleThreads--;
mHaveIdleThread = PR_FALSE;
PRIntervalTime delta = PR_IntervalNow() - start;
if (delta >= timeout)
@ -756,10 +611,15 @@ nsHostResolver::GetHostToLookup(nsHostRecord **result, struct nsHostResolverThre
start += delta;
}
if (!PR_CLIST_IS_EMPTY(&mPendingQ)) {
// remove next record from mPendingQ; hand over owning reference.
*result = static_cast<nsHostRecord *>(mPendingQ.next);
PR_REMOVE_AND_INIT_LINK(*result);
return PR_TRUE;
}
// tell thread to exit...
mThreadCount--;
if (!aID->onlyHighPriority)
mAnyPriorityThreadCount--;
return PR_FALSE;
}
@ -838,11 +698,11 @@ nsHostResolver::ThreadFunc(void *arg)
#if defined(RES_RETRY_ON_FAILURE)
nsResState rs;
#endif
struct nsHostResolverThreadInfo *info = (struct nsHostResolverThreadInfo *) arg;
nsHostResolver *resolver = info->self;
nsHostResolver *resolver = (nsHostResolver *) arg;
nsHostRecord *rec;
PRAddrInfo *ai;
while (resolver->GetHostToLookup(&rec, info)) {
while (resolver->GetHostToLookup(&rec)) {
LOG(("resolving %s ...\n", rec->host));
PRIntn flags = PR_AI_ADDRCONFIG;

Просмотреть файл

@ -68,11 +68,6 @@ class nsResolveHostCallback;
return n; \
}
#define MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY 5
#define MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY 3
#define MAX_RESOLVER_THREADS (MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY + \
MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY)
struct nsHostKey
{
const char *host;
@ -129,9 +124,6 @@ private:
PRBool resolving; /* true if this record is being resolved, which means
* that it is either on the pending queue or owned by
* one of the worker threads. */
PRBool onQueue; /* true if pending and on the queue (not yet given to getaddrinfo())*/
~nsHostRecord();
};
@ -165,16 +157,6 @@ public:
nsresult status) = 0;
};
/**
* nsHostResolverThreadInfo structures are passed to the resolver
* thread.
*/
struct nsHostResolverThreadInfo
{
nsHostResolver *self;
PRBool onlyHighPriority;
};
/**
* nsHostResolver - an asynchronous host name resolver.
*/
@ -232,47 +214,32 @@ public:
*/
enum {
RES_BYPASS_CACHE = 1 << 0,
RES_CANON_NAME = 1 << 1,
RES_PRIORITY_MEDIUM = 1 << 2,
RES_PRIORITY_LOW = 1 << 3
RES_CANON_NAME = 1 << 1
};
private:
nsHostResolver(PRUint32 maxCacheEntries=50, PRUint32 maxCacheLifetime=1);
~nsHostResolver();
// nsHostResolverThreadInfo * is passed to the ThreadFunc
struct nsHostResolverThreadInfo mHighPriorityInfo, mAnyPriorityInfo;
nsresult Init();
nsresult IssueLookup(nsHostRecord *);
PRBool GetHostToLookup(nsHostRecord **m, struct nsHostResolverThreadInfo *aID);
PRBool GetHostToLookup(nsHostRecord **);
void OnLookupComplete(nsHostRecord *, nsresult, PRAddrInfo *);
void DeQueue(PRCList &aQ, nsHostRecord **aResult);
void ClearPendingQueue(PRCList *aPendingQueue);
static void MoveQueue(nsHostRecord *aRec, PRCList &aDestQ);
static void ThreadFunc(void *);
PRUint32 mMaxCacheEntries;
PRUint32 mMaxCacheLifetime;
PRLock *mLock;
PRCondVar *mIdleThreadCV; // non-null if idle thread
PRUint32 mNumIdleThreads;
PRBool mHaveIdleThread;
PRUint32 mThreadCount;
PRUint32 mAnyPriorityThreadCount;
PLDHashTable mDB;
PRCList mHighQ;
PRCList mMediumQ;
PRCList mLowQ;
PRCList mPendingQ;
PRCList mEvictionQ;
PRUint32 mEvictionQSize;
PRUint32 mPendingCount;
PRTime mCreationTime;
PRBool mShutdown;
PRIntervalTime mLongIdleTimeout;
PRIntervalTime mShortIdleTimeout;
};
#endif // nsHostResolver_h__

Просмотреть файл

@ -82,7 +82,6 @@
#include "nsIOService.h"
#include "nsAuthInformationHolder.h"
#include "nsICacheService.h"
#include "nsDNSPrefetch.h"
// True if the local cache should be bypassed when processing a request.
#define BYPASS_LOCAL_CACHE(loadFlags) \
@ -4003,13 +4002,6 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
if (NS_FAILED(rv))
return rv;
// Start a DNS lookup very early in case the real open is queued the DNS can
// happen in parallel.
nsRefPtr<nsDNSPrefetch> prefetch = new nsDNSPrefetch(mURI);
if (prefetch) {
prefetch->PrefetchMedium();
}
// Remember the cookie header that was set, if any
const char *cookieHeader = mRequestHead.PeekHeader(nsHttp::Cookie);
if (cookieHeader)