1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
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/. */
8 #ifndef _nsCacheService_h_
9 #define _nsCacheService_h_
11 #include "nsICacheService.h"
12 #include "nsCacheSession.h"
13 #include "nsCacheDevice.h"
14 #include "nsCacheEntry.h"
17 #include "nsIObserver.h"
20 #include "nsRefPtrHashtable.h"
21 #include "mozilla/CondVar.h"
22 #include "mozilla/Mutex.h"
23 #include "mozilla/Telemetry.h"
26 class nsCacheProfilePrefObserver
;
27 class nsDiskCacheDevice
;
28 class nsMemoryCacheDevice
;
29 class nsOfflineCacheDevice
;
30 class nsCacheServiceAutoLock
;
34 /******************************************************************************
36 ******************************************************************************/
38 class nsCacheService
: public nsICacheService
42 NS_DECL_NSICACHESERVICE
45 virtual ~nsCacheService();
47 // Define a Create method to be used with a factory:
49 Create(nsISupports
* outer
, const nsIID
& iid
, void* *result
);
53 * Methods called by nsCacheSession
55 static nsresult
OpenCacheEntry(nsCacheSession
* session
,
56 const nsACString
& key
,
57 nsCacheAccessMode accessRequested
,
59 nsICacheListener
* listener
,
60 nsICacheEntryDescriptor
** result
);
62 static nsresult
EvictEntriesForSession(nsCacheSession
* session
);
64 static nsresult
IsStorageEnabledForPolicy(nsCacheStoragePolicy storagePolicy
,
67 static nsresult
DoomEntry(nsCacheSession
*session
,
68 const nsACString
&key
,
69 nsICacheListener
*listener
);
72 * Methods called by nsCacheEntryDescriptor
75 static void CloseDescriptor(nsCacheEntryDescriptor
* descriptor
);
77 static nsresult
GetFileForEntry(nsCacheEntry
* entry
,
80 static nsresult
OpenInputStreamForEntry(nsCacheEntry
* entry
,
81 nsCacheAccessMode mode
,
83 nsIInputStream
** result
);
85 static nsresult
OpenOutputStreamForEntry(nsCacheEntry
* entry
,
86 nsCacheAccessMode mode
,
88 nsIOutputStream
** result
);
90 static nsresult
OnDataSizeChange(nsCacheEntry
* entry
, PRInt32 deltaSize
);
92 static nsresult
SetCacheElement(nsCacheEntry
* entry
, nsISupports
* element
);
94 static nsresult
ValidateEntry(nsCacheEntry
* entry
);
96 static PRInt32
CacheCompressionLevel();
99 * Methods called by any cache classes
103 nsCacheService
* GlobalInstance() { return gService
; }
105 static PRInt64
MemoryDeviceSize();
107 static nsresult
DoomEntry(nsCacheEntry
* entry
);
109 static bool IsStorageEnabledForPolicy_Locked(nsCacheStoragePolicy policy
);
112 * Called by disk cache to notify us to use the new max smart size
114 static void MarkStartingFresh();
117 * Methods called by nsApplicationCacheService
120 nsresult
GetOfflineDevice(nsOfflineCacheDevice
** aDevice
);
123 * Creates an offline cache device that works over a specific profile directory.
124 * A tool to preload offline cache for profiles different from the current
125 * application's profile directory.
127 nsresult
GetCustomOfflineDevice(nsIFile
*aProfileDir
,
129 nsOfflineCacheDevice
**aDevice
);
131 // This method may be called to release an object while the cache service
132 // lock is being held. If a non-null target is specified and the target
133 // does not correspond to the current thread, then the release will be
134 // proxied to the specified target. Otherwise, the object will be added to
135 // the list of objects to be released when the cache service is unlocked.
136 static void ReleaseObject_Locked(nsISupports
* object
,
137 nsIEventTarget
* target
= nullptr);
139 static nsresult
DispatchToCacheIOThread(nsIRunnable
* event
);
141 // Calling this method will block the calling thread until all pending
142 // events on the cache-io thread has finished. The calling thread must
143 // hold the cache-lock
144 static nsresult
SyncWithCacheIOThread();
148 * Methods called by nsCacheProfilePrefObserver
150 static void OnProfileShutdown(bool cleanse
);
151 static void OnProfileChanged();
153 static void SetDiskCacheEnabled(bool enabled
);
154 // Sets the disk cache capacity (in kilobytes)
155 static void SetDiskCacheCapacity(PRInt32 capacity
);
156 // Set max size for a disk-cache entry (in KB). -1 disables limit up to
157 // 1/8th of disk cache size
158 static void SetDiskCacheMaxEntrySize(PRInt32 maxSize
);
159 // Set max size for a memory-cache entry (in kilobytes). -1 disables
160 // limit up to 90% of memory cache size
161 static void SetMemoryCacheMaxEntrySize(PRInt32 maxSize
);
163 static void SetOfflineCacheEnabled(bool enabled
);
164 // Sets the offline cache capacity (in kilobytes)
165 static void SetOfflineCacheCapacity(PRInt32 capacity
);
167 static void SetMemoryCache();
169 static void SetCacheCompressionLevel(PRInt32 level
);
171 // Starts smart cache size computation if disk device is available
172 static nsresult
SetDiskSmartSize();
177 static void AssertOwnsLock()
178 { gService
->mLock
.AssertCurrentThreadOwns(); }
180 static void LeavePrivateBrowsing();
182 typedef bool (*DoomCheckFn
)(nsCacheEntry
* entry
);
185 friend class nsCacheServiceAutoLock
;
186 friend class nsOfflineCacheDevice
;
187 friend class nsProcessRequestEvent
;
188 friend class nsSetSmartSizeEvent
;
189 friend class nsBlockOnCacheThreadEvent
;
190 friend class nsSetDiskSmartSizeCallback
;
191 friend class nsDoomEvent
;
192 friend class nsDisableOldMaxSmartSizePrefEvent
;
198 static void Lock(::mozilla::Telemetry::ID mainThreadLockerID
);
199 static void Unlock();
201 nsresult
CreateDiskDevice();
202 nsresult
CreateOfflineDevice();
203 nsresult
CreateCustomOfflineDevice(nsIFile
*aProfileDir
,
205 nsOfflineCacheDevice
**aDevice
);
206 nsresult
CreateMemoryDevice();
208 nsresult
RemoveCustomOfflineDevice(nsOfflineCacheDevice
*aDevice
);
210 nsresult
CreateRequest(nsCacheSession
* session
,
211 const nsACString
& clientKey
,
212 nsCacheAccessMode accessRequested
,
214 nsICacheListener
* listener
,
215 nsCacheRequest
** request
);
217 nsresult
DoomEntry_Internal(nsCacheEntry
* entry
,
218 bool doProcessPendingRequests
);
220 nsresult
EvictEntriesForClient(const char * clientID
,
221 nsCacheStoragePolicy storagePolicy
);
223 // Notifies request listener asynchronously on the request's thread, and
224 // releases the descriptor on the request's thread. If this method fails,
225 // the descriptor is not released.
226 nsresult
NotifyListener(nsCacheRequest
* request
,
227 nsICacheEntryDescriptor
* descriptor
,
228 nsCacheAccessMode accessGranted
,
231 nsresult
ActivateEntry(nsCacheRequest
* request
,
232 nsCacheEntry
** entry
,
233 nsCacheEntry
** doomedEntry
);
235 nsCacheDevice
* EnsureEntryHasDevice(nsCacheEntry
* entry
);
237 nsCacheEntry
* SearchCacheDevices(nsCString
* key
, nsCacheStoragePolicy policy
, bool *collision
);
239 void DeactivateEntry(nsCacheEntry
* entry
);
241 nsresult
ProcessRequest(nsCacheRequest
* request
,
242 bool calledFromOpenCacheEntry
,
243 nsICacheEntryDescriptor
** result
);
245 nsresult
ProcessPendingRequests(nsCacheEntry
* entry
);
247 void ClearPendingRequests(nsCacheEntry
* entry
);
248 void ClearDoomList(void);
249 void ClearActiveEntries(void);
250 void DoomActiveEntries(DoomCheckFn check
);
253 PLDHashOperator
DeactivateAndClearEntry(PLDHashTable
* table
,
254 PLDHashEntryHdr
* hdr
,
258 PLDHashOperator
RemoveActiveEntry(PLDHashTable
* table
,
259 PLDHashEntryHdr
* hdr
,
264 PLDHashOperator
ShutdownCustomCacheDeviceEnum(const nsAString
& aProfileDir
,
265 nsRefPtr
<nsOfflineCacheDevice
>& aDevice
,
267 #if defined(PR_LOGGING)
268 void LogCacheStatistics();
271 nsresult
SetDiskSmartSize_Locked();
277 static nsCacheService
* gService
; // there can be only one...
279 nsCacheProfilePrefObserver
* mObserver
;
281 mozilla::Mutex mLock
;
282 mozilla::CondVar mCondVar
;
284 nsCOMPtr
<nsIThread
> mCacheIOThread
;
286 nsTArray
<nsISupports
*> mDoomedObjects
;
287 nsCOMPtr
<nsITimer
> mSmartSizeTimer
;
290 bool mClearingEntries
;
292 bool mEnableMemoryDevice
;
293 bool mEnableDiskDevice
;
294 bool mEnableOfflineDevice
;
296 nsMemoryCacheDevice
* mMemoryDevice
;
297 nsDiskCacheDevice
* mDiskDevice
;
298 nsOfflineCacheDevice
* mOfflineDevice
;
300 nsRefPtrHashtable
<nsStringHashKey
, nsOfflineCacheDevice
> mCustomOfflineDevices
;
302 nsCacheEntryHashTable mActiveEntries
;
303 PRCList mDoomedEntries
;
307 PRUint32 mTotalEntries
;
309 PRUint32 mCacheMisses
;
310 PRUint32 mMaxKeyLength
;
311 PRUint32 mMaxDataSize
;
312 PRUint32 mMaxMetaSize
;
314 // Unexpected error totals
315 PRUint32 mDeactivateFailures
;
316 PRUint32 mDeactivatedUnboundEntries
;
319 /******************************************************************************
320 * nsCacheServiceAutoLock
321 ******************************************************************************/
323 #define LOCK_TELEM(x) \
324 (::mozilla::Telemetry::CACHE_SERVICE_LOCK_WAIT_MAINTHREAD_##x)
326 // Instantiate this class to acquire the cache service lock for a particular
328 class nsCacheServiceAutoLock
{
330 nsCacheServiceAutoLock(mozilla::Telemetry::ID mainThreadLockerID
) {
331 nsCacheService::Lock(mainThreadLockerID
);
333 ~nsCacheServiceAutoLock() {
334 nsCacheService::Unlock();
338 #endif // _nsCacheService_h_