1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : *
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is nsCacheService.h, released
17 : * February 10, 2001.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * Netscape Communications Corporation.
21 : * Portions created by the Initial Developer are Copyright (C) 2001
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : * Gordon Sheridan <gordon@netscape.com>
26 : * Patrick C. Beard <beard@netscape.com>
27 : * Darin Fisher <darin@netscape.com>
28 : * Ehsan Akhgari <ehsan.akhgari@gmail.com>
29 : *
30 : * Alternatively, the contents of this file may be used under the terms of
31 : * either the GNU General Public License Version 2 or later (the "GPL"), or
32 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
33 : * in which case the provisions of the GPL or the LGPL are applicable instead
34 : * of those above. If you wish to allow use of your version of this file only
35 : * under the terms of either the GPL or the LGPL, and not to allow others to
36 : * use your version of this file under the terms of the MPL, indicate your
37 : * decision by deleting the provisions above and replace them with the notice
38 : * and other provisions required by the GPL or the LGPL. If you do not delete
39 : * the provisions above, a recipient may use your version of this file under
40 : * the terms of any one of the MPL, the GPL or the LGPL.
41 : *
42 : * ***** END LICENSE BLOCK ***** */
43 :
44 :
45 : #ifndef _nsCacheService_h_
46 : #define _nsCacheService_h_
47 :
48 : #include "nsICacheService.h"
49 : #include "nsCacheSession.h"
50 : #include "nsCacheDevice.h"
51 : #include "nsCacheEntry.h"
52 :
53 : #include "prthread.h"
54 : #include "nsIObserver.h"
55 : #include "nsString.h"
56 : #include "nsTArray.h"
57 : #include "mozilla/CondVar.h"
58 : #include "mozilla/Mutex.h"
59 :
60 : class nsCacheRequest;
61 : class nsCacheProfilePrefObserver;
62 : class nsDiskCacheDevice;
63 : class nsMemoryCacheDevice;
64 : class nsOfflineCacheDevice;
65 : class nsCacheServiceAutoLock;
66 : class nsITimer;
67 :
68 :
69 : /******************************************************************************
70 : * nsCacheService
71 : ******************************************************************************/
72 :
73 : class nsCacheService : public nsICacheService
74 : {
75 : public:
76 : NS_DECL_ISUPPORTS
77 : NS_DECL_NSICACHESERVICE
78 :
79 : nsCacheService();
80 : virtual ~nsCacheService();
81 :
82 : // Define a Create method to be used with a factory:
83 : static nsresult
84 : Create(nsISupports* outer, const nsIID& iid, void* *result);
85 :
86 :
87 : /**
88 : * Methods called by nsCacheSession
89 : */
90 : static nsresult OpenCacheEntry(nsCacheSession * session,
91 : const nsACString & key,
92 : nsCacheAccessMode accessRequested,
93 : bool blockingMode,
94 : nsICacheListener * listener,
95 : nsICacheEntryDescriptor ** result);
96 :
97 : static nsresult EvictEntriesForSession(nsCacheSession * session);
98 :
99 : static nsresult IsStorageEnabledForPolicy(nsCacheStoragePolicy storagePolicy,
100 : bool * result);
101 :
102 : /**
103 : * Methods called by nsCacheEntryDescriptor
104 : */
105 :
106 : static void CloseDescriptor(nsCacheEntryDescriptor * descriptor);
107 :
108 : static nsresult GetFileForEntry(nsCacheEntry * entry,
109 : nsIFile ** result);
110 :
111 : static nsresult OpenInputStreamForEntry(nsCacheEntry * entry,
112 : nsCacheAccessMode mode,
113 : PRUint32 offset,
114 : nsIInputStream ** result);
115 :
116 : static nsresult OpenOutputStreamForEntry(nsCacheEntry * entry,
117 : nsCacheAccessMode mode,
118 : PRUint32 offset,
119 : nsIOutputStream ** result);
120 :
121 : static nsresult OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize);
122 :
123 : static nsresult SetCacheElement(nsCacheEntry * entry, nsISupports * element);
124 :
125 : static nsresult ValidateEntry(nsCacheEntry * entry);
126 :
127 : static PRInt32 CacheCompressionLevel();
128 :
129 : /**
130 : * Methods called by any cache classes
131 : */
132 :
133 : static
134 5514 : nsCacheService * GlobalInstance() { return gService; }
135 :
136 : static
137 : PRInt64 MemoryDeviceSize();
138 :
139 : static nsresult DoomEntry(nsCacheEntry * entry);
140 :
141 : static bool IsStorageEnabledForPolicy_Locked(nsCacheStoragePolicy policy);
142 :
143 : // This method may be called to release an object while the cache service
144 : // lock is being held. If a non-null target is specified and the target
145 : // does not correspond to the current thread, then the release will be
146 : // proxied to the specified target. Otherwise, the object will be added to
147 : // the list of objects to be released when the cache service is unlocked.
148 : static void ReleaseObject_Locked(nsISupports * object,
149 : nsIEventTarget * target = nsnull);
150 :
151 : static nsresult DispatchToCacheIOThread(nsIRunnable* event);
152 :
153 : // Calling this method will block the calling thread until all pending
154 : // events on the cache-io thread has finished. The calling thread must
155 : // hold the cache-lock
156 : static nsresult SyncWithCacheIOThread();
157 :
158 :
159 : /**
160 : * Methods called by nsCacheProfilePrefObserver
161 : */
162 : static void OnProfileShutdown(bool cleanse);
163 : static void OnProfileChanged();
164 :
165 : static void SetDiskCacheEnabled(bool enabled);
166 : // Sets the disk cache capacity (in kilobytes)
167 : static void SetDiskCacheCapacity(PRInt32 capacity);
168 : // Set max size for a disk-cache entry (in KB). -1 disables limit up to
169 : // 1/8th of disk cache size
170 : static void SetDiskCacheMaxEntrySize(PRInt32 maxSize);
171 : // Set max size for a memory-cache entry (in kilobytes). -1 disables
172 : // limit up to 90% of memory cache size
173 : static void SetMemoryCacheMaxEntrySize(PRInt32 maxSize);
174 :
175 : static void SetOfflineCacheEnabled(bool enabled);
176 : // Sets the offline cache capacity (in kilobytes)
177 : static void SetOfflineCacheCapacity(PRInt32 capacity);
178 :
179 : static void SetMemoryCache();
180 :
181 : static void SetCacheCompressionLevel(PRInt32 level);
182 :
183 : static void OnEnterExitPrivateBrowsing();
184 :
185 : // Starts smart cache size computation if disk device is available
186 : static nsresult SetDiskSmartSize();
187 :
188 : nsresult Init();
189 : void Shutdown();
190 :
191 350 : static void AssertOwnsLock()
192 350 : { gService->mLock.AssertCurrentThreadOwns(); }
193 :
194 : private:
195 : friend class nsCacheServiceAutoLock;
196 : friend class nsOfflineCacheDevice;
197 : friend class nsProcessRequestEvent;
198 : friend class nsSetSmartSizeEvent;
199 : friend class nsBlockOnCacheThreadEvent;
200 : friend class nsSetDiskSmartSizeCallback;
201 :
202 : /**
203 : * Internal Methods
204 : */
205 :
206 : static void Lock();
207 : static void Unlock();
208 :
209 : nsresult CreateDiskDevice();
210 : nsresult CreateOfflineDevice();
211 : nsresult CreateMemoryDevice();
212 :
213 : nsresult CreateRequest(nsCacheSession * session,
214 : const nsACString & clientKey,
215 : nsCacheAccessMode accessRequested,
216 : bool blockingMode,
217 : nsICacheListener * listener,
218 : nsCacheRequest ** request);
219 :
220 : nsresult DoomEntry_Internal(nsCacheEntry * entry,
221 : bool doProcessPendingRequests);
222 :
223 : nsresult EvictEntriesForClient(const char * clientID,
224 : nsCacheStoragePolicy storagePolicy);
225 :
226 : // Notifies request listener asynchronously on the request's thread, and
227 : // releases the descriptor on the request's thread. If this method fails,
228 : // the descriptor is not released.
229 : nsresult NotifyListener(nsCacheRequest * request,
230 : nsICacheEntryDescriptor * descriptor,
231 : nsCacheAccessMode accessGranted,
232 : nsresult error);
233 :
234 : nsresult ActivateEntry(nsCacheRequest * request,
235 : nsCacheEntry ** entry,
236 : nsCacheEntry ** doomedEntry);
237 :
238 : nsCacheDevice * EnsureEntryHasDevice(nsCacheEntry * entry);
239 :
240 : nsCacheEntry * SearchCacheDevices(nsCString * key, nsCacheStoragePolicy policy, bool *collision);
241 :
242 : void DeactivateEntry(nsCacheEntry * entry);
243 :
244 : nsresult ProcessRequest(nsCacheRequest * request,
245 : bool calledFromOpenCacheEntry,
246 : nsICacheEntryDescriptor ** result);
247 :
248 : nsresult ProcessPendingRequests(nsCacheEntry * entry);
249 :
250 : void ClearPendingRequests(nsCacheEntry * entry);
251 : void ClearDoomList(void);
252 : void ClearActiveEntries(void);
253 : void DoomActiveEntries(void);
254 :
255 : static
256 : PLDHashOperator DeactivateAndClearEntry(PLDHashTable * table,
257 : PLDHashEntryHdr * hdr,
258 : PRUint32 number,
259 : void * arg);
260 : static
261 : PLDHashOperator RemoveActiveEntry(PLDHashTable * table,
262 : PLDHashEntryHdr * hdr,
263 : PRUint32 number,
264 : void * arg);
265 : #if defined(PR_LOGGING)
266 : void LogCacheStatistics();
267 : #endif
268 :
269 : nsresult SetDiskSmartSize_Locked();
270 :
271 : /**
272 : * Data Members
273 : */
274 :
275 : static nsCacheService * gService; // there can be only one...
276 :
277 : nsCacheProfilePrefObserver * mObserver;
278 :
279 : mozilla::Mutex mLock;
280 : mozilla::CondVar mCondVar;
281 :
282 : nsCOMPtr<nsIThread> mCacheIOThread;
283 :
284 : nsTArray<nsISupports*> mDoomedObjects;
285 : nsCOMPtr<nsITimer> mSmartSizeTimer;
286 :
287 : bool mInitialized;
288 :
289 : bool mEnableMemoryDevice;
290 : bool mEnableDiskDevice;
291 : bool mEnableOfflineDevice;
292 :
293 : nsMemoryCacheDevice * mMemoryDevice;
294 : nsDiskCacheDevice * mDiskDevice;
295 : nsOfflineCacheDevice * mOfflineDevice;
296 :
297 : nsCacheEntryHashTable mActiveEntries;
298 : PRCList mDoomedEntries;
299 :
300 : // stats
301 :
302 : PRUint32 mTotalEntries;
303 : PRUint32 mCacheHits;
304 : PRUint32 mCacheMisses;
305 : PRUint32 mMaxKeyLength;
306 : PRUint32 mMaxDataSize;
307 : PRUint32 mMaxMetaSize;
308 :
309 : // Unexpected error totals
310 : PRUint32 mDeactivateFailures;
311 : PRUint32 mDeactivatedUnboundEntries;
312 : };
313 :
314 : /******************************************************************************
315 : * nsCacheServiceAutoLock
316 : ******************************************************************************/
317 :
318 : // Instantiate this class to acquire the cache service lock for a particular
319 : // execution scope.
320 : class nsCacheServiceAutoLock {
321 : public:
322 28711 : nsCacheServiceAutoLock() {
323 28711 : nsCacheService::Lock();
324 28711 : }
325 28711 : ~nsCacheServiceAutoLock() {
326 28711 : nsCacheService::Unlock();
327 28711 : }
328 : };
329 :
330 : #endif // _nsCacheService_h_
|