зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1616014 - Get rid off nsMainThreadPtrHandle in DNSListenerProxy r=valentin
Differential Revision: https://phabricator.services.mozilla.com/D75485
This commit is contained in:
Родитель
4060dae1b1
Коммит
9f9eb50d04
|
@ -10,6 +10,7 @@
|
||||||
#include "nsIXPConnect.h"
|
#include "nsIXPConnect.h"
|
||||||
#include "nsIProtocolProxyService.h"
|
#include "nsIProtocolProxyService.h"
|
||||||
#include "nsNetCID.h"
|
#include "nsNetCID.h"
|
||||||
|
#include "nsQueryObject.h"
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
#include "mozilla/net/NeckoChild.h"
|
#include "mozilla/net/NeckoChild.h"
|
||||||
|
@ -61,7 +62,7 @@ ChildDNSService::ChildDNSService()
|
||||||
void ChildDNSService::GetDNSRecordHashKey(
|
void ChildDNSService::GetDNSRecordHashKey(
|
||||||
const nsACString& aHost, const nsACString& aTrrServer, uint16_t aType,
|
const nsACString& aHost, const nsACString& aTrrServer, uint16_t aType,
|
||||||
const OriginAttributes& aOriginAttributes, uint32_t aFlags,
|
const OriginAttributes& aOriginAttributes, uint32_t aFlags,
|
||||||
nsIDNSListener* aListener, nsACString& aHashKey) {
|
uintptr_t aListenerAddr, nsACString& aHashKey) {
|
||||||
aHashKey.Assign(aHost);
|
aHashKey.Assign(aHost);
|
||||||
aHashKey.Assign(aTrrServer);
|
aHashKey.Assign(aTrrServer);
|
||||||
aHashKey.AppendInt(aType);
|
aHashKey.AppendInt(aType);
|
||||||
|
@ -71,7 +72,7 @@ void ChildDNSService::GetDNSRecordHashKey(
|
||||||
aHashKey.Append(originSuffix);
|
aHashKey.Append(originSuffix);
|
||||||
|
|
||||||
aHashKey.AppendInt(aFlags);
|
aHashKey.AppendInt(aFlags);
|
||||||
aHashKey.AppendPrintf("%p", aListener);
|
aHashKey.AppendPrintf("0x%" PRIxPTR, aListenerAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult ChildDNSService::AsyncResolveInternal(
|
nsresult ChildDNSService::AsyncResolveInternal(
|
||||||
|
@ -92,7 +93,7 @@ nsresult ChildDNSService::AsyncResolveInternal(
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need original listener for the pending requests hash.
|
// We need original listener for the pending requests hash.
|
||||||
nsIDNSListener* originalListener = listener;
|
uintptr_t originalListenerAddr = reinterpret_cast<uintptr_t>(listener);
|
||||||
|
|
||||||
// make sure JS callers get notification on the main thread
|
// make sure JS callers get notification on the main thread
|
||||||
nsCOMPtr<nsIEventTarget> target = target_;
|
nsCOMPtr<nsIEventTarget> target = target_;
|
||||||
|
@ -119,7 +120,7 @@ nsresult ChildDNSService::AsyncResolveInternal(
|
||||||
MutexAutoLock lock(mPendingRequestsLock);
|
MutexAutoLock lock(mPendingRequestsLock);
|
||||||
nsCString key;
|
nsCString key;
|
||||||
GetDNSRecordHashKey(hostname, aTrrServer, type, aOriginAttributes, flags,
|
GetDNSRecordHashKey(hostname, aTrrServer, type, aOriginAttributes, flags,
|
||||||
originalListener, key);
|
originalListenerAddr, key);
|
||||||
auto entry = mPendingRequests.LookupForAdd(key);
|
auto entry = mPendingRequests.LookupForAdd(key);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
entry.Data()->AppendElement(sender);
|
entry.Data()->AppendElement(sender);
|
||||||
|
@ -149,8 +150,9 @@ nsresult ChildDNSService::CancelAsyncResolveInternal(
|
||||||
MutexAutoLock lock(mPendingRequestsLock);
|
MutexAutoLock lock(mPendingRequestsLock);
|
||||||
nsTArray<RefPtr<DNSRequestSender>>* hashEntry;
|
nsTArray<RefPtr<DNSRequestSender>>* hashEntry;
|
||||||
nsCString key;
|
nsCString key;
|
||||||
|
uintptr_t listenerAddr = reinterpret_cast<uintptr_t>(aListener);
|
||||||
GetDNSRecordHashKey(aHostname, aTrrServer, aType, aOriginAttributes, aFlags,
|
GetDNSRecordHashKey(aHostname, aTrrServer, aType, aOriginAttributes, aFlags,
|
||||||
aListener, key);
|
listenerAddr, key);
|
||||||
if (mPendingRequests.Get(key, &hashEntry)) {
|
if (mPendingRequests.Get(key, &hashEntry)) {
|
||||||
// We cancel just one.
|
// We cancel just one.
|
||||||
hashEntry->ElementAt(0)->Cancel(aReason);
|
hashEntry->ElementAt(0)->Cancel(aReason);
|
||||||
|
@ -417,14 +419,11 @@ ChildDNSService::GetMyHostName(nsACString& result) {
|
||||||
void ChildDNSService::NotifyRequestDone(DNSRequestSender* aDnsRequest) {
|
void ChildDNSService::NotifyRequestDone(DNSRequestSender* aDnsRequest) {
|
||||||
// We need the original flags and listener for the pending requests hash.
|
// We need the original flags and listener for the pending requests hash.
|
||||||
uint32_t originalFlags = aDnsRequest->mFlags & ~RESOLVE_OFFLINE;
|
uint32_t originalFlags = aDnsRequest->mFlags & ~RESOLVE_OFFLINE;
|
||||||
nsCOMPtr<nsIDNSListener> originalListener = aDnsRequest->mListener;
|
uintptr_t originalListenerAddr =
|
||||||
nsCOMPtr<nsIDNSListenerProxy> wrapper = do_QueryInterface(originalListener);
|
reinterpret_cast<uintptr_t>(aDnsRequest->mListener.get());
|
||||||
|
RefPtr<DNSListenerProxy> wrapper = do_QueryObject(aDnsRequest->mListener);
|
||||||
if (wrapper) {
|
if (wrapper) {
|
||||||
wrapper->GetOriginalListener(getter_AddRefs(originalListener));
|
originalListenerAddr = wrapper->GetOriginalListenerAddress();
|
||||||
if (NS_WARN_IF(!originalListener)) {
|
|
||||||
MOZ_ASSERT(originalListener);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MutexAutoLock lock(mPendingRequestsLock);
|
MutexAutoLock lock(mPendingRequestsLock);
|
||||||
|
@ -432,7 +431,7 @@ void ChildDNSService::NotifyRequestDone(DNSRequestSender* aDnsRequest) {
|
||||||
nsCString key;
|
nsCString key;
|
||||||
GetDNSRecordHashKey(aDnsRequest->mHost, aDnsRequest->mTrrServer,
|
GetDNSRecordHashKey(aDnsRequest->mHost, aDnsRequest->mTrrServer,
|
||||||
aDnsRequest->mType, aDnsRequest->mOriginAttributes,
|
aDnsRequest->mType, aDnsRequest->mOriginAttributes,
|
||||||
originalFlags, originalListener, key);
|
originalFlags, originalListenerAddr, key);
|
||||||
|
|
||||||
nsTArray<RefPtr<DNSRequestSender>>* hashEntry;
|
nsTArray<RefPtr<DNSRequestSender>>* hashEntry;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ class ChildDNSService final : public nsPIDNSService, public nsIObserver {
|
||||||
void MOZ_ALWAYS_INLINE GetDNSRecordHashKey(
|
void MOZ_ALWAYS_INLINE GetDNSRecordHashKey(
|
||||||
const nsACString& aHost, const nsACString& aTrrServer, uint16_t aType,
|
const nsACString& aHost, const nsACString& aTrrServer, uint16_t aType,
|
||||||
const OriginAttributes& aOriginAttributes, uint32_t aFlags,
|
const OriginAttributes& aOriginAttributes, uint32_t aFlags,
|
||||||
nsIDNSListener* aListener, nsACString& aHashKey);
|
uintptr_t aListenerAddr, nsACString& aHashKey);
|
||||||
nsresult AsyncResolveInternal(const nsACString& hostname,
|
nsresult AsyncResolveInternal(const nsACString& hostname,
|
||||||
const nsACString& aTrrServer, uint16_t type,
|
const nsACString& aTrrServer, uint16_t type,
|
||||||
uint32_t flags, nsIDNSListener* listener,
|
uint32_t flags, nsIDNSListener* listener,
|
||||||
|
|
|
@ -10,26 +10,27 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace net {
|
namespace net {
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(DNSListenerProxy, nsIDNSListener, nsIDNSListenerProxy)
|
NS_IMPL_ADDREF(DNSListenerProxy)
|
||||||
|
NS_IMPL_RELEASE(DNSListenerProxy)
|
||||||
|
NS_INTERFACE_MAP_BEGIN(DNSListenerProxy)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIDNSListener)
|
||||||
|
NS_INTERFACE_MAP_ENTRY_CONCRETE(DNSListenerProxy)
|
||||||
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DNSListenerProxy::OnLookupComplete(nsICancelable* aRequest,
|
DNSListenerProxy::OnLookupComplete(nsICancelable* aRequest,
|
||||||
nsIDNSRecord* aRecord, nsresult aStatus) {
|
nsIDNSRecord* aRecord, nsresult aStatus) {
|
||||||
RefPtr<OnLookupCompleteRunnable> r =
|
RefPtr<DNSListenerProxy> self = this;
|
||||||
new OnLookupCompleteRunnable(mListener, aRequest, aRecord, aStatus);
|
nsCOMPtr<nsICancelable> request = aRequest;
|
||||||
return mTargetThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
nsCOMPtr<nsIDNSRecord> record = aRecord;
|
||||||
}
|
return mTargetThread->Dispatch(
|
||||||
|
NS_NewRunnableFunction("DNSListenerProxy::OnLookupComplete",
|
||||||
NS_IMETHODIMP
|
[self, request, record, aStatus]() {
|
||||||
DNSListenerProxy::OnLookupCompleteRunnable::Run() {
|
Unused << self->mListener->OnLookupComplete(
|
||||||
mListener->OnLookupComplete(mRequest, mRecord, mStatus);
|
request, record, aStatus);
|
||||||
return NS_OK;
|
self->mListener = nullptr;
|
||||||
}
|
}),
|
||||||
|
NS_DISPATCH_NORMAL);
|
||||||
NS_IMETHODIMP
|
|
||||||
DNSListenerProxy::GetOriginalListener(nsIDNSListener** aOriginalListener) {
|
|
||||||
NS_IF_ADDREF(*aOriginalListener = mListener);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace net
|
} // namespace net
|
||||||
|
|
|
@ -18,50 +18,44 @@ class nsICancelable;
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace net {
|
namespace net {
|
||||||
|
|
||||||
class DNSListenerProxy final : public nsIDNSListener,
|
#define DNS_LISTENER_PROXY_IID \
|
||||||
public nsIDNSListenerProxy {
|
{ \
|
||||||
|
0x8f172ca3, 0x7a7f, 0x4941, { \
|
||||||
|
0xa7, 0x0b, 0xbc, 0x72, 0x80, 0x2e, 0x9d, 0x9b \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
class DNSListenerProxy final : public nsIDNSListener {
|
||||||
public:
|
public:
|
||||||
DNSListenerProxy(nsIDNSListener* aListener, nsIEventTarget* aTargetThread)
|
DNSListenerProxy(nsIDNSListener* aListener, nsIEventTarget* aTargetThread)
|
||||||
// Sometimes aListener is a main-thread only object like XPCWrappedJS, and
|
// We want to make sure that |aListener| is only accessed on the target
|
||||||
// sometimes it's a threadsafe object like nsSOCKSSocketInfo. Use a main-
|
// thread.
|
||||||
// thread pointer holder, but disable strict enforcement of thread
|
: mListener(aListener),
|
||||||
// invariants. The AddRef implementation of XPCWrappedJS will assert if we
|
mTargetThread(aTargetThread),
|
||||||
// go wrong here.
|
mListenerAddress(reinterpret_cast<uintptr_t>(aListener)) {
|
||||||
: mListener(new nsMainThreadPtrHolder<nsIDNSListener>(
|
MOZ_ASSERT(mListener);
|
||||||
"DNSListenerProxy::mListener", aListener, false)),
|
MOZ_ASSERT(mTargetThread);
|
||||||
mTargetThread(aTargetThread) {}
|
}
|
||||||
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
NS_DECL_NSIDNSLISTENER
|
NS_DECL_NSIDNSLISTENER
|
||||||
NS_DECL_NSIDNSLISTENERPROXY
|
NS_DECLARE_STATIC_IID_ACCESSOR(DNS_LISTENER_PROXY_IID)
|
||||||
|
|
||||||
class OnLookupCompleteRunnable : public Runnable {
|
uintptr_t GetOriginalListenerAddress() const { return mListenerAddress; }
|
||||||
public:
|
|
||||||
OnLookupCompleteRunnable(
|
|
||||||
const nsMainThreadPtrHandle<nsIDNSListener>& aListener,
|
|
||||||
nsICancelable* aRequest, nsIDNSRecord* aRecord, nsresult aStatus)
|
|
||||||
: Runnable("DNSListenerProxy::OnLookupCompleteRunnable"),
|
|
||||||
mListener(aListener),
|
|
||||||
mRequest(aRequest),
|
|
||||||
mRecord(aRecord),
|
|
||||||
mStatus(aStatus) {}
|
|
||||||
|
|
||||||
NS_DECL_NSIRUNNABLE
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsMainThreadPtrHandle<nsIDNSListener> mListener;
|
|
||||||
nsCOMPtr<nsICancelable> mRequest;
|
|
||||||
nsCOMPtr<nsIDNSRecord> mRecord;
|
|
||||||
nsresult mStatus;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~DNSListenerProxy() {}
|
~DNSListenerProxy() {
|
||||||
|
NS_ProxyRelease("DNSListenerProxy::mListener", mTargetThread,
|
||||||
|
mListener.forget());
|
||||||
|
}
|
||||||
|
|
||||||
nsMainThreadPtrHandle<nsIDNSListener> mListener;
|
nsCOMPtr<nsIDNSListener> mListener;
|
||||||
nsCOMPtr<nsIEventTarget> mTargetThread;
|
nsCOMPtr<nsIEventTarget> mTargetThread;
|
||||||
|
uintptr_t mListenerAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NS_DEFINE_STATIC_IID_ACCESSOR(DNSListenerProxy, DNS_LISTENER_PROXY_IID)
|
||||||
|
|
||||||
} // namespace net
|
} // namespace net
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -437,13 +437,14 @@ void nsDNSAsyncRequest::OnResolveHostComplete(nsHostResolver* resolver,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsDNSAsyncRequest::EqualsAsyncListener(nsIDNSListener* aListener) {
|
bool nsDNSAsyncRequest::EqualsAsyncListener(nsIDNSListener* aListener) {
|
||||||
nsCOMPtr<nsIDNSListenerProxy> wrapper = do_QueryInterface(mListener);
|
uintptr_t originalListenerAddr = reinterpret_cast<uintptr_t>(mListener.get());
|
||||||
|
RefPtr<DNSListenerProxy> wrapper = do_QueryObject(mListener);
|
||||||
if (wrapper) {
|
if (wrapper) {
|
||||||
nsCOMPtr<nsIDNSListener> originalListener;
|
originalListenerAddr = wrapper->GetOriginalListenerAddress();
|
||||||
wrapper->GetOriginalListener(getter_AddRefs(originalListener));
|
|
||||||
return aListener == originalListener;
|
|
||||||
}
|
}
|
||||||
return (aListener == mListener);
|
|
||||||
|
uintptr_t listenerAddr = reinterpret_cast<uintptr_t>(aListener);
|
||||||
|
return (listenerAddr == originalListenerAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nsDNSAsyncRequest::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const {
|
size_t nsDNSAsyncRequest::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const {
|
||||||
|
|
|
@ -29,19 +29,3 @@ interface nsIDNSListener : nsISupports
|
||||||
in nsIDNSRecord aRecord,
|
in nsIDNSRecord aRecord,
|
||||||
in nsresult aStatus);
|
in nsresult aStatus);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* nsIDNSListenerProxy:
|
|
||||||
*
|
|
||||||
* Must be implemented by classes that wrap the original listener passed to
|
|
||||||
* nsIDNSService.AsyncResolve, so we have access to original listener for
|
|
||||||
* comparison purposes.
|
|
||||||
*/
|
|
||||||
[uuid(60eff0e4-6f7c-493c-add9-1cbea59063ad)]
|
|
||||||
interface nsIDNSListenerProxy : nsISupports
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The original nsIDNSListener which requested hostname resolution.
|
|
||||||
*/
|
|
||||||
readonly attribute nsIDNSListener originalListener;
|
|
||||||
};
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче