LCOV - code coverage report
Current view: top level - dom/quota - QuotaManager.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 59 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 23 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=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 "mozilla/dom/Nullable.h"
      13             : #include "mozilla/dom/ipc/IdType.h"
      14             : #include "mozilla/Mutex.h"
      15             : 
      16             : #include "nsClassHashtable.h"
      17             : #include "nsRefPtrHashtable.h"
      18             : 
      19             : #include "Client.h"
      20             : #include "PersistenceType.h"
      21             : 
      22             : #include "prenv.h"
      23             : 
      24             : #define QUOTA_MANAGER_CONTRACTID "@mozilla.org/dom/quota/manager;1"
      25             : 
      26             : class mozIStorageConnection;
      27             : class nsIEventTarget;
      28             : class nsIPrincipal;
      29             : class nsIThread;
      30             : class nsITimer;
      31             : class nsIURI;
      32             : class nsPIDOMWindowOuter;
      33             : class nsIRunnable;
      34             : 
      35             : BEGIN_QUOTA_NAMESPACE
      36             : 
      37             : class DirectoryLockImpl;
      38             : class GroupInfo;
      39             : class GroupInfoPair;
      40             : class OriginInfo;
      41             : class OriginScope;
      42             : class QuotaObject;
      43             : 
      44           0 : class NS_NO_VTABLE RefCountedObject
      45             : {
      46             : public:
      47             :   NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
      48             : };
      49             : 
      50             : class DirectoryLock
      51             :   : public RefCountedObject
      52             : {
      53             :   friend class DirectoryLockImpl;
      54             : 
      55             : private:
      56           0 :   DirectoryLock()
      57           0 :   { }
      58             : 
      59           0 :   ~DirectoryLock()
      60           0 :   { }
      61             : };
      62             : 
      63           0 : class NS_NO_VTABLE OpenDirectoryListener
      64             :   : public RefCountedObject
      65             : {
      66             : public:
      67             :   virtual void
      68             :   DirectoryLockAcquired(DirectoryLock* aLock) = 0;
      69             : 
      70             :   virtual void
      71             :   DirectoryLockFailed() = 0;
      72             : 
      73             : protected:
      74           0 :   virtual ~OpenDirectoryListener()
      75           0 :   { }
      76             : };
      77             : 
      78           0 : struct OriginParams
      79             : {
      80           0 :   OriginParams(PersistenceType aPersistenceType,
      81             :                const nsACString& aOrigin)
      82           0 :   : mOrigin(aOrigin)
      83           0 :   , mPersistenceType(aPersistenceType)
      84           0 :   { }
      85             : 
      86             :   nsCString mOrigin;
      87             :   PersistenceType mPersistenceType;
      88             : };
      89             : 
      90             : class QuotaManager final
      91             :   : public BackgroundThreadObject
      92             : {
      93             :   friend class DirectoryLockImpl;
      94             :   friend class GroupInfo;
      95             :   friend class OriginInfo;
      96             :   friend class QuotaObject;
      97             : 
      98             :   typedef nsClassHashtable<nsCStringHashKey,
      99             :                            nsTArray<DirectoryLockImpl*>> DirectoryLockTable;
     100             : 
     101             : public:
     102             :   class CreateRunnable;
     103             : 
     104             : private:
     105             :   class ShutdownRunnable;
     106             :   class ShutdownObserver;
     107             : 
     108             : public:
     109           0 :   NS_INLINE_DECL_REFCOUNTING(QuotaManager)
     110             : 
     111           0 :   static bool IsRunningXPCShellTests()
     112             :   {
     113           0 :     static bool kRunningXPCShellTests = !!PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR");
     114           0 :     return kRunningXPCShellTests;
     115             :   }
     116             : 
     117             :   static const char kReplaceChars[];
     118             : 
     119             :   static void
     120             :   GetOrCreate(nsIRunnable* aCallback);
     121             : 
     122             :   // Returns a non-owning reference.
     123             :   static QuotaManager*
     124             :   Get();
     125             : 
     126             :   // Returns true if we've begun the shutdown process.
     127             :   static bool IsShuttingDown();
     128             : 
     129             :   bool
     130           0 :   IsOriginInitialized(const nsACString& aOrigin) const
     131             :   {
     132           0 :     AssertIsOnIOThread();
     133             : 
     134           0 :     return mInitializedOrigins.Contains(aOrigin);
     135             :   }
     136             : 
     137             :   bool
     138           0 :   IsTemporaryStorageInitialized() const
     139             :   {
     140           0 :     AssertIsOnIOThread();
     141             : 
     142           0 :     return mTemporaryStorageInitialized;
     143             :   }
     144             : 
     145             :   void
     146             :   InitQuotaForOrigin(PersistenceType aPersistenceType,
     147             :                      const nsACString& aGroup,
     148             :                      const nsACString& aOrigin,
     149             :                      uint64_t aUsageBytes,
     150             :                      int64_t aAccessTime,
     151             :                      bool aPersisted);
     152             : 
     153             :   void
     154             :   DecreaseUsageForOrigin(PersistenceType aPersistenceType,
     155             :                          const nsACString& aGroup,
     156             :                          const nsACString& aOrigin,
     157             :                          int64_t aSize);
     158             : 
     159             :   void
     160             :   UpdateOriginAccessTime(PersistenceType aPersistenceType,
     161             :                          const nsACString& aGroup,
     162             :                          const nsACString& aOrigin);
     163             : 
     164             :   void
     165             :   RemoveQuota();
     166             : 
     167             :   void
     168           0 :   RemoveQuotaForOrigin(PersistenceType aPersistenceType,
     169             :                        const nsACString& aGroup,
     170             :                        const nsACString& aOrigin)
     171             :   {
     172           0 :     MutexAutoLock lock(mQuotaMutex);
     173           0 :     LockedRemoveQuotaForOrigin(aPersistenceType, aGroup, aOrigin);
     174           0 :   }
     175             : 
     176             :   already_AddRefed<QuotaObject>
     177             :   GetQuotaObject(PersistenceType aPersistenceType,
     178             :                  const nsACString& aGroup,
     179             :                  const nsACString& aOrigin,
     180             :                  nsIFile* aFile);
     181             : 
     182             :   already_AddRefed<QuotaObject>
     183             :   GetQuotaObject(PersistenceType aPersistenceType,
     184             :                  const nsACString& aGroup,
     185             :                  const nsACString& aOrigin,
     186             :                  const nsAString& aPath);
     187             : 
     188             :   Nullable<bool>
     189             :   OriginPersisted(const nsACString& aGroup,
     190             :                   const nsACString& aOrigin);
     191             : 
     192             :   void
     193             :   PersistOrigin(const nsACString& aGroup,
     194             :                 const nsACString& aOrigin);
     195             : 
     196             :   // Called when a process is being shot down. Aborts any running operations
     197             :   // for the given process.
     198             :   void
     199             :   AbortOperationsForProcess(ContentParentId aContentParentId);
     200             : 
     201             :   nsresult
     202             :   GetDirectoryForOrigin(PersistenceType aPersistenceType,
     203             :                         const nsACString& aASCIIOrigin,
     204             :                         nsIFile** aDirectory) const;
     205             : 
     206             :   nsresult
     207             :   RestoreDirectoryMetadata2(nsIFile* aDirectory, bool aPersistent);
     208             : 
     209             :   nsresult
     210             :   GetDirectoryMetadata2(nsIFile* aDirectory,
     211             :                         int64_t* aTimestamp,
     212             :                         bool* aPersisted,
     213             :                         nsACString& aSuffix,
     214             :                         nsACString& aGroup,
     215             :                         nsACString& aOrigin);
     216             : 
     217             :   nsresult
     218             :   GetDirectoryMetadata2WithRestore(nsIFile* aDirectory,
     219             :                                    bool aPersistent,
     220             :                                    int64_t* aTimestamp,
     221             :                                    bool* aPersisted,
     222             :                                    nsACString& aSuffix,
     223             :                                    nsACString& aGroup,
     224             :                                    nsACString& aOrigin);
     225             : 
     226             :   nsresult
     227             :   GetDirectoryMetadata2(nsIFile* aDirectory,
     228             :                         int64_t* aTimestamp,
     229             :                         bool* aPersisted);
     230             : 
     231             :   nsresult
     232             :   GetDirectoryMetadata2WithRestore(nsIFile* aDirectory,
     233             :                                    bool aPersistent,
     234             :                                    int64_t* aTimestamp,
     235             :                                    bool* aPersisted);
     236             : 
     237             :   // This is the main entry point into the QuotaManager API.
     238             :   // Any storage API implementation (quota client) that participates in
     239             :   // centralized quota and storage handling should call this method to get
     240             :   // a directory lock which will protect client's files from being deleted
     241             :   // while they are still in use.
     242             :   // After a lock is acquired, client is notified via the open listener's
     243             :   // method DirectoryLockAcquired. If the lock couldn't be acquired, client
     244             :   // gets DirectoryLockFailed notification.
     245             :   // A lock is a reference counted object and at the time DirectoryLockAcquired
     246             :   // is called, quota manager holds just one strong reference to it which is
     247             :   // then immediatelly cleared by quota manager. So it's up to client to add
     248             :   // a new reference in order to keep the lock alive.
     249             :   // Unlocking is simply done by dropping all references to the lock object.
     250             :   // In other words, protection which the lock represents dies with the lock
     251             :   // object itself.
     252             :   void
     253             :   OpenDirectory(PersistenceType aPersistenceType,
     254             :                 const nsACString& aGroup,
     255             :                 const nsACString& aOrigin,
     256             :                 Client::Type aClientType,
     257             :                 bool aExclusive,
     258             :                 OpenDirectoryListener* aOpenListener);
     259             : 
     260             :   // XXX RemoveMe once bug 1170279 gets fixed.
     261             :   void
     262             :   OpenDirectoryInternal(const Nullable<PersistenceType>& aPersistenceType,
     263             :                         const OriginScope& aOriginScope,
     264             :                         const Nullable<Client::Type>& aClientType,
     265             :                         bool aExclusive,
     266             :                         OpenDirectoryListener* aOpenListener);
     267             : 
     268             :   // Collect inactive and the least recently used origins.
     269             :   uint64_t
     270             :   CollectOriginsForEviction(uint64_t aMinSizeToBeFreed,
     271             :                             nsTArray<RefPtr<DirectoryLockImpl>>& aLocks);
     272             : 
     273             :   void
     274             :   AssertStorageIsInitialized() const
     275             : #ifdef DEBUG
     276             :   ;
     277             : #else
     278             :   { }
     279             : #endif
     280             : 
     281             :   nsresult
     282             :   EnsureStorageIsInitialized();
     283             : 
     284             :   nsresult
     285             :   EnsureOriginIsInitialized(PersistenceType aPersistenceType,
     286             :                             const nsACString& aSuffix,
     287             :                             const nsACString& aGroup,
     288             :                             const nsACString& aOrigin,
     289             :                             nsIFile** aDirectory);
     290             : 
     291             :   nsresult
     292             :   EnsureOriginIsInitializedInternal(PersistenceType aPersistenceType,
     293             :                                     const nsACString& aSuffix,
     294             :                                     const nsACString& aGroup,
     295             :                                     const nsACString& aOrigin,
     296             :                                     nsIFile** aDirectory,
     297             :                                     bool* aCreated);
     298             : 
     299             :   void
     300             :   OriginClearCompleted(PersistenceType aPersistenceType,
     301             :                        const nsACString& aOrigin);
     302             : 
     303             :   void
     304             :   ResetOrClearCompleted();
     305             : 
     306             :   void
     307           0 :   StartIdleMaintenance()
     308             :   {
     309           0 :     AssertIsOnOwningThread();
     310             : 
     311           0 :     for (auto& client : mClients) {
     312           0 :       client->StartIdleMaintenance();
     313             :     }
     314           0 :   }
     315             : 
     316             :   void
     317           0 :   StopIdleMaintenance()
     318             :   {
     319           0 :     AssertIsOnOwningThread();
     320             : 
     321           0 :     for (auto& client : mClients) {
     322           0 :       client->StopIdleMaintenance();
     323             :     }
     324           0 :   }
     325             : 
     326             :   void
     327           0 :   AssertCurrentThreadOwnsQuotaMutex()
     328             :   {
     329           0 :     mQuotaMutex.AssertCurrentThreadOwns();
     330           0 :   }
     331             : 
     332             :   nsIThread*
     333           0 :   IOThread()
     334             :   {
     335           0 :     NS_ASSERTION(mIOThread, "This should never be null!");
     336           0 :     return mIOThread;
     337             :   }
     338             : 
     339             :   Client*
     340             :   GetClient(Client::Type aClientType);
     341             : 
     342             :   const nsString&
     343           0 :   GetBasePath() const
     344             :   {
     345           0 :     return mBasePath;
     346             :   }
     347             : 
     348             :   const nsString&
     349           0 :   GetStoragePath() const
     350             :   {
     351           0 :     return mStoragePath;
     352             :   }
     353             : 
     354             :   const nsString&
     355           0 :   GetStoragePath(PersistenceType aPersistenceType) const
     356             :   {
     357           0 :     if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
     358           0 :       return mPermanentStoragePath;
     359             :     }
     360             : 
     361           0 :     if (aPersistenceType == PERSISTENCE_TYPE_TEMPORARY) {
     362           0 :       return mTemporaryStoragePath;
     363             :     }
     364             : 
     365           0 :     MOZ_ASSERT(aPersistenceType == PERSISTENCE_TYPE_DEFAULT);
     366             : 
     367           0 :     return mDefaultStoragePath;
     368             :   }
     369             : 
     370             :   uint64_t
     371             :   GetGroupLimit() const;
     372             : 
     373             :   void
     374             :   GetGroupUsageAndLimit(const nsACString& aGroup,
     375             :                         UsageInfo* aUsageInfo);
     376             : 
     377             :   static void
     378             :   GetStorageId(PersistenceType aPersistenceType,
     379             :                const nsACString& aOrigin,
     380             :                Client::Type aClientType,
     381             :                nsACString& aDatabaseId);
     382             : 
     383             :   static nsresult
     384             :   GetInfoFromPrincipal(nsIPrincipal* aPrincipal,
     385             :                        nsACString* aSuffix,
     386             :                        nsACString* aGroup,
     387             :                        nsACString* aOrigin);
     388             : 
     389             :   static nsresult
     390             :   GetInfoFromWindow(nsPIDOMWindowOuter* aWindow,
     391             :                     nsACString* aSuffix,
     392             :                     nsACString* aGroup,
     393             :                     nsACString* aOrigin);
     394             : 
     395             :   static void
     396             :   GetInfoForChrome(nsACString* aSuffix,
     397             :                    nsACString* aGroup,
     398             :                    nsACString* aOrigin);
     399             : 
     400             :   static bool
     401             :   IsOriginInternal(const nsACString& aOrigin);
     402             : 
     403             :   static void
     404             :   ChromeOrigin(nsACString& aOrigin);
     405             : 
     406             :   static bool
     407             :   AreOriginsEqualOnDisk(nsACString& aOrigin1,
     408             :                         nsACString& aOrigin2);
     409             : 
     410             : private:
     411             :   QuotaManager();
     412             : 
     413             :   virtual ~QuotaManager();
     414             : 
     415             :   nsresult
     416             :   Init(const nsAString& aBaseDirPath);
     417             : 
     418             :   void
     419             :   Shutdown();
     420             : 
     421             :   already_AddRefed<DirectoryLockImpl>
     422             :   CreateDirectoryLock(const Nullable<PersistenceType>& aPersistenceType,
     423             :                       const nsACString& aGroup,
     424             :                       const OriginScope& aOriginScope,
     425             :                       const Nullable<Client::Type>& aClientType,
     426             :                       bool aExclusive,
     427             :                       bool aInternal,
     428             :                       OpenDirectoryListener* aOpenListener);
     429             : 
     430             :   already_AddRefed<DirectoryLockImpl>
     431             :   CreateDirectoryLockForEviction(PersistenceType aPersistenceType,
     432             :                                  const nsACString& aGroup,
     433             :                                  const nsACString& aOrigin);
     434             : 
     435             :   void
     436             :   RegisterDirectoryLock(DirectoryLockImpl* aLock);
     437             : 
     438             :   void
     439             :   UnregisterDirectoryLock(DirectoryLockImpl* aLock);
     440             : 
     441             :   void
     442             :   RemovePendingDirectoryLock(DirectoryLockImpl* aLock);
     443             : 
     444             :   uint64_t
     445             :   LockedCollectOriginsForEviction(
     446             :                                  uint64_t aMinSizeToBeFreed,
     447             :                                  nsTArray<RefPtr<DirectoryLockImpl>>& aLocks);
     448             : 
     449             :   void
     450             :   LockedRemoveQuotaForOrigin(PersistenceType aPersistenceType,
     451             :                              const nsACString& aGroup,
     452             :                              const nsACString& aOrigin);
     453             : 
     454             :   already_AddRefed<OriginInfo>
     455             :   LockedGetOriginInfo(PersistenceType aPersistenceType,
     456             :                       const nsACString& aGroup,
     457             :                       const nsACString& aOrigin);
     458             : 
     459             :   nsresult
     460             :   MaybeUpgradeIndexedDBDirectory();
     461             : 
     462             :   nsresult
     463             :   MaybeUpgradePersistentStorageDirectory();
     464             : 
     465             :   nsresult
     466             :   MaybeRemoveOldDirectories();
     467             : 
     468             :   nsresult
     469             :   UpgradeStorageFrom0_0To1_0(mozIStorageConnection* aConnection);
     470             : 
     471             :   nsresult
     472             :   UpgradeStorageFrom1_0To2_0(mozIStorageConnection* aConnection);
     473             : 
     474             :   nsresult
     475             :   InitializeRepository(PersistenceType aPersistenceType);
     476             : 
     477             :   nsresult
     478             :   InitializeOrigin(PersistenceType aPersistenceType,
     479             :                    const nsACString& aGroup,
     480             :                    const nsACString& aOrigin,
     481             :                    int64_t aAccessTime,
     482             :                    bool aPersisted,
     483             :                    nsIFile* aDirectory);
     484             : 
     485             :   void
     486             :   CheckTemporaryStorageLimits();
     487             : 
     488             :   void
     489             :   DeleteFilesForOrigin(PersistenceType aPersistenceType,
     490             :                        const nsACString& aOrigin);
     491             : 
     492             :   void
     493             :   FinalizeOriginEviction(nsTArray<RefPtr<DirectoryLockImpl>>& aLocks);
     494             : 
     495             :   void
     496           0 :   ReleaseIOThreadObjects()
     497             :   {
     498           0 :     AssertIsOnIOThread();
     499             : 
     500           0 :     for (uint32_t index = 0; index < Client::TYPE_MAX; index++) {
     501           0 :       mClients[index]->ReleaseIOThreadObjects();
     502             :     }
     503           0 :   }
     504             : 
     505             :   DirectoryLockTable&
     506             :   GetDirectoryLockTable(PersistenceType aPersistenceType);
     507             : 
     508             :   static void
     509             :   ShutdownTimerCallback(nsITimer* aTimer, void* aClosure);
     510             : 
     511             :   mozilla::Mutex mQuotaMutex;
     512             : 
     513             :   nsClassHashtable<nsCStringHashKey, GroupInfoPair> mGroupInfoPairs;
     514             : 
     515             :   // Maintains a list of directory locks that are queued.
     516             :   nsTArray<RefPtr<DirectoryLockImpl>> mPendingDirectoryLocks;
     517             : 
     518             :   // Maintains a list of directory locks that are acquired or queued.
     519             :   nsTArray<DirectoryLockImpl*> mDirectoryLocks;
     520             : 
     521             :   // Directory lock tables that are used to update origin access time.
     522             :   DirectoryLockTable mTemporaryDirectoryLockTable;
     523             :   DirectoryLockTable mDefaultDirectoryLockTable;
     524             : 
     525             :   // Thread on which IO is performed.
     526             :   nsCOMPtr<nsIThread> mIOThread;
     527             : 
     528             :   // A timer that gets activated at shutdown to ensure we close all storages.
     529             :   nsCOMPtr<nsITimer> mShutdownTimer;
     530             : 
     531             :   // A list of all successfully initialized origins. This list isn't protected
     532             :   // by any mutex but it is only ever touched on the IO thread.
     533             :   nsTArray<nsCString> mInitializedOrigins;
     534             : 
     535             :   // This array is populated at initialization time and then never modified, so
     536             :   // it can be iterated on any thread.
     537             :   AutoTArray<RefPtr<Client>, Client::TYPE_MAX> mClients;
     538             : 
     539             :   nsString mBasePath;
     540             :   nsString mIndexedDBPath;
     541             :   nsString mStoragePath;
     542             :   nsString mPermanentStoragePath;
     543             :   nsString mTemporaryStoragePath;
     544             :   nsString mDefaultStoragePath;
     545             : 
     546             :   uint64_t mTemporaryStorageLimit;
     547             :   uint64_t mTemporaryStorageUsage;
     548             :   bool mTemporaryStorageInitialized;
     549             : 
     550             :   bool mStorageInitialized;
     551             : };
     552             : 
     553             : END_QUOTA_NAMESPACE
     554             : 
     555             : #endif /* mozilla_dom_quota_quotamanager_h__ */

Generated by: LCOV version 1.13