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