Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | #ifndef CacheFile__h__ |
michael@0 | 6 | #define CacheFile__h__ |
michael@0 | 7 | |
michael@0 | 8 | #include "CacheFileChunk.h" |
michael@0 | 9 | #include "CacheFileIOManager.h" |
michael@0 | 10 | #include "CacheFileMetadata.h" |
michael@0 | 11 | #include "nsRefPtrHashtable.h" |
michael@0 | 12 | #include "nsClassHashtable.h" |
michael@0 | 13 | #include "mozilla/Mutex.h" |
michael@0 | 14 | |
michael@0 | 15 | class nsIInputStream; |
michael@0 | 16 | class nsIOutputStream; |
michael@0 | 17 | |
michael@0 | 18 | namespace mozilla { |
michael@0 | 19 | namespace net { |
michael@0 | 20 | |
michael@0 | 21 | class CacheFileInputStream; |
michael@0 | 22 | class CacheFileOutputStream; |
michael@0 | 23 | class CacheOutputCloseListener; |
michael@0 | 24 | class MetadataWriteTimer; |
michael@0 | 25 | |
michael@0 | 26 | #define CACHEFILELISTENER_IID \ |
michael@0 | 27 | { /* 95e7f284-84ba-48f9-b1fc-3a7336b4c33c */ \ |
michael@0 | 28 | 0x95e7f284, \ |
michael@0 | 29 | 0x84ba, \ |
michael@0 | 30 | 0x48f9, \ |
michael@0 | 31 | {0xb1, 0xfc, 0x3a, 0x73, 0x36, 0xb4, 0xc3, 0x3c} \ |
michael@0 | 32 | } |
michael@0 | 33 | |
michael@0 | 34 | class CacheFileListener : public nsISupports |
michael@0 | 35 | { |
michael@0 | 36 | public: |
michael@0 | 37 | NS_DECLARE_STATIC_IID_ACCESSOR(CACHEFILELISTENER_IID) |
michael@0 | 38 | |
michael@0 | 39 | NS_IMETHOD OnFileReady(nsresult aResult, bool aIsNew) = 0; |
michael@0 | 40 | NS_IMETHOD OnFileDoomed(nsresult aResult) = 0; |
michael@0 | 41 | }; |
michael@0 | 42 | |
michael@0 | 43 | NS_DEFINE_STATIC_IID_ACCESSOR(CacheFileListener, CACHEFILELISTENER_IID) |
michael@0 | 44 | |
michael@0 | 45 | |
michael@0 | 46 | class CacheFile : public CacheFileChunkListener |
michael@0 | 47 | , public CacheFileIOListener |
michael@0 | 48 | , public CacheFileMetadataListener |
michael@0 | 49 | { |
michael@0 | 50 | public: |
michael@0 | 51 | NS_DECL_THREADSAFE_ISUPPORTS |
michael@0 | 52 | |
michael@0 | 53 | CacheFile(); |
michael@0 | 54 | |
michael@0 | 55 | nsresult Init(const nsACString &aKey, |
michael@0 | 56 | bool aCreateNew, |
michael@0 | 57 | bool aMemoryOnly, |
michael@0 | 58 | bool aPriority, |
michael@0 | 59 | CacheFileListener *aCallback); |
michael@0 | 60 | |
michael@0 | 61 | NS_IMETHOD OnChunkRead(nsresult aResult, CacheFileChunk *aChunk); |
michael@0 | 62 | NS_IMETHOD OnChunkWritten(nsresult aResult, CacheFileChunk *aChunk); |
michael@0 | 63 | NS_IMETHOD OnChunkAvailable(nsresult aResult, uint32_t aChunkIdx, |
michael@0 | 64 | CacheFileChunk *aChunk); |
michael@0 | 65 | NS_IMETHOD OnChunkUpdated(CacheFileChunk *aChunk); |
michael@0 | 66 | |
michael@0 | 67 | NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult); |
michael@0 | 68 | NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, |
michael@0 | 69 | nsresult aResult); |
michael@0 | 70 | NS_IMETHOD OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult); |
michael@0 | 71 | NS_IMETHOD OnFileDoomed(CacheFileHandle *aHandle, nsresult aResult); |
michael@0 | 72 | NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult); |
michael@0 | 73 | NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult); |
michael@0 | 74 | |
michael@0 | 75 | NS_IMETHOD OnMetadataRead(nsresult aResult); |
michael@0 | 76 | NS_IMETHOD OnMetadataWritten(nsresult aResult); |
michael@0 | 77 | |
michael@0 | 78 | NS_IMETHOD OpenInputStream(nsIInputStream **_retval); |
michael@0 | 79 | NS_IMETHOD OpenOutputStream(CacheOutputCloseListener *aCloseListener, nsIOutputStream **_retval); |
michael@0 | 80 | NS_IMETHOD SetMemoryOnly(); |
michael@0 | 81 | NS_IMETHOD Doom(CacheFileListener *aCallback); |
michael@0 | 82 | |
michael@0 | 83 | nsresult ThrowMemoryCachedData(); |
michael@0 | 84 | |
michael@0 | 85 | // metadata forwarders |
michael@0 | 86 | nsresult GetElement(const char *aKey, char **_retval); |
michael@0 | 87 | nsresult SetElement(const char *aKey, const char *aValue); |
michael@0 | 88 | nsresult ElementsSize(uint32_t *_retval); |
michael@0 | 89 | nsresult SetExpirationTime(uint32_t aExpirationTime); |
michael@0 | 90 | nsresult GetExpirationTime(uint32_t *_retval); |
michael@0 | 91 | nsresult SetLastModified(uint32_t aLastModified); |
michael@0 | 92 | nsresult GetLastModified(uint32_t *_retval); |
michael@0 | 93 | nsresult SetFrecency(uint32_t aFrecency); |
michael@0 | 94 | nsresult GetFrecency(uint32_t *_retval); |
michael@0 | 95 | nsresult GetLastFetched(uint32_t *_retval); |
michael@0 | 96 | nsresult GetFetchCount(uint32_t *_retval); |
michael@0 | 97 | |
michael@0 | 98 | bool DataSize(int64_t* aSize); |
michael@0 | 99 | void Key(nsACString& aKey) { aKey = mKey; } |
michael@0 | 100 | bool IsDoomed(); |
michael@0 | 101 | bool IsWriteInProgress(); |
michael@0 | 102 | |
michael@0 | 103 | // Memory reporting |
michael@0 | 104 | size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; |
michael@0 | 105 | size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; |
michael@0 | 106 | |
michael@0 | 107 | private: |
michael@0 | 108 | friend class CacheFileIOManager; |
michael@0 | 109 | friend class CacheFileChunk; |
michael@0 | 110 | friend class CacheFileInputStream; |
michael@0 | 111 | friend class CacheFileOutputStream; |
michael@0 | 112 | friend class CacheFileAutoLock; |
michael@0 | 113 | friend class MetadataWriteTimer; |
michael@0 | 114 | |
michael@0 | 115 | virtual ~CacheFile(); |
michael@0 | 116 | |
michael@0 | 117 | void Lock(); |
michael@0 | 118 | void Unlock(); |
michael@0 | 119 | void AssertOwnsLock() const; |
michael@0 | 120 | void ReleaseOutsideLock(nsISupports *aObject); |
michael@0 | 121 | |
michael@0 | 122 | nsresult GetChunk(uint32_t aIndex, bool aWriter, |
michael@0 | 123 | CacheFileChunkListener *aCallback, |
michael@0 | 124 | CacheFileChunk **_retval); |
michael@0 | 125 | nsresult GetChunkLocked(uint32_t aIndex, bool aWriter, |
michael@0 | 126 | CacheFileChunkListener *aCallback, |
michael@0 | 127 | CacheFileChunk **_retval); |
michael@0 | 128 | nsresult RemoveChunk(CacheFileChunk *aChunk); |
michael@0 | 129 | void RemoveChunkInternal(CacheFileChunk *aChunk, bool aCacheChunk); |
michael@0 | 130 | |
michael@0 | 131 | nsresult RemoveInput(CacheFileInputStream *aInput); |
michael@0 | 132 | nsresult RemoveOutput(CacheFileOutputStream *aOutput); |
michael@0 | 133 | nsresult NotifyChunkListener(CacheFileChunkListener *aCallback, |
michael@0 | 134 | nsIEventTarget *aTarget, |
michael@0 | 135 | nsresult aResult, |
michael@0 | 136 | uint32_t aChunkIdx, |
michael@0 | 137 | CacheFileChunk *aChunk); |
michael@0 | 138 | nsresult QueueChunkListener(uint32_t aIndex, |
michael@0 | 139 | CacheFileChunkListener *aCallback); |
michael@0 | 140 | nsresult NotifyChunkListeners(uint32_t aIndex, nsresult aResult, |
michael@0 | 141 | CacheFileChunk *aChunk); |
michael@0 | 142 | bool HaveChunkListeners(uint32_t aIndex); |
michael@0 | 143 | void NotifyListenersAboutOutputRemoval(); |
michael@0 | 144 | |
michael@0 | 145 | bool IsDirty(); |
michael@0 | 146 | void WriteMetadataIfNeeded(); |
michael@0 | 147 | void WriteMetadataIfNeededLocked(bool aFireAndForget = false); |
michael@0 | 148 | void PostWriteTimer(); |
michael@0 | 149 | |
michael@0 | 150 | static PLDHashOperator WriteAllCachedChunks(const uint32_t& aIdx, |
michael@0 | 151 | nsRefPtr<CacheFileChunk>& aChunk, |
michael@0 | 152 | void* aClosure); |
michael@0 | 153 | |
michael@0 | 154 | static PLDHashOperator FailListenersIfNonExistentChunk( |
michael@0 | 155 | const uint32_t& aIdx, |
michael@0 | 156 | nsAutoPtr<mozilla::net::ChunkListeners>& aListeners, |
michael@0 | 157 | void* aClosure); |
michael@0 | 158 | |
michael@0 | 159 | static PLDHashOperator FailUpdateListeners(const uint32_t& aIdx, |
michael@0 | 160 | nsRefPtr<CacheFileChunk>& aChunk, |
michael@0 | 161 | void* aClosure); |
michael@0 | 162 | |
michael@0 | 163 | nsresult PadChunkWithZeroes(uint32_t aChunkIdx); |
michael@0 | 164 | |
michael@0 | 165 | void SetError(nsresult aStatus); |
michael@0 | 166 | |
michael@0 | 167 | nsresult InitIndexEntry(); |
michael@0 | 168 | |
michael@0 | 169 | mozilla::Mutex mLock; |
michael@0 | 170 | bool mOpeningFile; |
michael@0 | 171 | bool mReady; |
michael@0 | 172 | bool mMemoryOnly; |
michael@0 | 173 | bool mOpenAsMemoryOnly; |
michael@0 | 174 | bool mDataAccessed; |
michael@0 | 175 | bool mDataIsDirty; |
michael@0 | 176 | bool mWritingMetadata; |
michael@0 | 177 | nsresult mStatus; |
michael@0 | 178 | int64_t mDataSize; |
michael@0 | 179 | nsCString mKey; |
michael@0 | 180 | |
michael@0 | 181 | nsRefPtr<CacheFileHandle> mHandle; |
michael@0 | 182 | nsRefPtr<CacheFileMetadata> mMetadata; |
michael@0 | 183 | nsCOMPtr<CacheFileListener> mListener; |
michael@0 | 184 | nsCOMPtr<CacheFileIOListener> mDoomAfterOpenListener; |
michael@0 | 185 | |
michael@0 | 186 | nsRefPtrHashtable<nsUint32HashKey, CacheFileChunk> mChunks; |
michael@0 | 187 | nsClassHashtable<nsUint32HashKey, ChunkListeners> mChunkListeners; |
michael@0 | 188 | nsRefPtrHashtable<nsUint32HashKey, CacheFileChunk> mCachedChunks; |
michael@0 | 189 | |
michael@0 | 190 | nsTArray<CacheFileInputStream*> mInputs; |
michael@0 | 191 | CacheFileOutputStream *mOutput; |
michael@0 | 192 | |
michael@0 | 193 | nsTArray<nsISupports*> mObjsToRelease; |
michael@0 | 194 | }; |
michael@0 | 195 | |
michael@0 | 196 | class CacheFileAutoLock { |
michael@0 | 197 | public: |
michael@0 | 198 | CacheFileAutoLock(CacheFile *aFile) |
michael@0 | 199 | : mFile(aFile) |
michael@0 | 200 | , mLocked(true) |
michael@0 | 201 | { |
michael@0 | 202 | mFile->Lock(); |
michael@0 | 203 | } |
michael@0 | 204 | ~CacheFileAutoLock() |
michael@0 | 205 | { |
michael@0 | 206 | if (mLocked) |
michael@0 | 207 | mFile->Unlock(); |
michael@0 | 208 | } |
michael@0 | 209 | void Lock() |
michael@0 | 210 | { |
michael@0 | 211 | MOZ_ASSERT(!mLocked); |
michael@0 | 212 | mFile->Lock(); |
michael@0 | 213 | mLocked = true; |
michael@0 | 214 | } |
michael@0 | 215 | void Unlock() |
michael@0 | 216 | { |
michael@0 | 217 | MOZ_ASSERT(mLocked); |
michael@0 | 218 | mFile->Unlock(); |
michael@0 | 219 | mLocked = false; |
michael@0 | 220 | } |
michael@0 | 221 | |
michael@0 | 222 | private: |
michael@0 | 223 | nsRefPtr<CacheFile> mFile; |
michael@0 | 224 | bool mLocked; |
michael@0 | 225 | }; |
michael@0 | 226 | |
michael@0 | 227 | } // net |
michael@0 | 228 | } // mozilla |
michael@0 | 229 | |
michael@0 | 230 | #endif |