From bd916210f859f525168919025e19fd34f13ea1c9 Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Tue, 9 Apr 2013 13:38:48 -0400 Subject: [PATCH] bug 857906 progress indicator spinning on multipart motion jpeg r=duell sr=bz --HG-- extra : rebase_source : 6b3beea6f6bb91e21c37e6dd01e5c6445317f994 --- image/src/imgLoader.cpp | 6 ++- netwerk/base/public/moz.build | 1 + netwerk/base/public/nsILoadGroupChild.idl | 40 ++++++++++++++++++ netwerk/base/src/nsLoadGroup.cpp | 50 +++++++++++++++++++++++ netwerk/base/src/nsLoadGroup.h | 7 ++++ netwerk/protocol/http/nsHttpChannel.cpp | 28 ++++++------- 6 files changed, 115 insertions(+), 17 deletions(-) create mode 100644 netwerk/base/public/nsILoadGroupChild.idl diff --git a/image/src/imgLoader.cpp b/image/src/imgLoader.cpp index 05151dd5bfb4..01daef3ca05f 100644 --- a/image/src/imgLoader.cpp +++ b/image/src/imgLoader.cpp @@ -52,6 +52,7 @@ #include "nsIContentSecurityPolicy.h" #include "nsIChannelPolicy.h" #include "nsILoadContext.h" +#include "nsILoadGroupChild.h" #include "nsContentUtils.h" @@ -1710,8 +1711,9 @@ nsresult imgLoader::LoadImage(nsIURI *aURI, // together as a logical group. nsCOMPtr loadGroup = do_CreateInstance(NS_LOADGROUP_CONTRACTID); - if (loadGroup) - loadGroup->SetLoadGroup(aLoadGroup); + nsCOMPtr childLoadGroup = do_QueryInterface(loadGroup); + if (childLoadGroup) + childLoadGroup->SetParentLoadGroup(aLoadGroup); newChannel->SetLoadGroup(loadGroup); request->Init(aURI, aURI, loadGroup, newChannel, entry, aCX, diff --git a/netwerk/base/public/moz.build b/netwerk/base/public/moz.build index 6be336391738..590e6b0b943b 100644 --- a/netwerk/base/public/moz.build +++ b/netwerk/base/public/moz.build @@ -46,6 +46,7 @@ XPIDL_SOURCES += [ 'nsIInputStreamChannel.idl', 'nsIInputStreamPump.idl', 'nsILoadGroup.idl', + 'nsILoadGroupChild.idl', 'nsIMIMEInputStream.idl', 'nsIMultiPartChannel.idl', 'nsINSSErrorsService.idl', diff --git a/netwerk/base/public/nsILoadGroupChild.idl b/netwerk/base/public/nsILoadGroupChild.idl new file mode 100644 index 000000000000..60780492904a --- /dev/null +++ b/netwerk/base/public/nsILoadGroupChild.idl @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsILoadGroup.idl" + +/** + * nsILoadGroupChild provides a hierarchy of load groups so that the + * root load group can be used to conceptually tie a series of loading + * operations into a logical whole while still leaving them separate + * for the purposes of cancellation and status events. + */ + +[scriptable, uuid(02efe8e2-fbbc-4718-a299-b8a09c60bf6b)] +interface nsILoadGroupChild : nsISupports +{ + /** + * The parent of this load group. It is stored with + * a nsIWeakReference/nsWeakPtr so there is no requirement for the + * parentLoadGroup to out live the child, nor will the child keep a + * reference count on the parent. + */ + attribute nsILoadGroup parentLoadGroup; + + /** + * The nsILoadGroup associated with this nsILoadGroupChild + */ + readonly attribute nsILoadGroup childLoadGroup; + + /** + * The rootLoadGroup is the recursive parent of this + * load group where parent is defined as parentlLoadGroup if set + * or childLoadGroup.loadGroup as a backup. (i.e. parentLoadGroup takes + * precedence.) The nsILoadGroup child is the root if neither parent + * nor loadgroup attribute is specified. + */ + readonly attribute nsILoadGroup rootLoadGroup; +}; + diff --git a/netwerk/base/src/nsLoadGroup.cpp b/netwerk/base/src/nsLoadGroup.cpp index 33c4a4b63f90..af4f9992ae20 100644 --- a/netwerk/base/src/nsLoadGroup.cpp +++ b/netwerk/base/src/nsLoadGroup.cpp @@ -155,6 +155,7 @@ nsLoadGroup::~nsLoadGroup() NS_IMPL_AGGREGATED(nsLoadGroup) NS_INTERFACE_MAP_BEGIN_AGGREGATED(nsLoadGroup) NS_INTERFACE_MAP_ENTRY(nsILoadGroup) + NS_INTERFACE_MAP_ENTRY(nsILoadGroupChild) NS_INTERFACE_MAP_ENTRY(nsIRequest) NS_INTERFACE_MAP_ENTRY(nsISupportsPriority) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) @@ -762,6 +763,55 @@ nsLoadGroup::GetConnectionInfo(nsILoadGroupConnectionInfo **aCI) return NS_OK; } +//////////////////////////////////////////////////////////////////////////////// +// nsILoadGroupChild methods: + +/* attribute nsILoadGroup parentLoadGroup; */ +NS_IMETHODIMP +nsLoadGroup::GetParentLoadGroup(nsILoadGroup * *aParentLoadGroup) +{ + *aParentLoadGroup = nullptr; + nsCOMPtr parent = do_QueryReferent(mParentLoadGroup); + if (!parent) + return NS_OK; + parent.forget(aParentLoadGroup); + return NS_OK; +} + +NS_IMETHODIMP +nsLoadGroup::SetParentLoadGroup(nsILoadGroup *aParentLoadGroup) +{ + mParentLoadGroup = do_GetWeakReference(aParentLoadGroup); + return NS_OK; +} + +/* readonly attribute nsILoadGroup childLoadGroup; */ +NS_IMETHODIMP +nsLoadGroup::GetChildLoadGroup(nsILoadGroup * *aChildLoadGroup) +{ + NS_ADDREF(*aChildLoadGroup = this); + return NS_OK; +} + +/* readonly attribute nsILoadGroup rootLoadGroup; */ +NS_IMETHODIMP +nsLoadGroup::GetRootLoadGroup(nsILoadGroup * *aRootLoadGroup) +{ + // first recursively try the root load group of our parent + nsCOMPtr ancestor = do_QueryReferent(mParentLoadGroup); + if (ancestor) + return ancestor->GetRootLoadGroup(aRootLoadGroup); + + // next recursively try the root load group of our own load grop + ancestor = do_QueryInterface(mLoadGroup); + if (ancestor) + return ancestor->GetRootLoadGroup(aRootLoadGroup); + + // finally just return this + NS_ADDREF(*aRootLoadGroup = this); + return NS_OK; +} + //////////////////////////////////////////////////////////////////////////////// // nsISupportsPriority methods: diff --git a/netwerk/base/src/nsLoadGroup.h b/netwerk/base/src/nsLoadGroup.h index add984f2dc15..918d59a21a06 100644 --- a/netwerk/base/src/nsLoadGroup.h +++ b/netwerk/base/src/nsLoadGroup.h @@ -7,6 +7,7 @@ #define nsLoadGroup_h__ #include "nsILoadGroup.h" +#include "nsILoadGroupChild.h" #include "nsIChannel.h" #include "nsIStreamListener.h" #include "nsAgg.h" @@ -23,6 +24,7 @@ class nsILoadGroupConnectionInfo; class nsLoadGroup : public nsILoadGroup, + public nsILoadGroupChild, public nsISupportsPriority, public nsSupportsWeakReference { @@ -37,6 +39,10 @@ public: // nsILoadGroup methods: NS_DECL_NSILOADGROUP + //////////////////////////////////////////////////////////////////////////// + // nsILoadGroupChild methods: + NS_DECL_NSILOADGROUPCHILD + //////////////////////////////////////////////////////////////////////////// // nsISupportsPriority methods: NS_DECL_NSISUPPORTSPRIORITY @@ -70,6 +76,7 @@ protected: PLDHashTable mRequests; nsWeakPtr mObserver; + nsWeakPtr mParentLoadGroup; nsresult mStatus; int32_t mPriority; diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 3ab9996e7866..8ded7064e33f 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -15,6 +15,7 @@ #include "nsIStringBundle.h" #include "nsIStreamListenerTee.h" #include "nsISeekableStream.h" +#include "nsILoadGroupChild.h" #include "nsMimeTypes.h" #include "nsNetUtil.h" #include "prprf.h" @@ -684,23 +685,20 @@ nsHttpChannel::SetupTransactionLoadGroupInfo() // Find the loadgroup at the end of the chain in order // to make sure all channels derived from the load group // use the same connection scope. - nsCOMPtr rootLoadGroup = mLoadGroup; - while (rootLoadGroup) { - nsCOMPtr tmp; - rootLoadGroup->GetLoadGroup(getter_AddRefs(tmp)); - if (tmp) - rootLoadGroup.swap(tmp); - else - break; - } + nsCOMPtr childLoadGroup = do_QueryInterface(mLoadGroup); + if (!childLoadGroup) + return; + + nsCOMPtr rootLoadGroup; + childLoadGroup->GetRootLoadGroup(getter_AddRefs(rootLoadGroup)); + if (!rootLoadGroup) + return; // Set the load group connection scope on the transaction - if (rootLoadGroup) { - nsCOMPtr ci; - rootLoadGroup->GetConnectionInfo(getter_AddRefs(ci)); - if (ci) - mTransaction->SetLoadGroupConnectionInfo(ci); - } + nsCOMPtr ci; + rootLoadGroup->GetConnectionInfo(getter_AddRefs(ci)); + if (ci) + mTransaction->SetLoadGroupConnectionInfo(ci); } nsresult