1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/cache2/CacheFile.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,230 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#ifndef CacheFile__h__ 1.9 +#define CacheFile__h__ 1.10 + 1.11 +#include "CacheFileChunk.h" 1.12 +#include "CacheFileIOManager.h" 1.13 +#include "CacheFileMetadata.h" 1.14 +#include "nsRefPtrHashtable.h" 1.15 +#include "nsClassHashtable.h" 1.16 +#include "mozilla/Mutex.h" 1.17 + 1.18 +class nsIInputStream; 1.19 +class nsIOutputStream; 1.20 + 1.21 +namespace mozilla { 1.22 +namespace net { 1.23 + 1.24 +class CacheFileInputStream; 1.25 +class CacheFileOutputStream; 1.26 +class CacheOutputCloseListener; 1.27 +class MetadataWriteTimer; 1.28 + 1.29 +#define CACHEFILELISTENER_IID \ 1.30 +{ /* 95e7f284-84ba-48f9-b1fc-3a7336b4c33c */ \ 1.31 + 0x95e7f284, \ 1.32 + 0x84ba, \ 1.33 + 0x48f9, \ 1.34 + {0xb1, 0xfc, 0x3a, 0x73, 0x36, 0xb4, 0xc3, 0x3c} \ 1.35 +} 1.36 + 1.37 +class CacheFileListener : public nsISupports 1.38 +{ 1.39 +public: 1.40 + NS_DECLARE_STATIC_IID_ACCESSOR(CACHEFILELISTENER_IID) 1.41 + 1.42 + NS_IMETHOD OnFileReady(nsresult aResult, bool aIsNew) = 0; 1.43 + NS_IMETHOD OnFileDoomed(nsresult aResult) = 0; 1.44 +}; 1.45 + 1.46 +NS_DEFINE_STATIC_IID_ACCESSOR(CacheFileListener, CACHEFILELISTENER_IID) 1.47 + 1.48 + 1.49 +class CacheFile : public CacheFileChunkListener 1.50 + , public CacheFileIOListener 1.51 + , public CacheFileMetadataListener 1.52 +{ 1.53 +public: 1.54 + NS_DECL_THREADSAFE_ISUPPORTS 1.55 + 1.56 + CacheFile(); 1.57 + 1.58 + nsresult Init(const nsACString &aKey, 1.59 + bool aCreateNew, 1.60 + bool aMemoryOnly, 1.61 + bool aPriority, 1.62 + CacheFileListener *aCallback); 1.63 + 1.64 + NS_IMETHOD OnChunkRead(nsresult aResult, CacheFileChunk *aChunk); 1.65 + NS_IMETHOD OnChunkWritten(nsresult aResult, CacheFileChunk *aChunk); 1.66 + NS_IMETHOD OnChunkAvailable(nsresult aResult, uint32_t aChunkIdx, 1.67 + CacheFileChunk *aChunk); 1.68 + NS_IMETHOD OnChunkUpdated(CacheFileChunk *aChunk); 1.69 + 1.70 + NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult); 1.71 + NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, 1.72 + nsresult aResult); 1.73 + NS_IMETHOD OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult); 1.74 + NS_IMETHOD OnFileDoomed(CacheFileHandle *aHandle, nsresult aResult); 1.75 + NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult); 1.76 + NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult); 1.77 + 1.78 + NS_IMETHOD OnMetadataRead(nsresult aResult); 1.79 + NS_IMETHOD OnMetadataWritten(nsresult aResult); 1.80 + 1.81 + NS_IMETHOD OpenInputStream(nsIInputStream **_retval); 1.82 + NS_IMETHOD OpenOutputStream(CacheOutputCloseListener *aCloseListener, nsIOutputStream **_retval); 1.83 + NS_IMETHOD SetMemoryOnly(); 1.84 + NS_IMETHOD Doom(CacheFileListener *aCallback); 1.85 + 1.86 + nsresult ThrowMemoryCachedData(); 1.87 + 1.88 + // metadata forwarders 1.89 + nsresult GetElement(const char *aKey, char **_retval); 1.90 + nsresult SetElement(const char *aKey, const char *aValue); 1.91 + nsresult ElementsSize(uint32_t *_retval); 1.92 + nsresult SetExpirationTime(uint32_t aExpirationTime); 1.93 + nsresult GetExpirationTime(uint32_t *_retval); 1.94 + nsresult SetLastModified(uint32_t aLastModified); 1.95 + nsresult GetLastModified(uint32_t *_retval); 1.96 + nsresult SetFrecency(uint32_t aFrecency); 1.97 + nsresult GetFrecency(uint32_t *_retval); 1.98 + nsresult GetLastFetched(uint32_t *_retval); 1.99 + nsresult GetFetchCount(uint32_t *_retval); 1.100 + 1.101 + bool DataSize(int64_t* aSize); 1.102 + void Key(nsACString& aKey) { aKey = mKey; } 1.103 + bool IsDoomed(); 1.104 + bool IsWriteInProgress(); 1.105 + 1.106 + // Memory reporting 1.107 + size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; 1.108 + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; 1.109 + 1.110 +private: 1.111 + friend class CacheFileIOManager; 1.112 + friend class CacheFileChunk; 1.113 + friend class CacheFileInputStream; 1.114 + friend class CacheFileOutputStream; 1.115 + friend class CacheFileAutoLock; 1.116 + friend class MetadataWriteTimer; 1.117 + 1.118 + virtual ~CacheFile(); 1.119 + 1.120 + void Lock(); 1.121 + void Unlock(); 1.122 + void AssertOwnsLock() const; 1.123 + void ReleaseOutsideLock(nsISupports *aObject); 1.124 + 1.125 + nsresult GetChunk(uint32_t aIndex, bool aWriter, 1.126 + CacheFileChunkListener *aCallback, 1.127 + CacheFileChunk **_retval); 1.128 + nsresult GetChunkLocked(uint32_t aIndex, bool aWriter, 1.129 + CacheFileChunkListener *aCallback, 1.130 + CacheFileChunk **_retval); 1.131 + nsresult RemoveChunk(CacheFileChunk *aChunk); 1.132 + void RemoveChunkInternal(CacheFileChunk *aChunk, bool aCacheChunk); 1.133 + 1.134 + nsresult RemoveInput(CacheFileInputStream *aInput); 1.135 + nsresult RemoveOutput(CacheFileOutputStream *aOutput); 1.136 + nsresult NotifyChunkListener(CacheFileChunkListener *aCallback, 1.137 + nsIEventTarget *aTarget, 1.138 + nsresult aResult, 1.139 + uint32_t aChunkIdx, 1.140 + CacheFileChunk *aChunk); 1.141 + nsresult QueueChunkListener(uint32_t aIndex, 1.142 + CacheFileChunkListener *aCallback); 1.143 + nsresult NotifyChunkListeners(uint32_t aIndex, nsresult aResult, 1.144 + CacheFileChunk *aChunk); 1.145 + bool HaveChunkListeners(uint32_t aIndex); 1.146 + void NotifyListenersAboutOutputRemoval(); 1.147 + 1.148 + bool IsDirty(); 1.149 + void WriteMetadataIfNeeded(); 1.150 + void WriteMetadataIfNeededLocked(bool aFireAndForget = false); 1.151 + void PostWriteTimer(); 1.152 + 1.153 + static PLDHashOperator WriteAllCachedChunks(const uint32_t& aIdx, 1.154 + nsRefPtr<CacheFileChunk>& aChunk, 1.155 + void* aClosure); 1.156 + 1.157 + static PLDHashOperator FailListenersIfNonExistentChunk( 1.158 + const uint32_t& aIdx, 1.159 + nsAutoPtr<mozilla::net::ChunkListeners>& aListeners, 1.160 + void* aClosure); 1.161 + 1.162 + static PLDHashOperator FailUpdateListeners(const uint32_t& aIdx, 1.163 + nsRefPtr<CacheFileChunk>& aChunk, 1.164 + void* aClosure); 1.165 + 1.166 + nsresult PadChunkWithZeroes(uint32_t aChunkIdx); 1.167 + 1.168 + void SetError(nsresult aStatus); 1.169 + 1.170 + nsresult InitIndexEntry(); 1.171 + 1.172 + mozilla::Mutex mLock; 1.173 + bool mOpeningFile; 1.174 + bool mReady; 1.175 + bool mMemoryOnly; 1.176 + bool mOpenAsMemoryOnly; 1.177 + bool mDataAccessed; 1.178 + bool mDataIsDirty; 1.179 + bool mWritingMetadata; 1.180 + nsresult mStatus; 1.181 + int64_t mDataSize; 1.182 + nsCString mKey; 1.183 + 1.184 + nsRefPtr<CacheFileHandle> mHandle; 1.185 + nsRefPtr<CacheFileMetadata> mMetadata; 1.186 + nsCOMPtr<CacheFileListener> mListener; 1.187 + nsCOMPtr<CacheFileIOListener> mDoomAfterOpenListener; 1.188 + 1.189 + nsRefPtrHashtable<nsUint32HashKey, CacheFileChunk> mChunks; 1.190 + nsClassHashtable<nsUint32HashKey, ChunkListeners> mChunkListeners; 1.191 + nsRefPtrHashtable<nsUint32HashKey, CacheFileChunk> mCachedChunks; 1.192 + 1.193 + nsTArray<CacheFileInputStream*> mInputs; 1.194 + CacheFileOutputStream *mOutput; 1.195 + 1.196 + nsTArray<nsISupports*> mObjsToRelease; 1.197 +}; 1.198 + 1.199 +class CacheFileAutoLock { 1.200 +public: 1.201 + CacheFileAutoLock(CacheFile *aFile) 1.202 + : mFile(aFile) 1.203 + , mLocked(true) 1.204 + { 1.205 + mFile->Lock(); 1.206 + } 1.207 + ~CacheFileAutoLock() 1.208 + { 1.209 + if (mLocked) 1.210 + mFile->Unlock(); 1.211 + } 1.212 + void Lock() 1.213 + { 1.214 + MOZ_ASSERT(!mLocked); 1.215 + mFile->Lock(); 1.216 + mLocked = true; 1.217 + } 1.218 + void Unlock() 1.219 + { 1.220 + MOZ_ASSERT(mLocked); 1.221 + mFile->Unlock(); 1.222 + mLocked = false; 1.223 + } 1.224 + 1.225 +private: 1.226 + nsRefPtr<CacheFile> mFile; 1.227 + bool mLocked; 1.228 +}; 1.229 + 1.230 +} // net 1.231 +} // mozilla 1.232 + 1.233 +#endif