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 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_cache_QuotaClientImpl_h 8 #define mozilla_dom_cache_QuotaClientImpl_h 9 10 #include "mozilla/dom/cache/QuotaClient.h" 11 #include "mozilla/dom/cache/FileUtils.h" 12 13 namespace mozilla { 14 namespace dom { 15 namespace cache { 16 17 class CacheQuotaClient final : public quota::Client { 18 static CacheQuotaClient* sInstance; 19 20 public: 21 using PersistenceType = quota::PersistenceType; 22 using UsageInfo = quota::UsageInfo; 23 24 CacheQuotaClient(); 25 26 static CacheQuotaClient* Get(); 27 28 virtual Type GetType() override; 29 virtual nsresult InitOrigin(PersistenceType aPersistenceType, 30 const nsACString& aGroup, 31 const nsACString& aOrigin, 32 const AtomicBool& aCanceled, 33 UsageInfo* aUsageInfo) override; 34 35 virtual nsresult GetUsageForOrigin(PersistenceType aPersistenceType, 36 const nsACString& aGroup, 37 const nsACString& aOrigin, 38 const AtomicBool& aCanceled, 39 UsageInfo* aUsageInfo) override; 40 41 virtual void OnOriginClearCompleted(PersistenceType aPersistenceType, 42 const nsACString& aOrigin) override; 43 44 virtual void ReleaseIOThreadObjects() override; 45 46 virtual void AbortOperations(const nsACString& aOrigin) override; 47 48 virtual void AbortOperationsForProcess( 49 ContentParentId aContentParentId) override; 50 51 virtual void StartIdleMaintenance() override; 52 53 virtual void StopIdleMaintenance() override; 54 55 virtual void ShutdownWorkThreads() override; 56 57 nsresult UpgradeStorageFrom2_0To2_1(nsIFile* aDirectory) override; 58 59 template <typename Callable> MaybeUpdatePaddingFileInternal(nsIFile * aBaseDir,mozIStorageConnection * aConn,const int64_t aIncreaseSize,const int64_t aDecreaseSize,Callable aCommitHook)60 nsresult MaybeUpdatePaddingFileInternal(nsIFile* aBaseDir, 61 mozIStorageConnection* aConn, 62 const int64_t aIncreaseSize, 63 const int64_t aDecreaseSize, 64 Callable aCommitHook) { 65 MOZ_ASSERT(!NS_IsMainThread()); 66 MOZ_DIAGNOSTIC_ASSERT(aBaseDir); 67 MOZ_DIAGNOSTIC_ASSERT(aConn); 68 MOZ_DIAGNOSTIC_ASSERT(aIncreaseSize >= 0); 69 MOZ_DIAGNOSTIC_ASSERT(aDecreaseSize >= 0); 70 71 nsresult rv; 72 73 // Temporary should be removed at the end of each action. If not, it means 74 // the failure happened. 75 bool temporaryPaddingFileExist = 76 mozilla::dom::cache::DirectoryPaddingFileExists( 77 aBaseDir, DirPaddingFile::TMP_FILE); 78 79 if (aIncreaseSize == aDecreaseSize && !temporaryPaddingFileExist) { 80 // Early return here, since most cache actions won't modify padding size. 81 rv = aCommitHook(); 82 Unused << NS_WARN_IF(NS_FAILED(rv)); 83 return rv; 84 } 85 86 { 87 MutexAutoLock lock(mDirPaddingFileMutex); 88 rv = mozilla::dom::cache::LockedUpdateDirectoryPaddingFile( 89 aBaseDir, aConn, aIncreaseSize, aDecreaseSize, 90 temporaryPaddingFileExist); 91 if (NS_WARN_IF(NS_FAILED(rv))) { 92 // Don't delete the temporary padding file here to force the next action 93 // recalculate the padding size. 94 return rv; 95 } 96 97 rv = aCommitHook(); 98 if (NS_WARN_IF(NS_FAILED(rv))) { 99 // Don't delete the temporary padding file here to force the next action 100 // recalculate the padding size. 101 return rv; 102 } 103 104 rv = mozilla::dom::cache::LockedDirectoryPaddingFinalizeWrite(aBaseDir); 105 if (NS_WARN_IF(NS_FAILED(rv))) { 106 // Force restore file next time. 107 Unused << mozilla::dom::cache::LockedDirectoryPaddingDeleteFile( 108 aBaseDir, DirPaddingFile::FILE); 109 110 // Ensure that we are able to force the padding file to be restored. 111 MOZ_ASSERT(mozilla::dom::cache::DirectoryPaddingFileExists( 112 aBaseDir, DirPaddingFile::TMP_FILE)); 113 114 // Since both the body file and header have been stored in the 115 // file-system, just make the action be resolve and let the padding file 116 // be restored in the next action. 117 rv = NS_OK; 118 } 119 } 120 121 return rv; 122 } 123 124 nsresult RestorePaddingFileInternal(nsIFile* aBaseDir, 125 mozIStorageConnection* aConn); 126 127 nsresult WipePaddingFileInternal(const QuotaInfo& aQuotaInfo, 128 nsIFile* aBaseDir); 129 130 private: 131 ~CacheQuotaClient(); 132 133 nsresult GetUsageForOriginInternal(PersistenceType aPersistenceType, 134 const nsACString& aGroup, 135 const nsACString& aOrigin, 136 const AtomicBool& aCanceled, 137 bool aInitializing, UsageInfo* aUsageInfo); 138 139 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheQuotaClient, override) 140 141 // Mutex lock to protect directroy padding files. It should only be acquired 142 // in DOM Cache IO threads and Quota IO thread. 143 mozilla::Mutex mDirPaddingFileMutex; 144 }; 145 146 } // namespace cache 147 } // namespace dom 148 } // namespace mozilla 149 150 #endif // mozilla_dom_cache_QuotaClientImpl_h 151