dom/quota/QuotaManager.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:61a44058bc4b
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef mozilla_dom_quota_quotamanager_h__
8 #define mozilla_dom_quota_quotamanager_h__
9
10 #include "QuotaCommon.h"
11
12 #include "nsIObserver.h"
13 #include "nsIQuotaManager.h"
14
15 #include "mozilla/dom/Nullable.h"
16 #include "mozilla/Mutex.h"
17
18 #include "nsClassHashtable.h"
19 #include "nsRefPtrHashtable.h"
20
21 #include "ArrayCluster.h"
22 #include "Client.h"
23 #include "PersistenceType.h"
24 #include "StoragePrivilege.h"
25
26 #define QUOTA_MANAGER_CONTRACTID "@mozilla.org/dom/quota/manager;1"
27
28 class nsIOfflineStorage;
29 class nsIPrincipal;
30 class nsIThread;
31 class nsITimer;
32 class nsIURI;
33 class nsPIDOMWindow;
34 class nsIRunnable;
35
36 BEGIN_QUOTA_NAMESPACE
37
38 class AcquireListener;
39 class AsyncUsageRunnable;
40 class CheckQuotaHelper;
41 class CollectOriginsHelper;
42 class FinalizeOriginEvictionRunnable;
43 class GroupInfo;
44 class GroupInfoPair;
45 class OriginClearRunnable;
46 class OriginInfo;
47 class OriginOrPatternString;
48 class QuotaObject;
49 class ResetOrClearRunnable;
50 struct SynchronizedOp;
51
52 class QuotaManager MOZ_FINAL : public nsIQuotaManager,
53 public nsIObserver
54 {
55 friend class AsyncUsageRunnable;
56 friend class CollectOriginsHelper;
57 friend class FinalizeOriginEvictionRunnable;
58 friend class GroupInfo;
59 friend class OriginClearRunnable;
60 friend class OriginInfo;
61 friend class QuotaObject;
62 friend class ResetOrClearRunnable;
63
64 enum MozBrowserPatternFlag
65 {
66 MozBrowser = 0,
67 NotMozBrowser,
68 IgnoreMozBrowser
69 };
70
71 typedef void
72 (*WaitingOnStoragesCallback)(nsTArray<nsCOMPtr<nsIOfflineStorage> >&, void*);
73
74 public:
75 NS_DECL_ISUPPORTS
76 NS_DECL_NSIQUOTAMANAGER
77 NS_DECL_NSIOBSERVER
78
79 // Returns a non-owning reference.
80 static QuotaManager*
81 GetOrCreate();
82
83 // Returns a non-owning reference.
84 static QuotaManager*
85 Get();
86
87 // Returns an owning reference! No one should call this but the factory.
88 static QuotaManager*
89 FactoryCreate();
90
91 // Returns true if we've begun the shutdown process.
92 static bool IsShuttingDown();
93
94 void
95 InitQuotaForOrigin(PersistenceType aPersistenceType,
96 const nsACString& aGroup,
97 const nsACString& aOrigin,
98 uint64_t aLimitBytes,
99 uint64_t aUsageBytes,
100 int64_t aAccessTime);
101
102 void
103 DecreaseUsageForOrigin(PersistenceType aPersistenceType,
104 const nsACString& aGroup,
105 const nsACString& aOrigin,
106 int64_t aSize);
107
108 void
109 UpdateOriginAccessTime(PersistenceType aPersistenceType,
110 const nsACString& aGroup,
111 const nsACString& aOrigin);
112
113 void
114 RemoveQuota();
115
116 void
117 RemoveQuotaForPersistenceType(PersistenceType);
118
119 void
120 RemoveQuotaForOrigin(PersistenceType aPersistenceType,
121 const nsACString& aGroup,
122 const nsACString& aOrigin)
123 {
124 MutexAutoLock lock(mQuotaMutex);
125 LockedRemoveQuotaForOrigin(aPersistenceType, aGroup, aOrigin);
126 }
127
128 void
129 RemoveQuotaForPattern(PersistenceType aPersistenceType,
130 const nsACString& aPattern);
131
132 already_AddRefed<QuotaObject>
133 GetQuotaObject(PersistenceType aPersistenceType,
134 const nsACString& aGroup,
135 const nsACString& aOrigin,
136 nsIFile* aFile);
137
138 already_AddRefed<QuotaObject>
139 GetQuotaObject(PersistenceType aPersistenceType,
140 const nsACString& aGroup,
141 const nsACString& aOrigin,
142 const nsAString& aPath);
143
144 // Set the Window that the current thread is doing operations for.
145 // The caller is responsible for ensuring that aWindow is held alive.
146 static void
147 SetCurrentWindow(nsPIDOMWindow* aWindow)
148 {
149 QuotaManager* quotaManager = Get();
150 NS_ASSERTION(quotaManager, "Must have a manager here!");
151
152 quotaManager->SetCurrentWindowInternal(aWindow);
153 }
154
155 static void
156 CancelPromptsForWindow(nsPIDOMWindow* aWindow)
157 {
158 NS_ASSERTION(aWindow, "Passed null window!");
159
160 QuotaManager* quotaManager = Get();
161 NS_ASSERTION(quotaManager, "Must have a manager here!");
162
163 quotaManager->CancelPromptsForWindowInternal(aWindow);
164 }
165
166 // Called when a storage is created.
167 bool
168 RegisterStorage(nsIOfflineStorage* aStorage);
169
170 // Called when a storage is being unlinked or destroyed.
171 void
172 UnregisterStorage(nsIOfflineStorage* aStorage);
173
174 // Called when a storage has been closed.
175 void
176 OnStorageClosed(nsIOfflineStorage* aStorage);
177
178 // Called when a window is being purged from the bfcache or the user leaves
179 // a page which isn't going into the bfcache. Forces any live storage
180 // objects to close themselves and aborts any running transactions.
181 void
182 AbortCloseStoragesForWindow(nsPIDOMWindow* aWindow);
183
184 // Used to check if there are running transactions in a given window.
185 bool
186 HasOpenTransactions(nsPIDOMWindow* aWindow);
187
188 // Waits for storages to be cleared and for version change transactions to
189 // complete before dispatching the given runnable.
190 nsresult
191 WaitForOpenAllowed(const OriginOrPatternString& aOriginOrPattern,
192 Nullable<PersistenceType> aPersistenceType,
193 const nsACString& aId, nsIRunnable* aRunnable);
194
195 // Acquire exclusive access to the storage given (waits for all others to
196 // close). If storages need to close first, the callback will be invoked
197 // with an array of said storages.
198 nsresult
199 AcquireExclusiveAccess(nsIOfflineStorage* aStorage,
200 const nsACString& aOrigin,
201 Nullable<PersistenceType> aPersistenceType,
202 AcquireListener* aListener,
203 WaitingOnStoragesCallback aCallback,
204 void* aClosure)
205 {
206 NS_ASSERTION(aStorage, "Need a storage here!");
207 return AcquireExclusiveAccess(aOrigin, aPersistenceType, aStorage,
208 aListener, aCallback, aClosure);
209 }
210
211 nsresult
212 AcquireExclusiveAccess(const nsACString& aOrigin,
213 Nullable<PersistenceType> aPersistenceType,
214 AcquireListener* aListener,
215 WaitingOnStoragesCallback aCallback,
216 void* aClosure)
217 {
218 return AcquireExclusiveAccess(aOrigin, aPersistenceType, nullptr,
219 aListener, aCallback, aClosure);
220 }
221
222 void
223 AllowNextSynchronizedOp(const OriginOrPatternString& aOriginOrPattern,
224 Nullable<PersistenceType> aPersistenceType,
225 const nsACString& aId);
226
227 bool
228 IsClearOriginPending(const nsACString& aPattern,
229 Nullable<PersistenceType> aPersistenceType)
230 {
231 return !!FindSynchronizedOp(aPattern, aPersistenceType, EmptyCString());
232 }
233
234 nsresult
235 GetDirectoryForOrigin(PersistenceType aPersistenceType,
236 const nsACString& aASCIIOrigin,
237 nsIFile** aDirectory) const;
238
239 nsresult
240 EnsureOriginIsInitialized(PersistenceType aPersistenceType,
241 const nsACString& aGroup,
242 const nsACString& aOrigin,
243 bool aTrackQuota,
244 nsIFile** aDirectory);
245
246 void
247 OriginClearCompleted(PersistenceType aPersistenceType,
248 const OriginOrPatternString& aOriginOrPattern);
249
250 void
251 ResetOrClearCompleted();
252
253 void
254 AssertCurrentThreadOwnsQuotaMutex()
255 {
256 mQuotaMutex.AssertCurrentThreadOwns();
257 }
258
259 nsIThread*
260 IOThread()
261 {
262 NS_ASSERTION(mIOThread, "This should never be null!");
263 return mIOThread;
264 }
265
266 already_AddRefed<Client>
267 GetClient(Client::Type aClientType);
268
269 const nsString&
270 GetStoragePath(PersistenceType aPersistenceType) const
271 {
272 if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
273 return mPersistentStoragePath;
274 }
275
276 NS_ASSERTION(aPersistenceType == PERSISTENCE_TYPE_TEMPORARY, "Huh?");
277
278 return mTemporaryStoragePath;
279 }
280
281 uint64_t
282 GetGroupLimit() const;
283
284 static uint32_t
285 GetStorageQuotaMB();
286
287 static void
288 GetStorageId(PersistenceType aPersistenceType,
289 const nsACString& aOrigin,
290 Client::Type aClientType,
291 const nsAString& aName,
292 nsACString& aDatabaseId);
293
294 static nsresult
295 GetInfoFromURI(nsIURI* aURI,
296 uint32_t aAppId,
297 bool aInMozBrowser,
298 nsACString* aGroup,
299 nsACString* aASCIIOrigin,
300 StoragePrivilege* aPrivilege,
301 PersistenceType* aDefaultPersistenceType);
302
303 static nsresult
304 GetInfoFromPrincipal(nsIPrincipal* aPrincipal,
305 nsACString* aGroup,
306 nsACString* aASCIIOrigin,
307 StoragePrivilege* aPrivilege,
308 PersistenceType* aDefaultPersistenceType);
309
310 static nsresult
311 GetInfoFromWindow(nsPIDOMWindow* aWindow,
312 nsACString* aGroup,
313 nsACString* aASCIIOrigin,
314 StoragePrivilege* aPrivilege,
315 PersistenceType* aDefaultPersistenceType);
316
317 static void
318 GetInfoForChrome(nsACString* aGroup,
319 nsACString* aASCIIOrigin,
320 StoragePrivilege* aPrivilege,
321 PersistenceType* aDefaultPersistenceType);
322
323 static void
324 GetOriginPatternString(uint32_t aAppId, bool aBrowserOnly,
325 const nsACString& aOrigin, nsAutoCString& _retval)
326 {
327 return GetOriginPatternString(aAppId,
328 aBrowserOnly ? MozBrowser : NotMozBrowser,
329 aOrigin, _retval);
330 }
331
332 static void
333 GetOriginPatternStringMaybeIgnoreBrowser(uint32_t aAppId, bool aBrowserOnly,
334 nsAutoCString& _retval)
335 {
336 return GetOriginPatternString(aAppId,
337 aBrowserOnly ? MozBrowser : IgnoreMozBrowser,
338 EmptyCString(), _retval);
339 }
340
341 private:
342 QuotaManager();
343
344 virtual ~QuotaManager();
345
346 nsresult
347 Init();
348
349 void
350 SetCurrentWindowInternal(nsPIDOMWindow* aWindow);
351
352 void
353 CancelPromptsForWindowInternal(nsPIDOMWindow* aWindow);
354
355 // Determine if the quota is lifted for the Window the current thread is
356 // using.
357 bool
358 LockedQuotaIsLifted();
359
360 uint64_t
361 LockedCollectOriginsForEviction(uint64_t aMinSizeToBeFreed,
362 nsTArray<OriginInfo*>& aOriginInfos);
363
364 void
365 LockedRemoveQuotaForOrigin(PersistenceType aPersistenceType,
366 const nsACString& aGroup,
367 const nsACString& aOrigin);
368
369 nsresult
370 AcquireExclusiveAccess(const nsACString& aOrigin,
371 Nullable<PersistenceType> aPersistenceType,
372 nsIOfflineStorage* aStorage,
373 AcquireListener* aListener,
374 WaitingOnStoragesCallback aCallback,
375 void* aClosure);
376
377 void
378 AddSynchronizedOp(const OriginOrPatternString& aOriginOrPattern,
379 Nullable<PersistenceType> aPersistenceType);
380
381 nsresult
382 RunSynchronizedOp(nsIOfflineStorage* aStorage,
383 SynchronizedOp* aOp);
384
385 SynchronizedOp*
386 FindSynchronizedOp(const nsACString& aPattern,
387 Nullable<PersistenceType> aPersistenceType,
388 const nsACString& aId);
389
390 nsresult
391 MaybeUpgradeIndexedDBDirectory();
392
393 nsresult
394 InitializeOrigin(PersistenceType aPersistenceType,
395 const nsACString& aGroup,
396 const nsACString& aOrigin,
397 bool aTrackQuota,
398 int64_t aAccessTime,
399 nsIFile* aDirectory);
400
401 nsresult
402 ClearStoragesForApp(uint32_t aAppId, bool aBrowserOnly);
403
404 void
405 CheckTemporaryStorageLimits();
406
407 // Collect inactive and the least recently used origins.
408 uint64_t
409 CollectOriginsForEviction(uint64_t aMinSizeToBeFreed,
410 nsTArray<OriginInfo*>& aOriginInfos);
411
412 void
413 DeleteTemporaryFilesForOrigin(const nsACString& aOrigin);
414
415 void
416 FinalizeOriginEviction(nsTArray<nsCString>& aOrigins);
417
418 void
419 SaveOriginAccessTime(const nsACString& aOrigin, int64_t aTimestamp);
420
421 void
422 ReleaseIOThreadObjects()
423 {
424 AssertIsOnIOThread();
425
426 for (uint32_t index = 0; index < Client::TYPE_MAX; index++) {
427 mClients[index]->ReleaseIOThreadObjects();
428 }
429 }
430
431 static void
432 GetOriginPatternString(uint32_t aAppId,
433 MozBrowserPatternFlag aBrowserFlag,
434 const nsACString& aOrigin,
435 nsAutoCString& _retval);
436
437 static PLDHashOperator
438 RemoveQuotaForPersistenceTypeCallback(const nsACString& aKey,
439 nsAutoPtr<GroupInfoPair>& aValue,
440 void* aUserArg);
441
442 static PLDHashOperator
443 RemoveQuotaCallback(const nsACString& aKey,
444 nsAutoPtr<GroupInfoPair>& aValue,
445 void* aUserArg);
446
447 static PLDHashOperator
448 RemoveQuotaForPatternCallback(const nsACString& aKey,
449 nsAutoPtr<GroupInfoPair>& aValue,
450 void* aUserArg);
451
452 static PLDHashOperator
453 GetOriginsExceedingGroupLimit(const nsACString& aKey,
454 GroupInfoPair* aValue,
455 void* aUserArg);
456
457 static PLDHashOperator
458 GetAllTemporaryStorageOrigins(const nsACString& aKey,
459 GroupInfoPair* aValue,
460 void* aUserArg);
461
462 static PLDHashOperator
463 AddTemporaryStorageOrigins(const nsACString& aKey,
464 ArrayCluster<nsIOfflineStorage*>* aValue,
465 void* aUserArg);
466
467 static PLDHashOperator
468 GetInactiveTemporaryStorageOrigins(const nsACString& aKey,
469 GroupInfoPair* aValue,
470 void* aUserArg);
471
472 // TLS storage index for the current thread's window.
473 unsigned int mCurrentWindowIndex;
474
475 mozilla::Mutex mQuotaMutex;
476
477 nsClassHashtable<nsCStringHashKey, GroupInfoPair> mGroupInfoPairs;
478
479 // A map of Windows to the corresponding quota helper.
480 nsRefPtrHashtable<nsPtrHashKey<nsPIDOMWindow>,
481 CheckQuotaHelper> mCheckQuotaHelpers;
482
483 // Maintains a list of live storages per origin.
484 nsClassHashtable<nsCStringHashKey,
485 ArrayCluster<nsIOfflineStorage*> > mLiveStorages;
486
487 // Maintains a list of synchronized operatons that are in progress or queued.
488 nsAutoTArray<nsAutoPtr<SynchronizedOp>, 5> mSynchronizedOps;
489
490 // Thread on which IO is performed.
491 nsCOMPtr<nsIThread> mIOThread;
492
493 // A timer that gets activated at shutdown to ensure we close all storages.
494 nsCOMPtr<nsITimer> mShutdownTimer;
495
496 // A list of all successfully initialized origins. This list isn't protected
497 // by any mutex but it is only ever touched on the IO thread.
498 nsTArray<nsCString> mInitializedOrigins;
499
500 nsAutoTArray<nsRefPtr<Client>, Client::TYPE_MAX> mClients;
501
502 nsString mIndexedDBPath;
503 nsString mPersistentStoragePath;
504 nsString mTemporaryStoragePath;
505
506 uint64_t mTemporaryStorageLimit;
507 uint64_t mTemporaryStorageUsage;
508 bool mTemporaryStorageInitialized;
509
510 bool mStorageAreaInitialized;
511 };
512
513 class AutoEnterWindow
514 {
515 public:
516 AutoEnterWindow(nsPIDOMWindow* aWindow)
517 {
518 QuotaManager::SetCurrentWindow(aWindow);
519 }
520
521 ~AutoEnterWindow()
522 {
523 QuotaManager::SetCurrentWindow(nullptr);
524 }
525 };
526
527 END_QUOTA_NAMESPACE
528
529 #endif /* mozilla_dom_quota_quotamanager_h__ */

mercurial