Bug 399096 - nsDOMCacheUpdateService leaks. r=dcamp, sr=biesi, a=blocker
authorjwalden@mit.edu
Thu, 08 Nov 2007 21:12:59 -0800
changeset 7705 e05001545f94b7ebb1223110d7a4e347e529f6b0
parent 7704 1ad725d9a9ddab3f17a5629646af69fdfc13a24e
child 7706 9db3320c43db088ecf9a0d062afc6ffae19382e9
push idunknown
push userunknown
push dateunknown
reviewersdcamp, biesi, blocker
bugs399096
milestone1.9b2pre
Bug 399096 - nsDOMCacheUpdateService leaks. r=dcamp, sr=biesi, a=blocker
uriloader/prefetch/nsOfflineCacheUpdate.cpp
uriloader/prefetch/nsOfflineCacheUpdate.h
--- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp
@@ -414,19 +414,20 @@ nsresult
 nsOfflineCacheUpdate::Init(PRBool aPartialUpdate,
                            const nsACString &aUpdateDomain,
                            const nsACString &aOwnerURI,
                            nsIURI *aReferrerURI)
 {
     nsresult rv;
 
     // Make sure the service has been initialized
-    if (!nsOfflineCacheUpdateService::GetInstance()) {
+    nsOfflineCacheUpdateService* service =
+        nsOfflineCacheUpdateService::EnsureService();
+    if (!service)
         return NS_ERROR_FAILURE;
-    }
 
     LOG(("nsOfflineCacheUpdate::Init [%p]", this));
 
     mPartialUpdate = aPartialUpdate;
     mUpdateDomain = aUpdateDomain;
     mOwnerURI = aOwnerURI;
     mReferrerURI = aReferrerURI;
 
@@ -644,18 +645,18 @@ nsOfflineCacheUpdate::NotifyCompleted(ns
 
 nsresult
 nsOfflineCacheUpdate::Finish()
 {
     LOG(("nsOfflineCacheUpdate::Finish [%p]", this));
 
     mState = STATE_FINISHED;
 
-    nsOfflineCacheUpdateService *service =
-        nsOfflineCacheUpdateService::GetInstance();
+    nsOfflineCacheUpdateService* service =
+        nsOfflineCacheUpdateService::EnsureService();
 
     if (!mPartialUpdate) {
         if (mSucceeded) {
             nsresult rv = mMainCacheSession->MergeTemporaryClientID(mClientID);
             if (NS_FAILED(rv))
                 mSucceeded = PR_FALSE;
         }
 
@@ -817,33 +818,33 @@ nsOfflineCacheUpdate::RemoveObserver(nsI
 }
 
 
 NS_IMETHODIMP
 nsOfflineCacheUpdate::Schedule()
 {
     LOG(("nsOfflineCacheUpdate::Schedule [%p]", this));
 
-    nsOfflineCacheUpdateService *service =
-        nsOfflineCacheUpdateService::GetInstance();
+    nsOfflineCacheUpdateService* service =
+        nsOfflineCacheUpdateService::EnsureService();
 
     if (!service) {
         return NS_ERROR_FAILURE;
     }
 
     return service->Schedule(this);
 }
 
 NS_IMETHODIMP
 nsOfflineCacheUpdate::ScheduleOnDocumentStop(nsIDOMDocument *aDocument)
 {
     LOG(("nsOfflineCacheUpdate::ScheduleOnDocumentStop [%p]", this));
 
-    nsOfflineCacheUpdateService *service =
-        nsOfflineCacheUpdateService::GetInstance();
+    nsOfflineCacheUpdateService* service =
+        nsOfflineCacheUpdateService::EnsureService();
 
     if (!service) {
         return NS_ERROR_FAILURE;
     }
 
     return service->ScheduleOnDocumentStop(this, aDocument);
 }
 
@@ -925,16 +926,28 @@ nsOfflineCacheUpdateService::GetInstance
         return gOfflineCacheUpdateService;
     }
 
     NS_ADDREF(gOfflineCacheUpdateService);
 
     return gOfflineCacheUpdateService;
 }
 
+nsOfflineCacheUpdateService *
+nsOfflineCacheUpdateService::EnsureService()
+{
+    if (!gOfflineCacheUpdateService) {
+        // Make the service manager hold a long-lived reference to the service
+        nsCOMPtr<nsIOfflineCacheUpdateService> service =
+            do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID);
+    }
+
+    return gOfflineCacheUpdateService;
+}
+
 nsresult
 nsOfflineCacheUpdateService::Schedule(nsOfflineCacheUpdate *aUpdate)
 {
     LOG(("nsOfflineCacheUpdateService::Schedule [%p, update=%p]",
          this, aUpdate));
 
     nsresult rv;
     nsCOMPtr<nsIObserverService> observerService =
--- a/uriloader/prefetch/nsOfflineCacheUpdate.h
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.h
@@ -172,18 +172,25 @@ public:
 
     nsresult Init();
 
     nsresult Schedule(nsOfflineCacheUpdate *aUpdate);
     nsresult ScheduleOnDocumentStop(nsOfflineCacheUpdate *aUpdate,
                                     nsIDOMDocument *aDocument);
     nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate);
 
+    /**
+     * Returns the singleton nsOfflineCacheUpdateService without an addref, or
+     * nsnull if the service couldn't be created.
+     */
+    static nsOfflineCacheUpdateService *EnsureService();
+
+    /** Addrefs and returns the singleton nsOfflineCacheUpdateService. */
     static nsOfflineCacheUpdateService *GetInstance();
-
+    
 private:
     nsresult ProcessNextUpdate();
 
     nsTArray<nsRefPtr<nsOfflineCacheUpdate> > mUpdates;
     nsRefPtrHashtable<nsVoidPtrHashKey, nsOfflineCacheUpdate> mDocUpdates;
 
     PRBool mDisabled;
     PRBool mUpdateRunning;