author | Cosmin Sabou <csabou@mozilla.com> |
Mon, 18 Dec 2017 11:52:06 +0200 | |
changeset 396680 | 5572465c08a9 |
parent 396679 | 3a842d55ff1f |
child 396681 | be9d30ca06ec |
child 396690 | 2fcff634ec0e |
child 396709 | 59a2346b07f7 |
push id | 33107 |
push user | csabou@mozilla.com |
push date | Mon, 18 Dec 2017 09:52:35 +0000 |
treeherder | mozilla-central@5572465c08a9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | backout, backout |
bugs | 1424834 |
milestone | 59.0a1 |
backs out | 2503df83bbd9 49cc08386f17 |
first release with | nightly linux32
5572465c08a9
/
59.0a1
/
20171218100313
/
files
nightly linux64
5572465c08a9
/
59.0a1
/
20171218100313
/
files
nightly mac
5572465c08a9
/
59.0a1
/
20171218100313
/
files
nightly win32
5572465c08a9
/
59.0a1
/
20171218100313
/
files
nightly win64
5572465c08a9
/
59.0a1
/
20171218100313
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
59.0a1
/
20171218100313
/
pushlog to previous
nightly linux64
59.0a1
/
20171218100313
/
pushlog to previous
nightly mac
59.0a1
/
20171218100313
/
pushlog to previous
nightly win32
59.0a1
/
20171218100313
/
pushlog to previous
nightly win64
59.0a1
/
20171218100313
/
pushlog to previous
|
--- a/mfbt/LinkedList.h +++ b/mfbt/LinkedList.h @@ -546,17 +546,17 @@ public: * Measures the memory consumption of the list excluding |this|. Note that * it only measures the list elements themselves. If the list elements * contain pointers to other memory blocks, those blocks must be measured * separately during a subsequent iteration over the list. */ size_t sizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { size_t n = 0; - for (ConstRawType t = getFirst(); t; t = t->getNext()) { + for (const T* t = getFirst(); t; t = t->getNext()) { n += aMallocSizeOf(t); } return n; } /* * Like sizeOfExcludingThis(), but measures |this| as well. */
--- a/netwerk/dns/nsDNSService2.cpp +++ b/netwerk/dns/nsDNSService2.cpp @@ -290,16 +290,18 @@ nsDNSRecord::ReportUnusable(uint16_t aPo return NS_OK; } //----------------------------------------------------------------------------- class nsDNSAsyncRequest final : public nsResolveHostCallback , public nsICancelable { + ~nsDNSAsyncRequest() = default; + public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSICANCELABLE nsDNSAsyncRequest(nsHostResolver *res, const nsACString &host, const OriginAttributes &attrs, nsIDNSListener *listener, @@ -324,38 +326,38 @@ public: RefPtr<nsHostResolver> mResolver; nsCString mHost; // hostname we're resolving const OriginAttributes mOriginAttributes; // The originAttributes for this resolving nsCOMPtr<nsIDNSListener> mListener; uint16_t mFlags; uint16_t mAF; nsCString mNetworkInterface; -private: - virtual ~nsDNSAsyncRequest() = default; }; -NS_IMPL_ISUPPORTS(nsDNSAsyncRequest, nsICancelable) - void nsDNSAsyncRequest::OnResolveHostComplete(nsHostResolver *resolver, nsHostRecord *hostRecord, nsresult status) { // need to have an owning ref when we issue the callback to enable // the caller to be able to addref/release multiple times without // destroying the record prematurely. nsCOMPtr<nsIDNSRecord> rec; if (NS_SUCCEEDED(status)) { NS_ASSERTION(hostRecord, "no host record"); rec = new nsDNSRecord(hostRecord); } mListener->OnLookupComplete(this, rec, status); mListener = nullptr; + + // release the reference to ourselves that was added before we were + // handed off to the host resolver. + NS_RELEASE_THIS(); } bool nsDNSAsyncRequest::EqualsAsyncListener(nsIDNSListener *aListener) { nsCOMPtr<nsIDNSListenerProxy> wrapper = do_QueryInterface(mListener); if (wrapper) { nsCOMPtr<nsIDNSListener> originalListener; @@ -373,53 +375,50 @@ nsDNSAsyncRequest::SizeOfIncludingThis(M // The following fields aren't measured. // - mHost, because it's a non-owning pointer // - mResolver, because it's a non-owning pointer // - mListener, because it's a non-owning pointer return n; } +NS_IMPL_ISUPPORTS(nsDNSAsyncRequest, nsICancelable) + NS_IMETHODIMP nsDNSAsyncRequest::Cancel(nsresult reason) { NS_ENSURE_ARG(NS_FAILED(reason)); mResolver->DetachCallback(mHost.get(), mOriginAttributes, mFlags, mAF, mNetworkInterface.get(), this, reason); return NS_OK; } //----------------------------------------------------------------------------- -class nsDNSSyncRequest - : public nsResolveHostCallback +class nsDNSSyncRequest : public nsResolveHostCallback { - NS_DECL_THREADSAFE_ISUPPORTS public: explicit nsDNSSyncRequest(PRMonitor *mon) : mDone(false) , mStatus(NS_OK) , mMonitor(mon) {} + virtual ~nsDNSSyncRequest() = default; void OnResolveHostComplete(nsHostResolver *, nsHostRecord *, nsresult) override; bool EqualsAsyncListener(nsIDNSListener *aListener) override; size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const override; bool mDone; nsresult mStatus; RefPtr<nsHostRecord> mHostRecord; private: - virtual ~nsDNSSyncRequest() = default; - PRMonitor *mMonitor; }; -NS_IMPL_ISUPPORTS0(nsDNSSyncRequest) - void nsDNSSyncRequest::OnResolveHostComplete(nsHostResolver *resolver, nsHostRecord *hostRecord, nsresult status) { // store results, and wake up nsDNSService::Resolve to process results. PR_EnterMonitor(mMonitor); mDone = true; @@ -794,27 +793,26 @@ nsDNSService::AsyncResolveExtended(const listener, target_, attrs, result); } NS_IMETHODIMP nsDNSService::AsyncResolveExtendedNative(const nsACString &aHostname, uint32_t flags, const nsACString &aNetworkInterface, - nsIDNSListener *aListener, + nsIDNSListener *listener, nsIEventTarget *target_, const OriginAttributes &aOriginAttributes, nsICancelable **result) { // grab reference to global host resolver and IDN service. beware // simultaneous shutdown!! RefPtr<nsHostResolver> res; nsCOMPtr<nsIIDNService> idn; nsCOMPtr<nsIEventTarget> target = target_; - nsCOMPtr<nsIDNSListener> listener = aListener; bool localDomain = false; { MutexAutoLock lock(mLock); if (mDisablePrefetch && (flags & RESOLVE_SPECULATE)) return NS_ERROR_DNS_LOOKUP_QUEUE_FULL; res = mResolver; @@ -847,26 +845,31 @@ nsDNSService::AsyncResolveExtendedNative } if (target) { listener = new DNSListenerProxy(listener, target); } uint16_t af = GetAFForLookup(hostname, flags); - MOZ_ASSERT(listener); - RefPtr<nsDNSAsyncRequest> req = + auto *req = new nsDNSAsyncRequest(res, hostname, aOriginAttributes, listener, flags, af, aNetworkInterface); if (!req) return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*result = req); + // addref for resolver; will be released when OnResolveHostComplete is called. + NS_ADDREF(req); rv = res->ResolveHost(req->mHost.get(), req->mOriginAttributes, flags, af, req->mNetworkInterface.get(), req); - req.forget(result); + if (NS_FAILED(rv)) { + NS_RELEASE(req); + NS_RELEASE(*result); + } return rv; } NS_IMETHODIMP nsDNSService::CancelAsyncResolve(const nsACString &aHostname, uint32_t aFlags, nsIDNSListener *aListener, nsresult aReason, @@ -1047,33 +1050,35 @@ nsDNSService::ResolveInternal(const nsAC // we need to use a monitor! ;-) // PRMonitor *mon = PR_NewMonitor(); if (!mon) return NS_ERROR_OUT_OF_MEMORY; PR_EnterMonitor(mon); - RefPtr<nsDNSSyncRequest> syncReq = new nsDNSSyncRequest(mon); + nsDNSSyncRequest syncReq(mon); uint16_t af = GetAFForLookup(hostname, flags); - rv = res->ResolveHost(hostname.get(), aOriginAttributes, flags, af, "", syncReq); + rv = res->ResolveHost(hostname.get(), aOriginAttributes, flags, af, "", &syncReq); if (NS_SUCCEEDED(rv)) { // wait for result - while (!syncReq->mDone) { + while (!syncReq.mDone) PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); - } - if (NS_FAILED(syncReq->mStatus)) { - rv = syncReq->mStatus; - } else { - NS_ASSERTION(syncReq->mHostRecord, "no host record"); - RefPtr<nsDNSRecord> rec = new nsDNSRecord(syncReq->mHostRecord); - rec.forget(result); + if (NS_FAILED(syncReq.mStatus)) + rv = syncReq.mStatus; + else { + NS_ASSERTION(syncReq.mHostRecord, "no host record"); + auto *rec = new nsDNSRecord(syncReq.mHostRecord); + if (!rec) + rv = NS_ERROR_OUT_OF_MEMORY; + else + NS_ADDREF(*result = rec); } } PR_ExitMonitor(mon); PR_DestroyMonitor(mon); return rv; }
--- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -184,16 +184,17 @@ nsHostRecord::nsHostRecord(const nsHostK af = key->af; netInterface = host + strlen(key->host) + 1; memcpy((char *) netInterface, key->netInterface, strlen(key->netInterface) + 1); originSuffix = netInterface + strlen(key->netInterface) + 1; memcpy((char *) originSuffix, key->originSuffix, strlen(key->originSuffix) + 1); PR_INIT_CLIST(this); + PR_INIT_CLIST(&callbacks); } nsresult nsHostRecord::Create(const nsHostKey *key, nsHostRecord **result) { size_t hostLen = strlen(key->host) + 1; size_t netInterfaceLen = strlen(key->netInterface) + 1; size_t originSuffixLen = strlen(key->originSuffix) + 1; @@ -224,18 +225,16 @@ nsHostRecord::CopyExpirationTimesAndFlag mValidStart = aFromHostRecord->mValidStart; mValidEnd = aFromHostRecord->mValidEnd; mGraceStart = aFromHostRecord->mGraceStart; mDoomed = aFromHostRecord->mDoomed; } nsHostRecord::~nsHostRecord() { - mCallbacks.clear(); - Telemetry::Accumulate(Telemetry::DNS_BLACKLIST_COUNT, mBlacklistedCount); delete addr_info; } bool nsHostRecord::Blacklisted(NetAddr *aQuery) { // must call locked @@ -322,39 +321,41 @@ nsHostRecord::HasUsableResult(const mozi if (CheckExpiration(now) == EXP_EXPIRED) { return false; } return addr_info || addr || negative; } static size_t -SizeOfResolveHostCallbackListExcludingHead(const mozilla::LinkedList<RefPtr<nsResolveHostCallback>>& aCallbacks, +SizeOfResolveHostCallbackListExcludingHead(const PRCList *head, MallocSizeOf mallocSizeOf) { - size_t n = aCallbacks.sizeOfIncludingThis(mallocSizeOf); - - for (const nsResolveHostCallback* t = aCallbacks.getFirst(); t; t = t->getNext()) { - n += t->SizeOfIncludingThis(mallocSizeOf); + size_t n = 0; + PRCList *curr = head->next; + while (curr != head) { + nsResolveHostCallback *callback = + static_cast<nsResolveHostCallback*>(curr); + n += callback->SizeOfIncludingThis(mallocSizeOf); + curr = curr->next; } - return n; } size_t nsHostRecord::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const { size_t n = mallocSizeOf(this); // The |host| field (inherited from nsHostKey) actually points to extra // memory that is allocated beyond the end of the nsHostRecord (see // nsHostRecord::Create()). So it will be included in the // |mallocSizeOf(this)| call above. - n += SizeOfResolveHostCallbackListExcludingHead(mCallbacks, mallocSizeOf); + n += SizeOfResolveHostCallbackListExcludingHead(&callbacks, mallocSizeOf); n += addr_info ? addr_info->SizeOfIncludingThis(mallocSizeOf) : 0; n += mallocSizeOf(addr.get()); n += mBlacklistedItems.ShallowSizeOfExcludingThis(mallocSizeOf); for (size_t i = 0; i < mBlacklistedItems.Length(); i++) { n += mBlacklistedItems[i].SizeOfExcludingThisIfUnshared(mallocSizeOf); } return n; @@ -727,30 +728,29 @@ nsHostResolver::MoveQueue(nsHostRecord * } nsresult nsHostResolver::ResolveHost(const char *host, const OriginAttributes &aOriginAttributes, uint16_t flags, uint16_t af, const char *netInterface, - nsResolveHostCallback *aCallback) + nsResolveHostCallback *callback) { NS_ENSURE_TRUE(host && *host, NS_ERROR_UNEXPECTED); NS_ENSURE_TRUE(netInterface, NS_ERROR_UNEXPECTED); LOG(("Resolving host [%s%s%s]%s.\n", LOG_HOST(host, netInterface), flags & RES_BYPASS_CACHE ? " - bypassing cache" : "")); // ensure that we are working with a valid hostname before proceeding. see // bug 304904 for details. if (!net_IsValidHostName(nsDependentCString(host))) return NS_ERROR_UNKNOWN_HOST; - RefPtr<nsResolveHostCallback> callback(aCallback); // if result is set inside the lock, then we need to issue the // callback before returning. RefPtr<nsHostRecord> result; nsresult status = NS_OK, rv = NS_OK; { MutexAutoLock lock(mLock); if (mShutdown) @@ -926,36 +926,36 @@ nsHostResolver::ResolveHost(const char } // If no valid address was found in the cache or this is an // AF_UNSPEC request, then start a new lookup. if (!result) { LOG((" No usable address in cache for host [%s%s%s].", LOG_HOST(host, netInterface))); // Add callback to the list of pending callbacks. - he->rec->mCallbacks.insertBack(callback); + PR_APPEND_LINK(callback, &he->rec->callbacks); he->rec->flags = flags; rv = IssueLookup(he->rec); Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2, METHOD_NETWORK_FIRST); - if (NS_FAILED(rv) && callback->isInList()) { - callback->remove(); + if (NS_FAILED(rv)) { + PR_REMOVE_AND_INIT_LINK(callback); } else { LOG((" DNS lookup for host [%s%s%s] blocking " "pending 'getaddrinfo' query: callback [%p]", - LOG_HOST(host, netInterface), callback.get())); + LOG_HOST(host, netInterface), callback)); } } } else { LOG((" Host [%s%s%s] is being resolved. Appending callback " - "[%p].", LOG_HOST(host, netInterface), callback.get())); + "[%p].", LOG_HOST(host, netInterface), callback)); - he->rec->mCallbacks.insertBack(callback); + PR_APPEND_LINK(callback, &he->rec->callbacks); if (he->rec->onQueue) { Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2, METHOD_NETWORK_SHARED); // 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. @@ -971,66 +971,60 @@ nsHostResolver::ResolveHost(const char MoveQueue(he->rec, mMediumQ); he->rec->flags = flags; mIdleThreadCV.Notify(); } } } } } - if (result) { - if (callback->isInList()) { - callback->remove(); - } callback->OnResolveHostComplete(this, result, status); } return rv; } void nsHostResolver::DetachCallback(const char *host, const OriginAttributes &aOriginAttributes, uint16_t flags, uint16_t af, const char *netInterface, - nsResolveHostCallback *aCallback, + nsResolveHostCallback *callback, nsresult status) { RefPtr<nsHostRecord> rec; - RefPtr<nsResolveHostCallback> callback(aCallback); - { MutexAutoLock lock(mLock); nsAutoCString originSuffix; aOriginAttributes.CreateSuffix(originSuffix); nsHostKey key = { host, flags, af, netInterface, originSuffix.get() }; auto he = static_cast<nsHostDBEnt*>(mDB.Search(&key)); if (he) { // walk list looking for |callback|... we cannot assume // that it will be there! - - for (nsResolveHostCallback* c: he->rec->mCallbacks) { - if (c == callback) { + PRCList *node = he->rec->callbacks.next; + while (node != &he->rec->callbacks) { + if (static_cast<nsResolveHostCallback *>(node) == callback) { + PR_REMOVE_LINK(callback); rec = he->rec; - c->remove(); break; } + node = node->next; } } } // complete callback with the given status code; this would only be done if // the record was in the process of being resolved. - if (rec) { + if (rec) callback->OnResolveHostComplete(this, rec, status); - } } nsresult nsHostResolver::ConditionallyCreateThread(nsHostRecord *rec) { if (mNumIdleThreads) { // wake up idle thread to process this lookup mIdleThreadCV.Notify(); @@ -1294,30 +1288,30 @@ different_rrset(AddrInfo *rrset1, AddrIn // CompleteLookup() checks if the resolving should be redone and if so it // returns LOOKUP_RESOLVEAGAIN, but only if 'status' is not NS_ERROR_ABORT. // takes ownership of AddrInfo parameter nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(nsHostRecord* rec, nsresult status, AddrInfo* newRRSet) { // get the list of pending callbacks for this lookup, and notify // them that the lookup is complete. - mozilla::LinkedList<RefPtr<nsResolveHostCallback>> cbs; - + PRCList cbs; + PR_INIT_CLIST(&cbs); { MutexAutoLock lock(mLock); if (rec->mResolveAgain && (status != NS_ERROR_ABORT)) { LOG(("nsHostResolver record %p resolve again due to flushcache\n", rec)); rec->mResolveAgain = false; delete newRRSet; return LOOKUP_RESOLVEAGAIN; } // grab list of callbacks to notify - cbs = mozilla::Move(rec->mCallbacks); + MoveCList(rec->callbacks, cbs); // update record fields. We might have a rec->addr_info already if a // previous lookup result expired and we're reresolving it.. AddrInfo *old_addr_info; { MutexAutoLock lock(rec->addr_info_lock); if (different_rrset(rec->addr_info, newRRSet)) { LOG(("nsHostResolver record %p new gencnt\n", rec)); @@ -1375,18 +1369,25 @@ nsHostResolver::CompleteLookup(nsHostRec NS_WARNING_ASSERTION( NS_SUCCEEDED(rv), "Could not issue second async lookup for TTL."); } #endif } } - for (nsResolveHostCallback* c = cbs.getFirst(); c; c = c->removeAndGetNext()) { - c->OnResolveHostComplete(this, rec, status); + if (!PR_CLIST_IS_EMPTY(&cbs)) { + PRCList *node = cbs.next; + while (node != &cbs) { + nsResolveHostCallback *callback = + static_cast<nsResolveHostCallback *>(node); + node = node->next; + callback->OnResolveHostComplete(this, rec, status); + // NOTE: callback must not be dereferenced after this point!! + } } NS_RELEASE(rec); return LOOKUP_OK; } void @@ -1404,28 +1405,34 @@ nsHostResolver::CancelAsyncRequest(const nsAutoCString originSuffix; aOriginAttributes.CreateSuffix(originSuffix); // Lookup the host record associated with host, flags & address family nsHostKey key = { host, flags, af, netInterface, originSuffix.get() }; auto he = static_cast<nsHostDBEnt*>(mDB.Search(&key)); if (he) { nsHostRecord* recPtr = nullptr; - - for (RefPtr<nsResolveHostCallback> c : he->rec->mCallbacks) { - if (c->EqualsAsyncListener(aListener)) { - c->remove(); + PRCList *node = he->rec->callbacks.next; + // Remove the first nsDNSAsyncRequest callback which matches the + // supplied listener object + while (node != &he->rec->callbacks) { + nsResolveHostCallback *callback + = static_cast<nsResolveHostCallback *>(node); + if (callback && (callback->EqualsAsyncListener(aListener))) { + // Remove from the list of callbacks + PR_REMOVE_LINK(callback); recPtr = he->rec; - c->OnResolveHostComplete(this, recPtr, status); + callback->OnResolveHostComplete(this, recPtr, status); break; } + node = node->next; } // If there are no more callbacks, remove the hash table entry - if (recPtr && recPtr->mCallbacks.isEmpty()) { + if (recPtr && PR_CLIST_IS_EMPTY(&recPtr->callbacks)) { mDB.Remove((nsHostKey *)recPtr); // If record is on a Queue, remove it and then deref it if (recPtr->next != recPtr) { PR_REMOVE_LINK(recPtr); NS_RELEASE(recPtr); } } }
--- a/netwerk/dns/nsHostResolver.h +++ b/netwerk/dns/nsHostResolver.h @@ -15,17 +15,16 @@ #include "nsISupportsImpl.h" #include "nsIDNSListener.h" #include "nsIDNSService.h" #include "nsString.h" #include "nsTArray.h" #include "GetAddrInfo.h" #include "mozilla/net/DNS.h" #include "mozilla/net/DashboardTypes.h" -#include "mozilla/LinkedList.h" #include "mozilla/TimeStamp.h" #include "mozilla/UniquePtr.h" class nsHostResolver; class nsHostRecord; class nsResolveHostCallback; #define MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY 3 @@ -126,17 +125,18 @@ public: static DnsPriority GetPriority(uint16_t aFlags); bool RemoveOrRefresh(); // Mark records currently being resolved as needed // to resolve again. private: friend class nsHostResolver; - mozilla::LinkedList<RefPtr<nsResolveHostCallback>> mCallbacks; + + PRCList callbacks; /* list of callbacks */ bool 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. */ bool onQueue; /* true if pending and on the queue (not yet given to getaddrinfo())*/ bool usingAnyThread; /* true if off queue and contributing to mActiveAnyThreadCount */ bool mDoomed; /* explicitly expired */ @@ -158,23 +158,20 @@ private: // of gencnt. nsTArray<nsCString> mBlacklistedItems; explicit nsHostRecord(const nsHostKey *key); /* use Create() instead */ ~nsHostRecord(); }; /** - * This class is used to notify listeners when a ResolveHost operation is - * complete. Classes that derive it must implement threadsafe nsISupports - * to be able to use RefPtr with this class. + * ResolveHost callback object. It's PRCList members are used by + * the nsHostResolver and should not be used by anything else. */ -class nsResolveHostCallback - : public mozilla::LinkedListElement<RefPtr<nsResolveHostCallback>> - , public nsISupports +class NS_NO_VTABLE nsResolveHostCallback : public PRCList { public: /** * OnResolveHostComplete * * this function is called to complete a host lookup initiated by * nsHostResolver::ResolveHost. it may be invoked recursively from * ResolveHost or on an unspecified background thread. @@ -203,18 +200,16 @@ public: * the original listener is known. * * @param aListener * nsIDNSListener object associated with the original request */ virtual bool EqualsAsyncListener(nsIDNSListener *aListener) = 0; virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const = 0; -protected: - virtual ~nsResolveHostCallback() = default; }; /** * nsHostResolver - an asynchronous host name resolver. */ class nsHostResolver { typedef mozilla::CondVar CondVar;