netwerk/cache/nsCacheService.h

branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
equal deleted inserted replaced
-1:000000000000 0:b968e343d5ca
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/. */
6
7 #ifndef _nsCacheService_h_
8 #define _nsCacheService_h_
9
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"
17
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"
26
27 class nsCacheRequest;
28 class nsCacheProfilePrefObserver;
29 class nsDiskCacheDevice;
30 class nsMemoryCacheDevice;
31 class nsOfflineCacheDevice;
32 class nsCacheServiceAutoLock;
33 class nsITimer;
34 class mozIStorageService;
35
36
37 /******************************************************************************
38 * nsNotifyDoomListener
39 *****************************************************************************/
40
41 class nsNotifyDoomListener : public nsRunnable {
42 public:
43 nsNotifyDoomListener(nsICacheListener *listener,
44 nsresult status)
45 : mListener(listener) // transfers reference
46 , mStatus(status)
47 {}
48
49 NS_IMETHOD Run()
50 {
51 mListener->OnCacheEntryDoomed(mStatus);
52 NS_RELEASE(mListener);
53 return NS_OK;
54 }
55
56 private:
57 nsICacheListener *mListener;
58 nsresult mStatus;
59 };
60
61 /******************************************************************************
62 * nsCacheService
63 ******************************************************************************/
64
65 class nsCacheService : public nsICacheServiceInternal,
66 public nsIMemoryReporter
67 {
68 public:
69 NS_DECL_THREADSAFE_ISUPPORTS
70 NS_DECL_NSICACHESERVICE
71 NS_DECL_NSICACHESERVICEINTERNAL
72 NS_DECL_NSIMEMORYREPORTER
73
74 nsCacheService();
75 virtual ~nsCacheService();
76
77 // Define a Create method to be used with a factory:
78 static nsresult
79 Create(nsISupports* outer, const nsIID& iid, void* *result);
80
81
82 /**
83 * Methods called by nsCacheSession
84 */
85 static nsresult OpenCacheEntry(nsCacheSession * session,
86 const nsACString & key,
87 nsCacheAccessMode accessRequested,
88 bool blockingMode,
89 nsICacheListener * listener,
90 nsICacheEntryDescriptor ** result);
91
92 static nsresult EvictEntriesForSession(nsCacheSession * session);
93
94 static nsresult IsStorageEnabledForPolicy(nsCacheStoragePolicy storagePolicy,
95 bool * result);
96
97 static nsresult DoomEntry(nsCacheSession *session,
98 const nsACString &key,
99 nsICacheListener *listener);
100
101 /**
102 * Methods called by nsCacheEntryDescriptor
103 */
104
105 static void CloseDescriptor(nsCacheEntryDescriptor * descriptor);
106
107 static nsresult GetFileForEntry(nsCacheEntry * entry,
108 nsIFile ** result);
109
110 static nsresult OpenInputStreamForEntry(nsCacheEntry * entry,
111 nsCacheAccessMode mode,
112 uint32_t offset,
113 nsIInputStream ** result);
114
115 static nsresult OpenOutputStreamForEntry(nsCacheEntry * entry,
116 nsCacheAccessMode mode,
117 uint32_t offset,
118 nsIOutputStream ** result);
119
120 static nsresult OnDataSizeChange(nsCacheEntry * entry, int32_t deltaSize);
121
122 static nsresult SetCacheElement(nsCacheEntry * entry, nsISupports * element);
123
124 static nsresult ValidateEntry(nsCacheEntry * entry);
125
126 static int32_t CacheCompressionLevel();
127
128 static bool GetClearingEntries();
129
130 static void GetCacheBaseDirectoty(nsIFile ** result);
131 static void GetDiskCacheDirectory(nsIFile ** result);
132 static void GetAppCacheDirectory(nsIFile ** result);
133
134 /**
135 * Methods called by any cache classes
136 */
137
138 static
139 nsCacheService * GlobalInstance() { return gService; }
140
141 static nsresult DoomEntry(nsCacheEntry * entry);
142
143 static bool IsStorageEnabledForPolicy_Locked(nsCacheStoragePolicy policy);
144
145 /**
146 * Called by disk cache to notify us to use the new max smart size
147 */
148 static void MarkStartingFresh();
149
150 /**
151 * Methods called by nsApplicationCacheService
152 */
153
154 nsresult GetOfflineDevice(nsOfflineCacheDevice ** aDevice);
155
156 /**
157 * Creates an offline cache device that works over a specific profile directory.
158 * A tool to preload offline cache for profiles different from the current
159 * application's profile directory.
160 */
161 nsresult GetCustomOfflineDevice(nsIFile *aProfileDir,
162 int32_t aQuota,
163 nsOfflineCacheDevice **aDevice);
164
165 // This method may be called to release an object while the cache service
166 // lock is being held. If a non-null target is specified and the target
167 // does not correspond to the current thread, then the release will be
168 // proxied to the specified target. Otherwise, the object will be added to
169 // the list of objects to be released when the cache service is unlocked.
170 static void ReleaseObject_Locked(nsISupports * object,
171 nsIEventTarget * target = nullptr);
172
173 static nsresult DispatchToCacheIOThread(nsIRunnable* event);
174
175 // Calling this method will block the calling thread until all pending
176 // events on the cache-io thread has finished. The calling thread must
177 // hold the cache-lock
178 static nsresult SyncWithCacheIOThread();
179
180
181 /**
182 * Methods called by nsCacheProfilePrefObserver
183 */
184 static void OnProfileShutdown(bool cleanse);
185 static void OnProfileChanged();
186
187 static void SetDiskCacheEnabled(bool enabled);
188 // Sets the disk cache capacity (in kilobytes)
189 static void SetDiskCacheCapacity(int32_t capacity);
190 // Set max size for a disk-cache entry (in KB). -1 disables limit up to
191 // 1/8th of disk cache size
192 static void SetDiskCacheMaxEntrySize(int32_t maxSize);
193 // Set max size for a memory-cache entry (in kilobytes). -1 disables
194 // limit up to 90% of memory cache size
195 static void SetMemoryCacheMaxEntrySize(int32_t maxSize);
196
197 static void SetOfflineCacheEnabled(bool enabled);
198 // Sets the offline cache capacity (in kilobytes)
199 static void SetOfflineCacheCapacity(int32_t capacity);
200
201 static void SetMemoryCache();
202
203 static void SetCacheCompressionLevel(int32_t level);
204
205 // Starts smart cache size computation if disk device is available
206 static nsresult SetDiskSmartSize();
207
208 static void MoveOrRemoveDiskCache(nsIFile *aOldCacheDir,
209 nsIFile *aNewCacheDir,
210 const char *aCacheSubdir);
211
212 nsresult Init();
213 void Shutdown();
214
215 static bool IsInitialized()
216 {
217 if (!gService) {
218 return false;
219 }
220 return gService->mInitialized;
221 }
222
223 static void AssertOwnsLock()
224 { gService->mLock.AssertCurrentThreadOwns(); }
225
226 static void LeavePrivateBrowsing();
227 bool IsDoomListEmpty();
228
229 typedef bool (*DoomCheckFn)(nsCacheEntry* entry);
230
231 private:
232 friend class nsCacheServiceAutoLock;
233 friend class nsOfflineCacheDevice;
234 friend class nsProcessRequestEvent;
235 friend class nsSetSmartSizeEvent;
236 friend class nsBlockOnCacheThreadEvent;
237 friend class nsSetDiskSmartSizeCallback;
238 friend class nsDoomEvent;
239 friend class nsDisableOldMaxSmartSizePrefEvent;
240 friend class nsDiskCacheMap;
241 friend class nsAsyncDoomEvent;
242 friend class nsCacheEntryDescriptor;
243
244 /**
245 * Internal Methods
246 */
247
248 static void Lock(::mozilla::Telemetry::ID mainThreadLockerID);
249 static void Unlock();
250 void LockAcquired();
251 void LockReleased();
252
253 nsresult CreateDiskDevice();
254 nsresult CreateOfflineDevice();
255 nsresult CreateCustomOfflineDevice(nsIFile *aProfileDir,
256 int32_t aQuota,
257 nsOfflineCacheDevice **aDevice);
258 nsresult CreateMemoryDevice();
259
260 nsresult RemoveCustomOfflineDevice(nsOfflineCacheDevice *aDevice);
261
262 nsresult CreateRequest(nsCacheSession * session,
263 const nsACString & clientKey,
264 nsCacheAccessMode accessRequested,
265 bool blockingMode,
266 nsICacheListener * listener,
267 nsCacheRequest ** request);
268
269 nsresult DoomEntry_Internal(nsCacheEntry * entry,
270 bool doProcessPendingRequests);
271
272 nsresult EvictEntriesForClient(const char * clientID,
273 nsCacheStoragePolicy storagePolicy);
274
275 // Notifies request listener asynchronously on the request's thread, and
276 // releases the descriptor on the request's thread. If this method fails,
277 // the descriptor is not released.
278 nsresult NotifyListener(nsCacheRequest * request,
279 nsICacheEntryDescriptor * descriptor,
280 nsCacheAccessMode accessGranted,
281 nsresult error);
282
283 nsresult ActivateEntry(nsCacheRequest * request,
284 nsCacheEntry ** entry,
285 nsCacheEntry ** doomedEntry);
286
287 nsCacheDevice * EnsureEntryHasDevice(nsCacheEntry * entry);
288
289 nsCacheEntry * SearchCacheDevices(nsCString * key, nsCacheStoragePolicy policy, bool *collision);
290
291 void DeactivateEntry(nsCacheEntry * entry);
292
293 nsresult ProcessRequest(nsCacheRequest * request,
294 bool calledFromOpenCacheEntry,
295 nsICacheEntryDescriptor ** result);
296
297 nsresult ProcessPendingRequests(nsCacheEntry * entry);
298
299 void ClearDoomList(void);
300 void DoomActiveEntries(DoomCheckFn check);
301 void CloseAllStreams();
302 void FireClearNetworkCacheStoredAnywhereNotification();
303
304 static
305 PLDHashOperator GetActiveEntries(PLDHashTable * table,
306 PLDHashEntryHdr * hdr,
307 uint32_t number,
308 void * arg);
309 static
310 PLDHashOperator RemoveActiveEntry(PLDHashTable * table,
311 PLDHashEntryHdr * hdr,
312 uint32_t number,
313 void * arg);
314
315 static
316 PLDHashOperator ShutdownCustomCacheDeviceEnum(const nsAString& aProfileDir,
317 nsRefPtr<nsOfflineCacheDevice>& aDevice,
318 void* aUserArg);
319 #if defined(PR_LOGGING)
320 void LogCacheStatistics();
321 #endif
322
323 nsresult SetDiskSmartSize_Locked();
324
325 /**
326 * Data Members
327 */
328
329 static nsCacheService * gService; // there can be only one...
330
331 nsCOMPtr<mozIStorageService> mStorageService;
332
333 nsCacheProfilePrefObserver * mObserver;
334
335 mozilla::Mutex mLock;
336 mozilla::CondVar mCondVar;
337
338 mozilla::Mutex mTimeStampLock;
339 mozilla::TimeStamp mLockAcquiredTimeStamp;
340
341 nsCOMPtr<nsIThread> mCacheIOThread;
342
343 nsTArray<nsISupports*> mDoomedObjects;
344 nsCOMPtr<nsITimer> mSmartSizeTimer;
345
346 bool mInitialized;
347 bool mClearingEntries;
348
349 bool mEnableMemoryDevice;
350 bool mEnableDiskDevice;
351 bool mEnableOfflineDevice;
352
353 nsMemoryCacheDevice * mMemoryDevice;
354 nsDiskCacheDevice * mDiskDevice;
355 nsOfflineCacheDevice * mOfflineDevice;
356
357 nsRefPtrHashtable<nsStringHashKey, nsOfflineCacheDevice> mCustomOfflineDevices;
358
359 nsCacheEntryHashTable mActiveEntries;
360 PRCList mDoomedEntries;
361
362 // stats
363
364 uint32_t mTotalEntries;
365 uint32_t mCacheHits;
366 uint32_t mCacheMisses;
367 uint32_t mMaxKeyLength;
368 uint32_t mMaxDataSize;
369 uint32_t mMaxMetaSize;
370
371 // Unexpected error totals
372 uint32_t mDeactivateFailures;
373 uint32_t mDeactivatedUnboundEntries;
374 };
375
376 /******************************************************************************
377 * nsCacheServiceAutoLock
378 ******************************************************************************/
379
380 #define LOCK_TELEM(x) \
381 (::mozilla::Telemetry::CACHE_SERVICE_LOCK_WAIT_MAINTHREAD_##x)
382
383 // Instantiate this class to acquire the cache service lock for a particular
384 // execution scope.
385 class nsCacheServiceAutoLock {
386 public:
387 nsCacheServiceAutoLock(mozilla::Telemetry::ID mainThreadLockerID) {
388 nsCacheService::Lock(mainThreadLockerID);
389 }
390 ~nsCacheServiceAutoLock() {
391 nsCacheService::Unlock();
392 }
393 };
394
395 #endif // _nsCacheService_h_

mercurial