Bumping manifests a=b2g-bump
[gecko.git] / netwerk / cache / nsCacheService.h
blob10148b29d78191002044f255cde8ee4cafa7980a
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set ts=8 sts=4 et sw=4 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef _nsCacheService_h_
8 #define _nsCacheService_h_
10 #include "nsICacheService.h"
11 #include "nsCacheSession.h"
12 #include "nsCacheDevice.h"
13 #include "nsCacheEntry.h"
14 #include "nsThreadUtils.h"
15 #include "nsICacheListener.h"
16 #include "nsIMemoryReporter.h"
18 #include "prthread.h"
19 #include "nsIObserver.h"
20 #include "nsString.h"
21 #include "nsTArray.h"
22 #include "nsRefPtrHashtable.h"
23 #include "mozilla/CondVar.h"
24 #include "mozilla/Mutex.h"
25 #include "mozilla/Telemetry.h"
27 class nsCacheRequest;
28 class nsCacheProfilePrefObserver;
29 class nsDiskCacheDevice;
30 class nsMemoryCacheDevice;
31 class nsOfflineCacheDevice;
32 class nsCacheServiceAutoLock;
33 class nsITimer;
34 class mozIStorageService;
37 /******************************************************************************
38 * nsNotifyDoomListener
39 *****************************************************************************/
41 class nsNotifyDoomListener : public nsRunnable {
42 public:
43 nsNotifyDoomListener(nsICacheListener *listener,
44 nsresult status)
45 : mListener(listener) // transfers reference
46 , mStatus(status)
49 NS_IMETHOD Run()
51 mListener->OnCacheEntryDoomed(mStatus);
52 NS_RELEASE(mListener);
53 return NS_OK;
56 private:
57 nsICacheListener *mListener;
58 nsresult mStatus;
61 /******************************************************************************
62 * nsCacheService
63 ******************************************************************************/
65 class nsCacheService MOZ_FINAL : public nsICacheServiceInternal,
66 public nsIMemoryReporter
68 virtual ~nsCacheService();
70 public:
71 NS_DECL_THREADSAFE_ISUPPORTS
72 NS_DECL_NSICACHESERVICE
73 NS_DECL_NSICACHESERVICEINTERNAL
74 NS_DECL_NSIMEMORYREPORTER
76 nsCacheService();
78 // Define a Create method to be used with a factory:
79 static nsresult
80 Create(nsISupports* outer, const nsIID& iid, void* *result);
83 /**
84 * Methods called by nsCacheSession
86 static nsresult OpenCacheEntry(nsCacheSession * session,
87 const nsACString & key,
88 nsCacheAccessMode accessRequested,
89 bool blockingMode,
90 nsICacheListener * listener,
91 nsICacheEntryDescriptor ** result);
93 static nsresult EvictEntriesForSession(nsCacheSession * session);
95 static nsresult IsStorageEnabledForPolicy(nsCacheStoragePolicy storagePolicy,
96 bool * result);
98 static nsresult DoomEntry(nsCacheSession *session,
99 const nsACString &key,
100 nsICacheListener *listener);
103 * Methods called by nsCacheEntryDescriptor
106 static void CloseDescriptor(nsCacheEntryDescriptor * descriptor);
108 static nsresult GetFileForEntry(nsCacheEntry * entry,
109 nsIFile ** result);
111 static nsresult OpenInputStreamForEntry(nsCacheEntry * entry,
112 nsCacheAccessMode mode,
113 uint32_t offset,
114 nsIInputStream ** result);
116 static nsresult OpenOutputStreamForEntry(nsCacheEntry * entry,
117 nsCacheAccessMode mode,
118 uint32_t offset,
119 nsIOutputStream ** result);
121 static nsresult OnDataSizeChange(nsCacheEntry * entry, int32_t deltaSize);
123 static nsresult SetCacheElement(nsCacheEntry * entry, nsISupports * element);
125 static nsresult ValidateEntry(nsCacheEntry * entry);
127 static int32_t CacheCompressionLevel();
129 static bool GetClearingEntries();
131 static void GetCacheBaseDirectoty(nsIFile ** result);
132 static void GetDiskCacheDirectory(nsIFile ** result);
133 static void GetAppCacheDirectory(nsIFile ** result);
136 * Methods called by any cache classes
139 static
140 nsCacheService * GlobalInstance() { return gService; }
142 static nsresult DoomEntry(nsCacheEntry * entry);
144 static bool IsStorageEnabledForPolicy_Locked(nsCacheStoragePolicy policy);
147 * Called by disk cache to notify us to use the new max smart size
149 static void MarkStartingFresh();
152 * Methods called by nsApplicationCacheService
155 nsresult GetOfflineDevice(nsOfflineCacheDevice ** aDevice);
158 * Creates an offline cache device that works over a specific profile directory.
159 * A tool to preload offline cache for profiles different from the current
160 * application's profile directory.
162 nsresult GetCustomOfflineDevice(nsIFile *aProfileDir,
163 int32_t aQuota,
164 nsOfflineCacheDevice **aDevice);
166 // This method may be called to release an object while the cache service
167 // lock is being held. If a non-null target is specified and the target
168 // does not correspond to the current thread, then the release will be
169 // proxied to the specified target. Otherwise, the object will be added to
170 // the list of objects to be released when the cache service is unlocked.
171 static void ReleaseObject_Locked(nsISupports * object,
172 nsIEventTarget * target = nullptr);
174 static nsresult DispatchToCacheIOThread(nsIRunnable* event);
176 // Calling this method will block the calling thread until all pending
177 // events on the cache-io thread has finished. The calling thread must
178 // hold the cache-lock
179 static nsresult SyncWithCacheIOThread();
183 * Methods called by nsCacheProfilePrefObserver
185 static void OnProfileShutdown(bool cleanse);
186 static void OnProfileChanged();
188 static void SetDiskCacheEnabled(bool enabled);
189 // Sets the disk cache capacity (in kilobytes)
190 static void SetDiskCacheCapacity(int32_t capacity);
191 // Set max size for a disk-cache entry (in KB). -1 disables limit up to
192 // 1/8th of disk cache size
193 static void SetDiskCacheMaxEntrySize(int32_t maxSize);
194 // Set max size for a memory-cache entry (in kilobytes). -1 disables
195 // limit up to 90% of memory cache size
196 static void SetMemoryCacheMaxEntrySize(int32_t maxSize);
198 static void SetOfflineCacheEnabled(bool enabled);
199 // Sets the offline cache capacity (in kilobytes)
200 static void SetOfflineCacheCapacity(int32_t capacity);
202 static void SetMemoryCache();
204 static void SetCacheCompressionLevel(int32_t level);
206 // Starts smart cache size computation if disk device is available
207 static nsresult SetDiskSmartSize();
209 static void MoveOrRemoveDiskCache(nsIFile *aOldCacheDir,
210 nsIFile *aNewCacheDir,
211 const char *aCacheSubdir);
213 nsresult Init();
214 void Shutdown();
216 static bool IsInitialized()
218 if (!gService) {
219 return false;
221 return gService->mInitialized;
224 static void AssertOwnsLock()
225 { gService->mLock.AssertCurrentThreadOwns(); }
227 static void LeavePrivateBrowsing();
228 bool IsDoomListEmpty();
230 typedef bool (*DoomCheckFn)(nsCacheEntry* entry);
232 // Accessors to the disabled functionality
233 nsresult CreateSessionInternal(const char * clientID,
234 nsCacheStoragePolicy storagePolicy,
235 bool streamBased,
236 nsICacheSession **result);
237 nsresult VisitEntriesInternal(nsICacheVisitor *visitor);
238 nsresult EvictEntriesInternal(nsCacheStoragePolicy storagePolicy);
240 private:
241 friend class nsCacheServiceAutoLock;
242 friend class nsOfflineCacheDevice;
243 friend class nsProcessRequestEvent;
244 friend class nsSetSmartSizeEvent;
245 friend class nsBlockOnCacheThreadEvent;
246 friend class nsSetDiskSmartSizeCallback;
247 friend class nsDoomEvent;
248 friend class nsDisableOldMaxSmartSizePrefEvent;
249 friend class nsDiskCacheMap;
250 friend class nsAsyncDoomEvent;
251 friend class nsCacheEntryDescriptor;
254 * Internal Methods
257 static void Lock(::mozilla::Telemetry::ID mainThreadLockerID);
258 static void Unlock();
259 void LockAcquired();
260 void LockReleased();
262 nsresult CreateDiskDevice();
263 nsresult CreateOfflineDevice();
264 nsresult CreateCustomOfflineDevice(nsIFile *aProfileDir,
265 int32_t aQuota,
266 nsOfflineCacheDevice **aDevice);
267 nsresult CreateMemoryDevice();
269 nsresult RemoveCustomOfflineDevice(nsOfflineCacheDevice *aDevice);
271 nsresult CreateRequest(nsCacheSession * session,
272 const nsACString & clientKey,
273 nsCacheAccessMode accessRequested,
274 bool blockingMode,
275 nsICacheListener * listener,
276 nsCacheRequest ** request);
278 nsresult DoomEntry_Internal(nsCacheEntry * entry,
279 bool doProcessPendingRequests);
281 nsresult EvictEntriesForClient(const char * clientID,
282 nsCacheStoragePolicy storagePolicy);
284 // Notifies request listener asynchronously on the request's thread, and
285 // releases the descriptor on the request's thread. If this method fails,
286 // the descriptor is not released.
287 nsresult NotifyListener(nsCacheRequest * request,
288 nsICacheEntryDescriptor * descriptor,
289 nsCacheAccessMode accessGranted,
290 nsresult error);
292 nsresult ActivateEntry(nsCacheRequest * request,
293 nsCacheEntry ** entry,
294 nsCacheEntry ** doomedEntry);
296 nsCacheDevice * EnsureEntryHasDevice(nsCacheEntry * entry);
298 nsCacheEntry * SearchCacheDevices(nsCString * key, nsCacheStoragePolicy policy, bool *collision);
300 void DeactivateEntry(nsCacheEntry * entry);
302 nsresult ProcessRequest(nsCacheRequest * request,
303 bool calledFromOpenCacheEntry,
304 nsICacheEntryDescriptor ** result);
306 nsresult ProcessPendingRequests(nsCacheEntry * entry);
308 void ClearDoomList(void);
309 void DoomActiveEntries(DoomCheckFn check);
310 void CloseAllStreams();
311 void FireClearNetworkCacheStoredAnywhereNotification();
313 static
314 PLDHashOperator GetActiveEntries(PLDHashTable * table,
315 PLDHashEntryHdr * hdr,
316 uint32_t number,
317 void * arg);
318 static
319 PLDHashOperator RemoveActiveEntry(PLDHashTable * table,
320 PLDHashEntryHdr * hdr,
321 uint32_t number,
322 void * arg);
324 static
325 PLDHashOperator ShutdownCustomCacheDeviceEnum(const nsAString& aProfileDir,
326 nsRefPtr<nsOfflineCacheDevice>& aDevice,
327 void* aUserArg);
328 #if defined(PR_LOGGING)
329 void LogCacheStatistics();
330 #endif
332 nsresult SetDiskSmartSize_Locked();
335 * Data Members
338 static nsCacheService * gService; // there can be only one...
340 nsCOMPtr<mozIStorageService> mStorageService;
342 nsCacheProfilePrefObserver * mObserver;
344 mozilla::Mutex mLock;
345 mozilla::CondVar mCondVar;
347 mozilla::Mutex mTimeStampLock;
348 mozilla::TimeStamp mLockAcquiredTimeStamp;
350 nsCOMPtr<nsIThread> mCacheIOThread;
352 nsTArray<nsISupports*> mDoomedObjects;
353 nsCOMPtr<nsITimer> mSmartSizeTimer;
355 bool mInitialized;
356 bool mClearingEntries;
358 bool mEnableMemoryDevice;
359 bool mEnableDiskDevice;
360 bool mEnableOfflineDevice;
362 nsMemoryCacheDevice * mMemoryDevice;
363 nsDiskCacheDevice * mDiskDevice;
364 nsOfflineCacheDevice * mOfflineDevice;
366 nsRefPtrHashtable<nsStringHashKey, nsOfflineCacheDevice> mCustomOfflineDevices;
368 nsCacheEntryHashTable mActiveEntries;
369 PRCList mDoomedEntries;
371 // stats
373 uint32_t mTotalEntries;
374 uint32_t mCacheHits;
375 uint32_t mCacheMisses;
376 uint32_t mMaxKeyLength;
377 uint32_t mMaxDataSize;
378 uint32_t mMaxMetaSize;
380 // Unexpected error totals
381 uint32_t mDeactivateFailures;
382 uint32_t mDeactivatedUnboundEntries;
385 /******************************************************************************
386 * nsCacheServiceAutoLock
387 ******************************************************************************/
389 #define LOCK_TELEM(x) \
390 (::mozilla::Telemetry::CACHE_SERVICE_LOCK_WAIT_MAINTHREAD_##x)
392 // Instantiate this class to acquire the cache service lock for a particular
393 // execution scope.
394 class nsCacheServiceAutoLock {
395 public:
396 explicit nsCacheServiceAutoLock(mozilla::Telemetry::ID mainThreadLockerID) {
397 nsCacheService::Lock(mainThreadLockerID);
399 ~nsCacheServiceAutoLock() {
400 nsCacheService::Unlock();
404 #endif // _nsCacheService_h_