Bug 1600678 - Use IPDL refcounted for DNSRequest r=valentin

Differential Revision: https://phabricator.services.mozilla.com/D55475

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kershaw Chang 2019-12-02 18:28:49 +00:00
Родитель 2fc5985a45
Коммит a1a7f14884
13 изменённых файлов: 18 добавлений и 106 удалений

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

@ -196,7 +196,7 @@ class CancelDNSRequestEvent : public Runnable {
mReasonForCancel(aReason) {} mReasonForCancel(aReason) {}
NS_IMETHOD Run() override { NS_IMETHOD Run() override {
if (mDnsRequest->mIPCOpen) { if (mDnsRequest->CanSend()) {
// Send request to Parent process. // Send request to Parent process.
mDnsRequest->SendCancelDNSRequest(mDnsRequest->mHost, mDnsRequest->mType, mDnsRequest->SendCancelDNSRequest(mDnsRequest->mHost, mDnsRequest->mType,
mDnsRequest->mOriginAttributes, mDnsRequest->mOriginAttributes,
@ -225,8 +225,7 @@ DNSRequestChild::DNSRequestChild(const nsACString& aHost, const uint16_t& aType,
mHost(aHost), mHost(aHost),
mType(aType), mType(aType),
mOriginAttributes(aOriginAttributes), mOriginAttributes(aOriginAttributes),
mFlags(aFlags), mFlags(aFlags) {}
mIPCOpen(false) {}
void DNSRequestChild::StartRequest() { void DNSRequestChild::StartRequest() {
// we can only do IPDL on the main thread // we can only do IPDL on the main thread
@ -263,11 +262,6 @@ void DNSRequestChild::StartRequest() {
MOZ_ASSERT(false, "Wrong process"); MOZ_ASSERT(false, "Wrong process");
return; return;
} }
mIPCOpen = true;
// IPDL holds a reference until IPDL channel gets destroyed
AddIPDLReference();
} }
void DNSRequestChild::CallOnLookupComplete() { void DNSRequestChild::CallOnLookupComplete() {
@ -283,7 +277,6 @@ void DNSRequestChild::CallOnLookupByTypeComplete() {
mozilla::ipc::IPCResult DNSRequestChild::RecvLookupCompleted( mozilla::ipc::IPCResult DNSRequestChild::RecvLookupCompleted(
const DNSRequestResponse& reply) { const DNSRequestResponse& reply) {
mIPCOpen = false;
MOZ_ASSERT(mListener); MOZ_ASSERT(mListener);
switch (reply.type()) { switch (reply.type()) {
@ -340,17 +333,13 @@ mozilla::ipc::IPCResult DNSRequestChild::RecvLookupCompleted(
return IPC_OK(); return IPC_OK();
} }
void DNSRequestChild::ReleaseIPDLReference() { void DNSRequestChild::ActorDestroy(ActorDestroyReason why) {
// Request is done or destroyed. Remove it from the hash table. // Request is done or destroyed. Remove it from the hash table.
RefPtr<ChildDNSService> dnsServiceChild = RefPtr<ChildDNSService> dnsServiceChild =
dont_AddRef(ChildDNSService::GetSingleton()); dont_AddRef(ChildDNSService::GetSingleton());
dnsServiceChild->NotifyRequestDone(this); dnsServiceChild->NotifyRequestDone(this);
Release();
} }
void DNSRequestChild::ActorDestroy(ActorDestroyReason why) { mIPCOpen = false; }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// DNSRequestChild::nsISupports // DNSRequestChild::nsISupports
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -363,7 +352,7 @@ NS_IMPL_ISUPPORTS(DNSRequestChild, nsICancelable)
NS_IMETHODIMP NS_IMETHODIMP
DNSRequestChild::Cancel(nsresult reason) { DNSRequestChild::Cancel(nsresult reason) {
if (mIPCOpen) { if (CanSend()) {
// We can only do IPDL on the main thread // We can only do IPDL on the main thread
nsCOMPtr<nsIRunnable> runnable = new CancelDNSRequestEvent(this, reason); nsCOMPtr<nsIRunnable> runnable = new CancelDNSRequestEvent(this, reason);
SystemGroup::Dispatch(TaskCategory::Other, runnable.forget()); SystemGroup::Dispatch(TaskCategory::Other, runnable.forget());

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

@ -29,9 +29,6 @@ class DNSRequestChild final : public PDNSRequestChild, public nsICancelable {
const uint32_t& aFlags, nsIDNSListener* aListener, const uint32_t& aFlags, nsIDNSListener* aListener,
nsIEventTarget* target); nsIEventTarget* target);
void AddIPDLReference() { AddRef(); }
void ReleaseIPDLReference();
// Sends IPDL request to parent // Sends IPDL request to parent
void StartRequest(); void StartRequest();
void CallOnLookupComplete(); void CallOnLookupComplete();
@ -40,7 +37,7 @@ class DNSRequestChild final : public PDNSRequestChild, public nsICancelable {
protected: protected:
friend class CancelDNSRequestEvent; friend class CancelDNSRequestEvent;
friend class ChildDNSService; friend class ChildDNSService;
virtual ~DNSRequestChild() {} virtual ~DNSRequestChild() = default;
mozilla::ipc::IPCResult RecvLookupCompleted(const DNSRequestResponse& reply); mozilla::ipc::IPCResult RecvLookupCompleted(const DNSRequestResponse& reply);
virtual void ActorDestroy(ActorDestroyReason why) override; virtual void ActorDestroy(ActorDestroyReason why) override;
@ -60,7 +57,6 @@ class DNSRequestChild final : public PDNSRequestChild, public nsICancelable {
uint16_t mType; uint16_t mType;
const OriginAttributes mOriginAttributes; const OriginAttributes mOriginAttributes;
uint16_t mFlags; uint16_t mFlags;
bool mIPCOpen;
}; };
} // namespace net } // namespace net

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

@ -19,7 +19,7 @@ using namespace mozilla::ipc;
namespace mozilla { namespace mozilla {
namespace net { namespace net {
DNSRequestParent::DNSRequestParent() : mFlags(0), mIPCClosed(false) {} DNSRequestParent::DNSRequestParent() : mFlags(0) {}
void DNSRequestParent::DoAsyncResolve(const nsACString& hostname, void DNSRequestParent::DoAsyncResolve(const nsACString& hostname,
const OriginAttributes& originAttributes, const OriginAttributes& originAttributes,
@ -34,8 +34,7 @@ void DNSRequestParent::DoAsyncResolve(const nsACString& hostname,
getter_AddRefs(unused)); getter_AddRefs(unused));
} }
if (NS_FAILED(rv) && !mIPCClosed) { if (NS_FAILED(rv) && CanSend()) {
mIPCClosed = true;
Unused << SendLookupCompleted(DNSRequestResponse(rv)); Unused << SendLookupCompleted(DNSRequestResponse(rv));
} }
} }
@ -58,17 +57,6 @@ mozilla::ipc::IPCResult DNSRequestParent::RecvCancelDNSRequest(
return IPC_OK(); return IPC_OK();
} }
mozilla::ipc::IPCResult DNSRequestParent::Recv__delete__() {
mIPCClosed = true;
return IPC_OK();
}
void DNSRequestParent::ActorDestroy(ActorDestroyReason why) {
// We may still have refcount>0 if DNS hasn't called our OnLookupComplete
// yet, but child process has crashed. We must not send any more msgs
// to child, or IPDL will kill chrome process, too.
mIPCClosed = true;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// DNSRequestParent::nsISupports // DNSRequestParent::nsISupports
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -82,7 +70,7 @@ NS_IMPL_ISUPPORTS(DNSRequestParent, nsIDNSListener)
NS_IMETHODIMP NS_IMETHODIMP
DNSRequestParent::OnLookupComplete(nsICancelable* request, nsIDNSRecord* rec, DNSRequestParent::OnLookupComplete(nsICancelable* request, nsIDNSRecord* rec,
nsresult status) { nsresult status) {
if (mIPCClosed) { if (!CanSend()) {
// nothing to do: child probably crashed // nothing to do: child probably crashed
return NS_OK; return NS_OK;
} }
@ -107,7 +95,6 @@ DNSRequestParent::OnLookupComplete(nsICancelable* request, nsIDNSRecord* rec,
Unused << SendLookupCompleted(DNSRequestResponse(status)); Unused << SendLookupCompleted(DNSRequestResponse(status));
} }
mIPCClosed = true;
return NS_OK; return NS_OK;
} }
@ -115,7 +102,7 @@ NS_IMETHODIMP
DNSRequestParent::OnLookupByTypeComplete(nsICancelable* aRequest, DNSRequestParent::OnLookupByTypeComplete(nsICancelable* aRequest,
nsIDNSByTypeRecord* aRes, nsIDNSByTypeRecord* aRes,
nsresult aStatus) { nsresult aStatus) {
if (mIPCClosed) { if (!CanSend()) {
// nothing to do: child probably crashed // nothing to do: child probably crashed
return NS_OK; return NS_OK;
} }
@ -127,7 +114,6 @@ DNSRequestParent::OnLookupByTypeComplete(nsICancelable* aRequest,
} else { } else {
Unused << SendLookupCompleted(DNSRequestResponse(aStatus)); Unused << SendLookupCompleted(DNSRequestResponse(aStatus));
} }
mIPCClosed = true;
return NS_OK; return NS_OK;
} }

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

@ -30,16 +30,11 @@ class DNSRequestParent : public PDNSRequestParent, public nsIDNSListener {
const nsCString& hostName, const uint16_t& type, const nsCString& hostName, const uint16_t& type,
const OriginAttributes& originAttributes, const uint32_t& flags, const OriginAttributes& originAttributes, const uint32_t& flags,
const nsresult& reason); const nsresult& reason);
mozilla::ipc::IPCResult Recv__delete__() override;
protected:
virtual void ActorDestroy(ActorDestroyReason why) override;
private: private:
virtual ~DNSRequestParent() = default; virtual ~DNSRequestParent() = default;
uint32_t mFlags; uint32_t mFlags;
bool mIPCClosed; // true if IPDL channel has been closed (child crash)
}; };
} // namespace net } // namespace net

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

@ -17,7 +17,7 @@ using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
namespace mozilla { namespace mozilla {
namespace net { namespace net {
async protocol PDNSRequest async refcounted protocol PDNSRequest
{ {
manager PNecko or PSocketProcess; manager PNecko or PSocketProcess;

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

@ -254,21 +254,6 @@ bool NeckoChild::DeallocPUDPSocketChild(PUDPSocketChild* child) {
return true; return true;
} }
PDNSRequestChild* NeckoChild::AllocPDNSRequestChild(
const nsCString& aHost, const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags) {
// We don't allocate here: instead we always use IPDL constructor that takes
// an existing object
MOZ_ASSERT_UNREACHABLE("AllocPDNSRequestChild should not be called on child");
return nullptr;
}
bool NeckoChild::DeallocPDNSRequestChild(PDNSRequestChild* aChild) {
DNSRequestChild* p = static_cast<DNSRequestChild*>(aChild);
p->ReleaseIPDLReference();
return true;
}
PChannelDiverterChild* NeckoChild::AllocPChannelDiverterChild( PChannelDiverterChild* NeckoChild::AllocPChannelDiverterChild(
const ChannelDiverterArgs& channel) { const ChannelDiverterArgs& channel) {
return new ChannelDiverterChild(); return new ChannelDiverterChild();

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

@ -60,10 +60,6 @@ class NeckoChild : public PNeckoChild {
PUDPSocketChild* AllocPUDPSocketChild(nsIPrincipal* aPrincipal, PUDPSocketChild* AllocPUDPSocketChild(nsIPrincipal* aPrincipal,
const nsCString& aFilter); const nsCString& aFilter);
bool DeallocPUDPSocketChild(PUDPSocketChild*); bool DeallocPUDPSocketChild(PUDPSocketChild*);
PDNSRequestChild* AllocPDNSRequestChild(
const nsCString& aHost, const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags);
bool DeallocPDNSRequestChild(PDNSRequestChild*);
PSimpleChannelChild* AllocPSimpleChannelChild(const uint32_t& channelId); PSimpleChannelChild* AllocPSimpleChannelChild(const uint32_t& channelId);
bool DeallocPSimpleChannelChild(PSimpleChannelChild* child); bool DeallocPSimpleChannelChild(PSimpleChannelChild* child);
PChannelDiverterChild* AllocPChannelDiverterChild( PChannelDiverterChild* AllocPChannelDiverterChild(

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

@ -598,12 +598,11 @@ bool NeckoParent::DeallocPUDPSocketParent(PUDPSocketParent* actor) {
return true; return true;
} }
PDNSRequestParent* NeckoParent::AllocPDNSRequestParent( already_AddRefed<PDNSRequestParent> NeckoParent::AllocPDNSRequestParent(
const nsCString& aHost, const OriginAttributes& aOriginAttributes, const nsCString& aHost, const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags) { const uint32_t& aFlags) {
DNSRequestParent* p = new DNSRequestParent(); RefPtr<DNSRequestParent> actor = new DNSRequestParent();
p->AddRef(); return actor.forget();
return p;
} }
mozilla::ipc::IPCResult NeckoParent::RecvPDNSRequestConstructor( mozilla::ipc::IPCResult NeckoParent::RecvPDNSRequestConstructor(
@ -614,12 +613,6 @@ mozilla::ipc::IPCResult NeckoParent::RecvPDNSRequestConstructor(
return IPC_OK(); return IPC_OK();
} }
bool NeckoParent::DeallocPDNSRequestParent(PDNSRequestParent* aParent) {
DNSRequestParent* p = static_cast<DNSRequestParent*>(aParent);
p->Release();
return true;
}
mozilla::ipc::IPCResult NeckoParent::RecvSpeculativeConnect( mozilla::ipc::IPCResult NeckoParent::RecvSpeculativeConnect(
const URIParams& aURI, nsIPrincipal* aPrincipal, const bool& aAnonymous) { const URIParams& aURI, nsIPrincipal* aPrincipal, const bool& aAnonymous) {
nsCOMPtr<nsISpeculativeConnect> speculator(gIOService); nsCOMPtr<nsISpeculativeConnect> speculator(gIOService);

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

@ -150,14 +150,13 @@ class NeckoParent : public PNeckoParent {
PUDPSocketParent*, nsIPrincipal* aPrincipal, PUDPSocketParent*, nsIPrincipal* aPrincipal,
const nsCString& aFilter) override; const nsCString& aFilter) override;
bool DeallocPUDPSocketParent(PUDPSocketParent*); bool DeallocPUDPSocketParent(PUDPSocketParent*);
PDNSRequestParent* AllocPDNSRequestParent( already_AddRefed<PDNSRequestParent> AllocPDNSRequestParent(
const nsCString& aHost, const OriginAttributes& aOriginAttributes, const nsCString& aHost, const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags); const uint32_t& aFlags);
virtual mozilla::ipc::IPCResult RecvPDNSRequestConstructor( virtual mozilla::ipc::IPCResult RecvPDNSRequestConstructor(
PDNSRequestParent* actor, const nsCString& hostName, PDNSRequestParent* actor, const nsCString& hostName,
const OriginAttributes& aOriginAttributes, const OriginAttributes& aOriginAttributes,
const uint32_t& flags) override; const uint32_t& flags) override;
bool DeallocPDNSRequestParent(PDNSRequestParent*);
mozilla::ipc::IPCResult RecvSpeculativeConnect(const URIParams& aURI, mozilla::ipc::IPCResult RecvSpeculativeConnect(const URIParams& aURI,
nsIPrincipal* aPrincipal, nsIPrincipal* aPrincipal,
const bool& aAnonymous); const bool& aAnonymous);

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

@ -212,20 +212,5 @@ bool SocketProcessChild::DeallocPWebrtcTCPSocketChild(
return true; return true;
} }
PDNSRequestChild* SocketProcessChild::AllocPDNSRequestChild(
const nsCString& aHost, const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags) {
// We don't allocate here: instead we always use IPDL constructor that takes
// an existing object
MOZ_ASSERT_UNREACHABLE("AllocPDNSRequestChild should not be called on child");
return nullptr;
}
bool SocketProcessChild::DeallocPDNSRequestChild(PDNSRequestChild* aChild) {
DNSRequestChild* p = static_cast<DNSRequestChild*>(aChild);
p->ReleaseIPDLReference();
return true;
}
} // namespace net } // namespace net
} // namespace mozilla } // namespace mozilla

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

@ -47,10 +47,6 @@ class SocketProcessChild final : public PSocketProcessChild {
PWebrtcTCPSocketChild* AllocPWebrtcTCPSocketChild(const Maybe<TabId>& tabId); PWebrtcTCPSocketChild* AllocPWebrtcTCPSocketChild(const Maybe<TabId>& tabId);
bool DeallocPWebrtcTCPSocketChild(PWebrtcTCPSocketChild* aActor); bool DeallocPWebrtcTCPSocketChild(PWebrtcTCPSocketChild* aActor);
PDNSRequestChild* AllocPDNSRequestChild(
const nsCString& aHost, const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags);
bool DeallocPDNSRequestChild(PDNSRequestChild*);
void CleanUp(); void CleanUp();
void DestroySocketProcessBridgeParent(ProcessId aId); void DestroySocketProcessBridgeParent(ProcessId aId);

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

@ -141,12 +141,11 @@ bool SocketProcessParent::DeallocPWebrtcTCPSocketParent(
return true; return true;
} }
PDNSRequestParent* SocketProcessParent::AllocPDNSRequestParent( already_AddRefed<PDNSRequestParent> SocketProcessParent::AllocPDNSRequestParent(
const nsCString& aHost, const OriginAttributes& aOriginAttributes, const nsCString& aHost, const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags) { const uint32_t& aFlags) {
DNSRequestParent* p = new DNSRequestParent(); RefPtr<DNSRequestParent> actor = new DNSRequestParent();
p->AddRef(); return actor.forget();
return p;
} }
mozilla::ipc::IPCResult SocketProcessParent::RecvPDNSRequestConstructor( mozilla::ipc::IPCResult SocketProcessParent::RecvPDNSRequestConstructor(
@ -157,12 +156,6 @@ mozilla::ipc::IPCResult SocketProcessParent::RecvPDNSRequestConstructor(
return IPC_OK(); return IPC_OK();
} }
bool SocketProcessParent::DeallocPDNSRequestParent(PDNSRequestParent* aParent) {
DNSRequestParent* p = static_cast<DNSRequestParent*>(aParent);
p->Release();
return true;
}
// To ensure that IPDL is finished before SocketParent gets deleted. // To ensure that IPDL is finished before SocketParent gets deleted.
class DeferredDeleteSocketProcessParent : public Runnable { class DeferredDeleteSocketProcessParent : public Runnable {
public: public:

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

@ -56,14 +56,13 @@ class SocketProcessParent final
PWebrtcTCPSocketParent* AllocPWebrtcTCPSocketParent( PWebrtcTCPSocketParent* AllocPWebrtcTCPSocketParent(
const Maybe<TabId>& aTabId); const Maybe<TabId>& aTabId);
bool DeallocPWebrtcTCPSocketParent(PWebrtcTCPSocketParent* aActor); bool DeallocPWebrtcTCPSocketParent(PWebrtcTCPSocketParent* aActor);
PDNSRequestParent* AllocPDNSRequestParent( already_AddRefed<PDNSRequestParent> AllocPDNSRequestParent(
const nsCString& aHost, const OriginAttributes& aOriginAttributes, const nsCString& aHost, const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags); const uint32_t& aFlags);
virtual mozilla::ipc::IPCResult RecvPDNSRequestConstructor( virtual mozilla::ipc::IPCResult RecvPDNSRequestConstructor(
PDNSRequestParent* actor, const nsCString& hostName, PDNSRequestParent* actor, const nsCString& hostName,
const OriginAttributes& aOriginAttributes, const OriginAttributes& aOriginAttributes,
const uint32_t& flags) override; const uint32_t& flags) override;
bool DeallocPDNSRequestParent(PDNSRequestParent*);
void ActorDestroy(ActorDestroyReason aWhy) override; void ActorDestroy(ActorDestroyReason aWhy) override;
bool SendRequestMemoryReport(const uint32_t& aGeneration, bool SendRequestMemoryReport(const uint32_t& aGeneration,