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