netwerk/cache2/CacheStorageService.h

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #ifndef CacheStorageService__h__
michael@0 6 #define CacheStorageService__h__
michael@0 7
michael@0 8 #include "nsICacheStorageService.h"
michael@0 9 #include "nsIMemoryReporter.h"
michael@0 10
michael@0 11 #include "nsITimer.h"
michael@0 12 #include "nsClassHashtable.h"
michael@0 13 #include "nsString.h"
michael@0 14 #include "nsThreadUtils.h"
michael@0 15 #include "nsProxyRelease.h"
michael@0 16 #include "mozilla/Mutex.h"
michael@0 17 #include "mozilla/Atomics.h"
michael@0 18 #include "nsTArray.h"
michael@0 19
michael@0 20 class nsIURI;
michael@0 21 class nsICacheEntryOpenCallback;
michael@0 22 class nsICacheEntryDoomCallback;
michael@0 23 class nsICacheStorageVisitor;
michael@0 24 class nsIRunnable;
michael@0 25 class nsIThread;
michael@0 26 class nsIEventTarget;
michael@0 27
michael@0 28 namespace mozilla {
michael@0 29 namespace net {
michael@0 30
michael@0 31 class CacheStorageService;
michael@0 32 class CacheStorage;
michael@0 33 class CacheEntry;
michael@0 34 class CacheEntryHandle;
michael@0 35 class CacheEntryTable;
michael@0 36
michael@0 37 class CacheMemoryConsumer
michael@0 38 {
michael@0 39 private:
michael@0 40 friend class CacheStorageService;
michael@0 41 uint32_t mReportedMemoryConsumption : 30;
michael@0 42 uint32_t mFlags : 2;
michael@0 43
michael@0 44 private:
michael@0 45 CacheMemoryConsumer() MOZ_DELETE;
michael@0 46
michael@0 47 protected:
michael@0 48 enum {
michael@0 49 // No special treatment, reports always to the disk-entries pool.
michael@0 50 NORMAL = 0,
michael@0 51 // This consumer is belonging to a memory-only cache entry, used to decide
michael@0 52 // which of the two disk and memory pools count this consumption at.
michael@0 53 MEMORY_ONLY = 1 << 0,
michael@0 54 // Prevent reports of this consumer at all, used for disk data chunks since
michael@0 55 // we throw them away as soon as the entry is not used by any consumer and
michael@0 56 // don't want to make them wipe the whole pool out during their short life.
michael@0 57 DONT_REPORT = 1 << 1
michael@0 58 };
michael@0 59
michael@0 60 CacheMemoryConsumer(uint32_t aFlags);
michael@0 61 ~CacheMemoryConsumer() { DoMemoryReport(0); }
michael@0 62 void DoMemoryReport(uint32_t aCurrentSize);
michael@0 63 };
michael@0 64
michael@0 65 class CacheStorageService : public nsICacheStorageService
michael@0 66 , public nsIMemoryReporter
michael@0 67 , public nsITimerCallback
michael@0 68 {
michael@0 69 public:
michael@0 70 NS_DECL_THREADSAFE_ISUPPORTS
michael@0 71 NS_DECL_NSICACHESTORAGESERVICE
michael@0 72 NS_DECL_NSIMEMORYREPORTER
michael@0 73 NS_DECL_NSITIMERCALLBACK
michael@0 74
michael@0 75 CacheStorageService();
michael@0 76
michael@0 77 void Shutdown();
michael@0 78 void DropPrivateBrowsingEntries();
michael@0 79
michael@0 80 // Wipes out the new or the old cache directory completely.
michael@0 81 static void WipeCacheDirectory(uint32_t aVersion);
michael@0 82
michael@0 83 static CacheStorageService* Self() { return sSelf; }
michael@0 84 static nsISupports* SelfISupports() { return static_cast<nsICacheStorageService*>(Self()); }
michael@0 85 nsresult Dispatch(nsIRunnable* aEvent);
michael@0 86 static bool IsRunning() { return sSelf && !sSelf->mShutdown; }
michael@0 87 static bool IsOnManagementThread();
michael@0 88 already_AddRefed<nsIEventTarget> Thread() const;
michael@0 89 mozilla::Mutex& Lock() { return mLock; }
michael@0 90
michael@0 91 // Memory reporting
michael@0 92 size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
michael@0 93 size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
michael@0 94 MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
michael@0 95
michael@0 96 private:
michael@0 97 virtual ~CacheStorageService();
michael@0 98 void ShutdownBackground();
michael@0 99
michael@0 100 private:
michael@0 101 // The following methods may only be called on the management
michael@0 102 // thread.
michael@0 103 friend class CacheEntry;
michael@0 104
michael@0 105 /**
michael@0 106 * Registers the entry in management ordered arrays, a mechanism
michael@0 107 * helping with weighted purge of entries.
michael@0 108 * Management arrays keep hard reference to the entry. Entry is
michael@0 109 * responsible to remove it self or the service is responsible to
michael@0 110 * remove the entry when it's no longer needed.
michael@0 111 */
michael@0 112 void RegisterEntry(CacheEntry* aEntry);
michael@0 113
michael@0 114 /**
michael@0 115 * Deregisters the entry from management arrays. References are
michael@0 116 * then released.
michael@0 117 */
michael@0 118 void UnregisterEntry(CacheEntry* aEntry);
michael@0 119
michael@0 120 /**
michael@0 121 * Removes the entry from the related entry hash table, if still present.
michael@0 122 */
michael@0 123 bool RemoveEntry(CacheEntry* aEntry, bool aOnlyUnreferenced = false);
michael@0 124
michael@0 125 /**
michael@0 126 * Tells the storage service whether this entry is only to be stored in
michael@0 127 * memory.
michael@0 128 */
michael@0 129 void RecordMemoryOnlyEntry(CacheEntry* aEntry,
michael@0 130 bool aOnlyInMemory,
michael@0 131 bool aOverwrite);
michael@0 132
michael@0 133 private:
michael@0 134 // Following methods are thread safe to call.
michael@0 135 friend class CacheStorage;
michael@0 136
michael@0 137 /**
michael@0 138 * Get, or create when not existing and demanded, an entry for the storage
michael@0 139 * and uri+id extension.
michael@0 140 */
michael@0 141 nsresult AddStorageEntry(CacheStorage const* aStorage,
michael@0 142 nsIURI* aURI,
michael@0 143 const nsACString & aIdExtension,
michael@0 144 bool aCreateIfNotExist,
michael@0 145 bool aReplace,
michael@0 146 CacheEntryHandle** aResult);
michael@0 147
michael@0 148 /**
michael@0 149 * Removes the entry from the related entry hash table, if still present
michael@0 150 * and returns it.
michael@0 151 */
michael@0 152 nsresult DoomStorageEntry(CacheStorage const* aStorage,
michael@0 153 nsIURI* aURI,
michael@0 154 const nsACString & aIdExtension,
michael@0 155 nsICacheEntryDoomCallback* aCallback);
michael@0 156
michael@0 157 /**
michael@0 158 * Removes and returns entry table for the storage.
michael@0 159 */
michael@0 160 nsresult DoomStorageEntries(CacheStorage const* aStorage,
michael@0 161 nsICacheEntryDoomCallback* aCallback);
michael@0 162
michael@0 163 /**
michael@0 164 * Walk all entiries beloging to the storage.
michael@0 165 */
michael@0 166 nsresult WalkStorageEntries(CacheStorage const* aStorage,
michael@0 167 bool aVisitEntries,
michael@0 168 nsICacheStorageVisitor* aVisitor);
michael@0 169
michael@0 170 private:
michael@0 171 friend class CacheFileIOManager;
michael@0 172
michael@0 173 /**
michael@0 174 * CacheFileIOManager uses this method to notify CacheStorageService that
michael@0 175 * an active entry was removed. This method is called even if the entry
michael@0 176 * removal was originated by CacheStorageService.
michael@0 177 */
michael@0 178 void CacheFileDoomed(nsILoadContextInfo* aLoadContextInfo,
michael@0 179 const nsACString & aIdExtension,
michael@0 180 const nsACString & aURISpec);
michael@0 181
michael@0 182 private:
michael@0 183 friend class CacheMemoryConsumer;
michael@0 184
michael@0 185 /**
michael@0 186 * When memory consumption of this entry radically changes, this method
michael@0 187 * is called to reflect the size of allocated memory. This call may purge
michael@0 188 * unspecified number of entries from memory (but not from disk).
michael@0 189 */
michael@0 190 void OnMemoryConsumptionChange(CacheMemoryConsumer* aConsumer,
michael@0 191 uint32_t aCurrentMemoryConsumption);
michael@0 192
michael@0 193 /**
michael@0 194 * If not already pending, it schedules mPurgeTimer that fires after 1 second
michael@0 195 * and dispatches PurgeOverMemoryLimit().
michael@0 196 */
michael@0 197 void SchedulePurgeOverMemoryLimit();
michael@0 198
michael@0 199 /**
michael@0 200 * Called on the management thread, removes all expired and then least used
michael@0 201 * entries from the memory, first from the disk pool and then from the memory
michael@0 202 * pool.
michael@0 203 */
michael@0 204 void PurgeOverMemoryLimit();
michael@0 205
michael@0 206 private:
michael@0 207 nsresult DoomStorageEntries(nsCSubstring const& aContextKey,
michael@0 208 nsILoadContextInfo* aContext,
michael@0 209 bool aDiskStorage,
michael@0 210 nsICacheEntryDoomCallback* aCallback);
michael@0 211 nsresult AddStorageEntry(nsCSubstring const& aContextKey,
michael@0 212 nsIURI* aURI,
michael@0 213 const nsACString & aIdExtension,
michael@0 214 bool aWriteToDisk,
michael@0 215 bool aCreateIfNotExist,
michael@0 216 bool aReplace,
michael@0 217 CacheEntryHandle** aResult);
michael@0 218
michael@0 219 static CacheStorageService* sSelf;
michael@0 220
michael@0 221 mozilla::Mutex mLock;
michael@0 222
michael@0 223 bool mShutdown;
michael@0 224
michael@0 225 // Accessible only on the service thread
michael@0 226 class MemoryPool
michael@0 227 {
michael@0 228 public:
michael@0 229 enum EType
michael@0 230 {
michael@0 231 DISK,
michael@0 232 MEMORY,
michael@0 233 } mType;
michael@0 234
michael@0 235 MemoryPool(EType aType);
michael@0 236 ~MemoryPool();
michael@0 237
michael@0 238 nsTArray<nsRefPtr<CacheEntry> > mFrecencyArray;
michael@0 239 nsTArray<nsRefPtr<CacheEntry> > mExpirationArray;
michael@0 240 mozilla::Atomic<uint32_t> mMemorySize;
michael@0 241
michael@0 242 bool OnMemoryConsumptionChange(uint32_t aSavedMemorySize,
michael@0 243 uint32_t aCurrentMemoryConsumption);
michael@0 244 /**
michael@0 245 * Purges entries from memory based on the frecency ordered array.
michael@0 246 */
michael@0 247 void PurgeOverMemoryLimit();
michael@0 248 void PurgeExpired();
michael@0 249 void PurgeByFrecency(bool &aFrecencyNeedsSort, uint32_t aWhat);
michael@0 250 void PurgeAll(uint32_t aWhat);
michael@0 251
michael@0 252 private:
michael@0 253 uint32_t const Limit() const;
michael@0 254 MemoryPool() MOZ_DELETE;
michael@0 255 };
michael@0 256
michael@0 257 MemoryPool mDiskPool;
michael@0 258 MemoryPool mMemoryPool;
michael@0 259 MemoryPool& Pool(bool aUsingDisk)
michael@0 260 {
michael@0 261 return aUsingDisk ? mDiskPool : mMemoryPool;
michael@0 262 }
michael@0 263 MemoryPool const& Pool(bool aUsingDisk) const
michael@0 264 {
michael@0 265 return aUsingDisk ? mDiskPool : mMemoryPool;
michael@0 266 }
michael@0 267
michael@0 268 nsCOMPtr<nsITimer> mPurgeTimer;
michael@0 269
michael@0 270 class PurgeFromMemoryRunnable : public nsRunnable
michael@0 271 {
michael@0 272 public:
michael@0 273 PurgeFromMemoryRunnable(CacheStorageService* aService, uint32_t aWhat)
michael@0 274 : mService(aService), mWhat(aWhat) { }
michael@0 275
michael@0 276 private:
michael@0 277 virtual ~PurgeFromMemoryRunnable() { }
michael@0 278
michael@0 279 NS_IMETHOD Run()
michael@0 280 {
michael@0 281 // TODO not all flags apply to both pools
michael@0 282 mService->Pool(true).PurgeAll(mWhat);
michael@0 283 mService->Pool(false).PurgeAll(mWhat);
michael@0 284 return NS_OK;
michael@0 285 }
michael@0 286
michael@0 287 nsRefPtr<CacheStorageService> mService;
michael@0 288 uint32_t mWhat;
michael@0 289 };
michael@0 290 };
michael@0 291
michael@0 292 template<class T>
michael@0 293 void ProxyRelease(nsCOMPtr<T> &object, nsIThread* thread)
michael@0 294 {
michael@0 295 T* release;
michael@0 296 object.forget(&release);
michael@0 297
michael@0 298 NS_ProxyRelease(thread, release);
michael@0 299 }
michael@0 300
michael@0 301 template<class T>
michael@0 302 void ProxyReleaseMainThread(nsCOMPtr<T> &object)
michael@0 303 {
michael@0 304 nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
michael@0 305 ProxyRelease(object, mainThread);
michael@0 306 }
michael@0 307
michael@0 308 } // net
michael@0 309 } // mozilla
michael@0 310
michael@0 311 #define NS_CACHE_STORAGE_SERVICE_CID \
michael@0 312 { 0xea70b098, 0x5014, 0x4e21, \
michael@0 313 { 0xae, 0xe1, 0x75, 0xe6, 0xb2, 0xc4, 0xb8, 0xe0 } } \
michael@0 314
michael@0 315 #define NS_CACHE_STORAGE_SERVICE_CONTRACTID \
michael@0 316 "@mozilla.org/netwerk/cache-storage-service;1"
michael@0 317
michael@0 318 #endif

mercurial