From c6adba047faf9b1cc61ea02381ea80edfd519659 Mon Sep 17 00:00:00 2001 From: "josh@joshmatthews.net" Date: Sat, 24 Apr 2010 00:19:33 +1000 Subject: [PATCH] Bug 536316 - e10s HTTP: channel refcounting. r=jduell --- netwerk/ipc/NeckoChild.cpp | 4 ++-- .../protocol/http/src/HttpChannelChild.cpp | 23 ++++++++++++++++--- netwerk/protocol/http/src/HttpChannelChild.h | 1 + .../protocol/http/src/HttpChannelParent.cpp | 5 ++-- netwerk/protocol/http/src/HttpChannelParent.h | 2 ++ 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/netwerk/ipc/NeckoChild.cpp b/netwerk/ipc/NeckoChild.cpp index 926a4e4424e..07007207442 100644 --- a/netwerk/ipc/NeckoChild.cpp +++ b/netwerk/ipc/NeckoChild.cpp @@ -99,8 +99,8 @@ NeckoChild::DeallocPHttpChannel(PHttpChannelChild* channel) { NS_ABORT_IF_FALSE(IsNeckoChild(), "DeallocPHttpChannel called by non-child!"); - HttpChannelChild *p = static_cast(channel); - p->Release(); + // Delete channel (HttpChannelChild's refcnt must already hit 0 to get here) + delete channel; return true; } diff --git a/netwerk/protocol/http/src/HttpChannelChild.cpp b/netwerk/protocol/http/src/HttpChannelChild.cpp index 34e9f2025ff..1bec68d47d6 100644 --- a/netwerk/protocol/http/src/HttpChannelChild.cpp +++ b/netwerk/protocol/http/src/HttpChannelChild.cpp @@ -67,8 +67,20 @@ HttpChannelChild::~HttpChannelChild() // HttpChannelChild::nsISupports //----------------------------------------------------------------------------- -NS_IMPL_ADDREF_INHERITED(HttpChannelChild, HttpBaseChannel) -NS_IMPL_RELEASE_INHERITED(HttpChannelChild, HttpBaseChannel) +// Override nsHashPropertyBag's AddRef: we don't need thread-safe refcnt +NS_IMPL_ADDREF(HttpChannelChild) +NS_IMPL_RELEASE_WITH_DESTROY(HttpChannelChild, RefcountHitZero()) + +void +HttpChannelChild::RefcountHitZero() +{ + if (mWasOpened) { + // NeckoChild::DeallocPHttpChannel will delete this + PHttpChannelChild::Send__delete__(this); + } else { + delete this; // we never opened IPDL channel + } +} NS_INTERFACE_MAP_BEGIN(HttpChannelChild) NS_INTERFACE_MAP_ENTRY(nsIRequest) @@ -158,6 +170,10 @@ HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode) nsresult rv = mListener->OnStopRequest(this, mListenerContext, statusCode); mListener = 0; mListenerContext = 0; + + // Corresponding AddRef in AsyncOpen(). + this->Release(); + if (!NS_SUCCEEDED(rv)) { // TODO: Cancel request: see notes in OnStartRequest return false; @@ -218,7 +234,8 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext) if (NS_FAILED(rv)) return rv; - // This corresponds to Release() in DeallocPHttpChannel + // The socket transport layer in the chrome process now has a logical ref to + // us, until either OnStopRequest or OnRedirect is called. this->AddRef(); // TODO: Combine constructor and AsyncOpen to save one IPC msg diff --git a/netwerk/protocol/http/src/HttpChannelChild.h b/netwerk/protocol/http/src/HttpChannelChild.h index 3321ed55d12..8a5c114b838 100644 --- a/netwerk/protocol/http/src/HttpChannelChild.h +++ b/netwerk/protocol/http/src/HttpChannelChild.h @@ -120,6 +120,7 @@ public: NS_IMETHOD SetPriority(PRInt32 value); protected: + void RefcountHitZero(); bool RecvOnStartRequest(const nsHttpResponseHead& responseHead); bool RecvOnDataAvailable(const nsCString& data, const PRUint32& offset, diff --git a/netwerk/protocol/http/src/HttpChannelParent.cpp b/netwerk/protocol/http/src/HttpChannelParent.cpp index 3f42c556709..fbc4ba8d5c8 100644 --- a/netwerk/protocol/http/src/HttpChannelParent.cpp +++ b/netwerk/protocol/http/src/HttpChannelParent.cpp @@ -103,12 +103,11 @@ HttpChannelParent::RecvAsyncOpen(const IPC::URI& aURI, if (NS_FAILED(rv)) return false; // TODO: send fail msg to child, return true - nsCOMPtr chan; - rv = NS_NewChannel(getter_AddRefs(chan), uri, ios, nsnull, nsnull, loadFlags); + rv = NS_NewChannel(getter_AddRefs(mChannel), uri, ios, nsnull, nsnull, loadFlags); if (NS_FAILED(rv)) return false; // TODO: send fail msg to child, return true - nsHttpChannel *httpChan = static_cast(chan.get()); + nsHttpChannel *httpChan = static_cast(mChannel.get()); if (originalUri) httpChan->SetOriginalURI(originalUri); diff --git a/netwerk/protocol/http/src/HttpChannelParent.h b/netwerk/protocol/http/src/HttpChannelParent.h index 94034afbdaa..212ff9d70d7 100644 --- a/netwerk/protocol/http/src/HttpChannelParent.h +++ b/netwerk/protocol/http/src/HttpChannelParent.h @@ -78,6 +78,8 @@ protected: const PRBool& forceAllowThirdPartyCookie); virtual bool RecvSetPriority(const PRUint16& priority); + + nsCOMPtr mChannel; }; } // namespace net