summaryrefslogtreecommitdiffstats
path: root/netwerk/cache/nsCacheService.h
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/cache/nsCacheService.h')
-rw-r--r--netwerk/cache/nsCacheService.h392
1 files changed, 392 insertions, 0 deletions
diff --git a/netwerk/cache/nsCacheService.h b/netwerk/cache/nsCacheService.h
new file mode 100644
index 000000000..1751d4875
--- /dev/null
+++ b/netwerk/cache/nsCacheService.h
@@ -0,0 +1,392 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* 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/. */
+
+#ifndef _nsCacheService_h_
+#define _nsCacheService_h_
+
+#include "nsICacheService.h"
+#include "nsCacheSession.h"
+#include "nsCacheDevice.h"
+#include "nsCacheEntry.h"
+#include "nsThreadUtils.h"
+#include "nsICacheListener.h"
+#include "nsIMemoryReporter.h"
+
+#include "prthread.h"
+#include "nsIObserver.h"
+#include "nsString.h"
+#include "nsTArray.h"
+#include "nsRefPtrHashtable.h"
+#include "mozilla/CondVar.h"
+#include "mozilla/Mutex.h"
+#include "mozilla/Telemetry.h"
+
+class nsCacheRequest;
+class nsCacheProfilePrefObserver;
+class nsDiskCacheDevice;
+class nsMemoryCacheDevice;
+class nsOfflineCacheDevice;
+class nsCacheServiceAutoLock;
+class nsITimer;
+class mozIStorageService;
+
+
+/******************************************************************************
+ * nsNotifyDoomListener
+ *****************************************************************************/
+
+class nsNotifyDoomListener : public mozilla::Runnable {
+public:
+ nsNotifyDoomListener(nsICacheListener *listener,
+ nsresult status)
+ : mListener(listener) // transfers reference
+ , mStatus(status)
+ {}
+
+ NS_IMETHOD Run() override
+ {
+ mListener->OnCacheEntryDoomed(mStatus);
+ NS_RELEASE(mListener);
+ return NS_OK;
+ }
+
+private:
+ nsICacheListener *mListener;
+ nsresult mStatus;
+};
+
+/******************************************************************************
+ * nsCacheService
+ ******************************************************************************/
+
+class nsCacheService final : public nsICacheServiceInternal,
+ public nsIMemoryReporter
+{
+ virtual ~nsCacheService();
+
+public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSICACHESERVICE
+ NS_DECL_NSICACHESERVICEINTERNAL
+ NS_DECL_NSIMEMORYREPORTER
+
+ nsCacheService();
+
+ // Define a Create method to be used with a factory:
+ static nsresult
+ Create(nsISupports* outer, const nsIID& iid, void* *result);
+
+
+ /**
+ * Methods called by nsCacheSession
+ */
+ static nsresult OpenCacheEntry(nsCacheSession * session,
+ const nsACString & key,
+ nsCacheAccessMode accessRequested,
+ bool blockingMode,
+ nsICacheListener * listener,
+ nsICacheEntryDescriptor ** result);
+
+ static nsresult EvictEntriesForSession(nsCacheSession * session);
+
+ static nsresult IsStorageEnabledForPolicy(nsCacheStoragePolicy storagePolicy,
+ bool * result);
+
+ static nsresult DoomEntry(nsCacheSession *session,
+ const nsACString &key,
+ nsICacheListener *listener);
+
+ /**
+ * Methods called by nsCacheEntryDescriptor
+ */
+
+ static void CloseDescriptor(nsCacheEntryDescriptor * descriptor);
+
+ static nsresult GetFileForEntry(nsCacheEntry * entry,
+ nsIFile ** result);
+
+ static nsresult OpenInputStreamForEntry(nsCacheEntry * entry,
+ nsCacheAccessMode mode,
+ uint32_t offset,
+ nsIInputStream ** result);
+
+ static nsresult OpenOutputStreamForEntry(nsCacheEntry * entry,
+ nsCacheAccessMode mode,
+ uint32_t offset,
+ nsIOutputStream ** result);
+
+ static nsresult OnDataSizeChange(nsCacheEntry * entry, int32_t deltaSize);
+
+ static nsresult SetCacheElement(nsCacheEntry * entry, nsISupports * element);
+
+ static nsresult ValidateEntry(nsCacheEntry * entry);
+
+ static int32_t CacheCompressionLevel();
+
+ static bool GetClearingEntries();
+
+ static void GetCacheBaseDirectoty(nsIFile ** result);
+ static void GetDiskCacheDirectory(nsIFile ** result);
+ static void GetAppCacheDirectory(nsIFile ** result);
+
+ /**
+ * Methods called by any cache classes
+ */
+
+ static
+ nsCacheService * GlobalInstance() { return gService; }
+
+ static nsresult DoomEntry(nsCacheEntry * entry);
+
+ static bool IsStorageEnabledForPolicy_Locked(nsCacheStoragePolicy policy);
+
+ /**
+ * Called by disk cache to notify us to use the new max smart size
+ */
+ static void MarkStartingFresh();
+
+ /**
+ * Methods called by nsApplicationCacheService
+ */
+
+ nsresult GetOfflineDevice(nsOfflineCacheDevice ** aDevice);
+
+ /**
+ * Creates an offline cache device that works over a specific profile directory.
+ * A tool to preload offline cache for profiles different from the current
+ * application's profile directory.
+ */
+ nsresult GetCustomOfflineDevice(nsIFile *aProfileDir,
+ int32_t aQuota,
+ nsOfflineCacheDevice **aDevice);
+
+ // This method may be called to release an object while the cache service
+ // lock is being held. If a non-null target is specified and the target
+ // does not correspond to the current thread, then the release will be
+ // proxied to the specified target. Otherwise, the object will be added to
+ // the list of objects to be released when the cache service is unlocked.
+ static void ReleaseObject_Locked(nsISupports * object,
+ nsIEventTarget * target = nullptr);
+
+ static nsresult DispatchToCacheIOThread(nsIRunnable* event);
+
+ // Calling this method will block the calling thread until all pending
+ // events on the cache-io thread has finished. The calling thread must
+ // hold the cache-lock
+ static nsresult SyncWithCacheIOThread();
+
+
+ /**
+ * Methods called by nsCacheProfilePrefObserver
+ */
+ static void OnProfileShutdown();
+ static void OnProfileChanged();
+
+ static void SetDiskCacheEnabled(bool enabled);
+ // Sets the disk cache capacity (in kilobytes)
+ static void SetDiskCacheCapacity(int32_t capacity);
+ // Set max size for a disk-cache entry (in KB). -1 disables limit up to
+ // 1/8th of disk cache size
+ static void SetDiskCacheMaxEntrySize(int32_t maxSize);
+ // Set max size for a memory-cache entry (in kilobytes). -1 disables
+ // limit up to 90% of memory cache size
+ static void SetMemoryCacheMaxEntrySize(int32_t maxSize);
+
+ static void SetOfflineCacheEnabled(bool enabled);
+ // Sets the offline cache capacity (in kilobytes)
+ static void SetOfflineCacheCapacity(int32_t capacity);
+
+ static void SetMemoryCache();
+
+ static void SetCacheCompressionLevel(int32_t level);
+
+ // Starts smart cache size computation if disk device is available
+ static nsresult SetDiskSmartSize();
+
+ static void MoveOrRemoveDiskCache(nsIFile *aOldCacheDir,
+ nsIFile *aNewCacheDir,
+ const char *aCacheSubdir);
+
+ nsresult Init();
+ void Shutdown();
+
+ static bool IsInitialized()
+ {
+ if (!gService) {
+ return false;
+ }
+ return gService->mInitialized;
+ }
+
+ static void AssertOwnsLock()
+ { gService->mLock.AssertCurrentThreadOwns(); }
+
+ static void LeavePrivateBrowsing();
+ bool IsDoomListEmpty();
+
+ typedef bool (*DoomCheckFn)(nsCacheEntry* entry);
+
+ // Accessors to the disabled functionality
+ nsresult CreateSessionInternal(const char * clientID,
+ nsCacheStoragePolicy storagePolicy,
+ bool streamBased,
+ nsICacheSession **result);
+ nsresult VisitEntriesInternal(nsICacheVisitor *visitor);
+ nsresult EvictEntriesInternal(nsCacheStoragePolicy storagePolicy);
+
+private:
+ friend class nsCacheServiceAutoLock;
+ friend class nsOfflineCacheDevice;
+ friend class nsProcessRequestEvent;
+ friend class nsSetSmartSizeEvent;
+ friend class nsBlockOnCacheThreadEvent;
+ friend class nsSetDiskSmartSizeCallback;
+ friend class nsDoomEvent;
+ friend class nsDisableOldMaxSmartSizePrefEvent;
+ friend class nsDiskCacheMap;
+ friend class nsAsyncDoomEvent;
+ friend class nsCacheEntryDescriptor;
+
+ /**
+ * Internal Methods
+ */
+
+ static void Lock();
+ static void Lock(::mozilla::Telemetry::ID mainThreadLockerID);
+ static void Unlock();
+ void LockAcquired();
+ void LockReleased();
+
+ nsresult CreateDiskDevice();
+ nsresult CreateOfflineDevice();
+ nsresult CreateCustomOfflineDevice(nsIFile *aProfileDir,
+ int32_t aQuota,
+ nsOfflineCacheDevice **aDevice);
+ nsresult CreateMemoryDevice();
+
+ nsresult RemoveCustomOfflineDevice(nsOfflineCacheDevice *aDevice);
+
+ nsresult CreateRequest(nsCacheSession * session,
+ const nsACString & clientKey,
+ nsCacheAccessMode accessRequested,
+ bool blockingMode,
+ nsICacheListener * listener,
+ nsCacheRequest ** request);
+
+ nsresult DoomEntry_Internal(nsCacheEntry * entry,
+ bool doProcessPendingRequests);
+
+ nsresult EvictEntriesForClient(const char * clientID,
+ nsCacheStoragePolicy storagePolicy);
+
+ // Notifies request listener asynchronously on the request's thread, and
+ // releases the descriptor on the request's thread. If this method fails,
+ // the descriptor is not released.
+ nsresult NotifyListener(nsCacheRequest * request,
+ nsICacheEntryDescriptor * descriptor,
+ nsCacheAccessMode accessGranted,
+ nsresult error);
+
+ nsresult ActivateEntry(nsCacheRequest * request,
+ nsCacheEntry ** entry,
+ nsCacheEntry ** doomedEntry);
+
+ nsCacheDevice * EnsureEntryHasDevice(nsCacheEntry * entry);
+
+ nsCacheEntry * SearchCacheDevices(nsCString * key, nsCacheStoragePolicy policy, bool *collision);
+
+ void DeactivateEntry(nsCacheEntry * entry);
+
+ nsresult ProcessRequest(nsCacheRequest * request,
+ bool calledFromOpenCacheEntry,
+ nsICacheEntryDescriptor ** result);
+
+ nsresult ProcessPendingRequests(nsCacheEntry * entry);
+
+ void ClearDoomList(void);
+ void DoomActiveEntries(DoomCheckFn check);
+ void CloseAllStreams();
+ void FireClearNetworkCacheStoredAnywhereNotification();
+
+ void LogCacheStatistics();
+
+ nsresult SetDiskSmartSize_Locked();
+
+ /**
+ * Data Members
+ */
+
+ static nsCacheService * gService; // there can be only one...
+
+ nsCOMPtr<mozIStorageService> mStorageService;
+
+ nsCacheProfilePrefObserver * mObserver;
+
+ mozilla::Mutex mLock;
+ mozilla::CondVar mCondVar;
+ bool mNotified;
+
+ mozilla::Mutex mTimeStampLock;
+ mozilla::TimeStamp mLockAcquiredTimeStamp;
+
+ nsCOMPtr<nsIThread> mCacheIOThread;
+
+ nsTArray<nsISupports*> mDoomedObjects;
+ nsCOMPtr<nsITimer> mSmartSizeTimer;
+
+ bool mInitialized;
+ bool mClearingEntries;
+
+ bool mEnableMemoryDevice;
+ bool mEnableDiskDevice;
+ bool mEnableOfflineDevice;
+
+ nsMemoryCacheDevice * mMemoryDevice;
+ nsDiskCacheDevice * mDiskDevice;
+ nsOfflineCacheDevice * mOfflineDevice;
+
+ nsRefPtrHashtable<nsStringHashKey, nsOfflineCacheDevice> mCustomOfflineDevices;
+
+ nsCacheEntryHashTable mActiveEntries;
+ PRCList mDoomedEntries;
+
+ // stats
+
+ uint32_t mTotalEntries;
+ uint32_t mCacheHits;
+ uint32_t mCacheMisses;
+ uint32_t mMaxKeyLength;
+ uint32_t mMaxDataSize;
+ uint32_t mMaxMetaSize;
+
+ // Unexpected error totals
+ uint32_t mDeactivateFailures;
+ uint32_t mDeactivatedUnboundEntries;
+};
+
+/******************************************************************************
+ * nsCacheServiceAutoLock
+ ******************************************************************************/
+
+#define LOCK_TELEM(x) \
+ (::mozilla::Telemetry::CACHE_SERVICE_LOCK_WAIT_MAINTHREAD_##x)
+
+// Instantiate this class to acquire the cache service lock for a particular
+// execution scope.
+class nsCacheServiceAutoLock {
+public:
+ nsCacheServiceAutoLock() {
+ nsCacheService::Lock();
+ }
+ explicit nsCacheServiceAutoLock(mozilla::Telemetry::ID mainThreadLockerID) {
+ nsCacheService::Lock(mainThreadLockerID);
+ }
+ ~nsCacheServiceAutoLock() {
+ nsCacheService::Unlock();
+ }
+};
+
+#endif // _nsCacheService_h_