From a4e3c8a289b40169055fc8e9f1c8d60b8b426baa Mon Sep 17 00:00:00 2001 From: "bsmedberg%covad.net" Date: Fri, 25 Feb 2005 21:11:46 +0000 Subject: [PATCH] Bug 283488 - Reentrant getservice for chromeregistry if a contents.rdf cannot be parsed. r=shaver (This reintroduces code that I stripped in the chrome registry rework because I thought it was silly. Joel was right.) --- chrome/src/nsChromeProtocolHandler.cpp | 11 ++++++++--- chrome/src/nsChromeRegistry.cpp | 14 ++++++++++---- chrome/src/nsChromeRegistry.h | 7 ++++++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/chrome/src/nsChromeProtocolHandler.cpp b/chrome/src/nsChromeProtocolHandler.cpp index 98bd3a7a0b9..bdae68502f0 100644 --- a/chrome/src/nsChromeProtocolHandler.cpp +++ b/chrome/src/nsChromeProtocolHandler.cpp @@ -556,11 +556,16 @@ nsChromeProtocolHandler::NewChannel(nsIURI* aURI, //aURI->GetSpec(getter_Copies(oldSpec)); //printf("*************************** %s\n", (const char*)oldSpec); - nsCOMPtr reg (do_GetService(NS_CHROMEREGISTRY_CONTRACTID)); - NS_ENSURE_TRUE(reg, NS_ERROR_FAILURE); + if (!nsChromeRegistry::gChromeRegistry) { + // We don't actually want this ref, we just want the service to + // initialize if it hasn't already. + nsCOMPtr reg (do_GetService(NS_CHROMEREGISTRY_CONTRACTID)); + } + + NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry, NS_ERROR_FAILURE); nsCOMPtr resolvedURI; - rv = reg->ConvertChromeURL(aURI, getter_AddRefs(resolvedURI)); + rv = nsChromeRegistry::gChromeRegistry->ConvertChromeURL(aURI, getter_AddRefs(resolvedURI)); if (NS_FAILED(rv)) { #ifdef DEBUG nsCAutoString spec; diff --git a/chrome/src/nsChromeRegistry.cpp b/chrome/src/nsChromeRegistry.cpp index 573fa2497de..1323c08d280 100644 --- a/chrome/src/nsChromeRegistry.cpp +++ b/chrome/src/nsChromeRegistry.cpp @@ -115,7 +115,7 @@ static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID); static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID); -nsChromeRegistry* gChromeRegistry; +nsChromeRegistry* nsChromeRegistry::gChromeRegistry; #define CHROME_URI "http://www.mozilla.org/rdf/chrome#" @@ -399,11 +399,15 @@ nsChromeRegistry::Init() !mStyleHash.Init()) return NS_ERROR_FAILURE; - gChromeRegistry = this; - mSelectedLocale = NS_LITERAL_CSTRING("en-US"); mSelectedSkin = NS_LITERAL_CSTRING("classic/1.0"); + // This initialization process is fairly complicated and may cause reentrant + // getservice calls to resolve chrome URIs (especially locale files). We + // don't want that, so we inform the protocol handler about our existence + // before we are actually fully initialized. + gChromeRegistry = this; + nsCOMPtr prefs (do_GetService(NS_PREFSERVICE_CONTRACTID)); if (!prefs) { NS_WARNING("Could not get pref service!"); @@ -449,6 +453,8 @@ nsChromeRegistry::Init() CheckForNewChrome(); + mInitialized = PR_TRUE; + return NS_OK; } @@ -586,7 +592,7 @@ nsChromeRegistry::ConvertChromeURL(nsIURI* aChromeURI, nsIURI* *aResult) PL_DHASH_LOOKUP)); if (PL_DHASH_ENTRY_IS_FREE(entry)) - return NS_ERROR_FAILURE; + return mInitialized ? NS_ERROR_FAILURE : NS_ERROR_NOT_INITIALIZED; if (entry->flags & PackageEntry::PLATFORM_PACKAGE) { #if defined(XP_WIN) || defined(XP_OS2) diff --git a/chrome/src/nsChromeRegistry.h b/chrome/src/nsChromeRegistry.h index 10bb4f4699a..32772b36257 100644 --- a/chrome/src/nsChromeRegistry.h +++ b/chrome/src/nsChromeRegistry.h @@ -83,10 +83,13 @@ public: NS_DECL_NSIOBSERVER // nsChromeRegistry methods: - nsChromeRegistry() { } + nsChromeRegistry() : mInitialized(PR_FALSE) { } ~nsChromeRegistry(); nsresult Init(); + + static nsChromeRegistry* gChromeRegistry; + static nsresult Canonify(nsIURL* aChromeURL); protected: @@ -217,6 +220,8 @@ public: }; private: + PRBool mInitialized; + // Hash of package names ("global") to PackageEntry objects PLDHashTable mPackagesHash;