Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/netwerk/cache2/CacheFileChunk.h
Line
Count
Source (jump to first uncovered line)
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 CacheFileChunk__h__
6
#define CacheFileChunk__h__
7
8
#include "CacheFileIOManager.h"
9
#include "CacheStorageService.h"
10
#include "CacheHashUtils.h"
11
#include "CacheFileUtils.h"
12
#include "nsAutoPtr.h"
13
#include "mozilla/Mutex.h"
14
15
namespace mozilla {
16
namespace net {
17
18
0
#define kChunkSize        (256 * 1024)
19
0
#define kEmptyChunkHash   0x1826
20
21
class CacheFileChunk;
22
class CacheFile;
23
24
class CacheFileChunkBuffer
25
{
26
public:
27
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheFileChunkBuffer)
28
29
  explicit CacheFileChunkBuffer(CacheFileChunk *aChunk);
30
31
  nsresult EnsureBufSize(uint32_t aSize);
32
  void     CopyFrom(CacheFileChunkBuffer *aOther);
33
  nsresult FillInvalidRanges(CacheFileChunkBuffer *aOther,
34
                             CacheFileUtils::ValidityMap *aMap);
35
  size_t   SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
36
37
0
  char *   Buf() const { return mBuf; }
38
  void     SetDataSize(uint32_t aDataSize);
39
0
  uint32_t DataSize() const { return mDataSize; }
40
0
  uint32_t ReadHandlesCount() const { return mReadHandlesCount; }
41
0
  bool     WriteHandleExists() const { return mWriteHandleExists; }
42
43
private:
44
  friend class CacheFileChunkHandle;
45
  friend class CacheFileChunkReadHandle;
46
  friend class CacheFileChunkWriteHandle;
47
48
  ~CacheFileChunkBuffer();
49
50
  void AssertOwnsLock() const;
51
52
  void RemoveReadHandle();
53
  void RemoveWriteHandle();
54
55
  // We keep a weak reference to the chunk to not create a reference cycle. The
56
  // buffer is referenced only by chunk and handles. Handles are always
57
  // destroyed before the chunk so it is guaranteed that mChunk is a valid
58
  // pointer for the whole buffer's lifetime.
59
  CacheFileChunk *mChunk;
60
  char           *mBuf;
61
  uint32_t        mBufSize;
62
  uint32_t        mDataSize;
63
  uint32_t        mReadHandlesCount;
64
  bool            mWriteHandleExists;
65
};
66
67
class CacheFileChunkHandle
68
{
69
public:
70
  uint32_t DataSize();
71
  uint32_t Offset();
72
73
protected:
74
  RefPtr<CacheFileChunkBuffer> mBuf;
75
};
76
77
class CacheFileChunkReadHandle : public CacheFileChunkHandle
78
{
79
public:
80
  explicit CacheFileChunkReadHandle(CacheFileChunkBuffer *aBuf);
81
  ~CacheFileChunkReadHandle();
82
83
  const char *Buf();
84
};
85
86
class CacheFileChunkWriteHandle : public CacheFileChunkHandle
87
{
88
public:
89
  explicit CacheFileChunkWriteHandle(CacheFileChunkBuffer *aBuf);
90
  ~CacheFileChunkWriteHandle();
91
92
  char *Buf();
93
  void UpdateDataSize(uint32_t aOffset, uint32_t aLen);
94
};
95
96
#define CACHEFILECHUNKLISTENER_IID \
97
{ /* baf16149-2ab5-499c-a9c2-5904eb95c288 */       \
98
  0xbaf16149,                                      \
99
  0x2ab5,                                          \
100
  0x499c,                                          \
101
  {0xa9, 0xc2, 0x59, 0x04, 0xeb, 0x95, 0xc2, 0x88} \
102
}
103
104
class CacheFileChunkListener : public nsISupports
105
{
106
public:
107
  NS_DECLARE_STATIC_IID_ACCESSOR(CACHEFILECHUNKLISTENER_IID)
108
109
  NS_IMETHOD OnChunkRead(nsresult aResult, CacheFileChunk *aChunk) = 0;
110
  NS_IMETHOD OnChunkWritten(nsresult aResult, CacheFileChunk *aChunk) = 0;
111
  NS_IMETHOD OnChunkAvailable(nsresult aResult, uint32_t aChunkIdx,
112
                              CacheFileChunk *aChunk) = 0;
113
  NS_IMETHOD OnChunkUpdated(CacheFileChunk *aChunk) = 0;
114
};
115
116
NS_DEFINE_STATIC_IID_ACCESSOR(CacheFileChunkListener,
117
                              CACHEFILECHUNKLISTENER_IID)
118
119
120
class ChunkListenerItem {
121
public:
122
0
  ChunkListenerItem()  { MOZ_COUNT_CTOR(ChunkListenerItem); }
123
0
  ~ChunkListenerItem() { MOZ_COUNT_DTOR(ChunkListenerItem); }
124
125
  nsCOMPtr<nsIEventTarget>         mTarget;
126
  nsCOMPtr<CacheFileChunkListener> mCallback;
127
};
128
129
class ChunkListeners {
130
public:
131
0
  ChunkListeners()  { MOZ_COUNT_CTOR(ChunkListeners); }
132
0
  ~ChunkListeners() { MOZ_COUNT_DTOR(ChunkListeners); }
133
134
  nsTArray<ChunkListenerItem *> mItems;
135
};
136
137
class CacheFileChunk final
138
  : public CacheFileIOListener
139
  , public CacheMemoryConsumer
140
{
141
public:
142
  NS_DECL_THREADSAFE_ISUPPORTS
143
  bool DispatchRelease();
144
145
  CacheFileChunk(CacheFile *aFile, uint32_t aIndex, bool aInitByWriter);
146
147
  void     InitNew();
148
  nsresult Read(CacheFileHandle *aHandle, uint32_t aLen,
149
                CacheHash::Hash16_t aHash,
150
                CacheFileChunkListener *aCallback);
151
  nsresult Write(CacheFileHandle *aHandle, CacheFileChunkListener *aCallback);
152
  void     WaitForUpdate(CacheFileChunkListener *aCallback);
153
  nsresult CancelWait(CacheFileChunkListener *aCallback);
154
  nsresult NotifyUpdateListeners();
155
156
  uint32_t            Index() const;
157
  CacheHash::Hash16_t Hash() const;
158
  uint32_t            DataSize() const;
159
160
  NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult) override;
161
  NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf,
162
                           nsresult aResult) override;
163
  NS_IMETHOD OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult) override;
164
  NS_IMETHOD OnFileDoomed(CacheFileHandle *aHandle, nsresult aResult) override;
165
  NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) override;
166
  NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) override;
167
  virtual bool IsKilled() override;
168
169
  bool   IsReady() const;
170
  bool   IsDirty() const;
171
172
  nsresult GetStatus();
173
  void     SetError(nsresult aStatus);
174
175
  CacheFileChunkReadHandle  GetReadHandle();
176
  CacheFileChunkWriteHandle GetWriteHandle(uint32_t aEnsuredBufSize);
177
178
  // Memory reporting
179
  size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
180
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
181
182
private:
183
  friend class CacheFileChunkBuffer;
184
  friend class CacheFileChunkWriteHandle;
185
  friend class CacheFileInputStream;
186
  friend class CacheFileOutputStream;
187
  friend class CacheFile;
188
189
  virtual ~CacheFileChunk();
190
191
  void AssertOwnsLock() const;
192
193
  void UpdateDataSize(uint32_t aOffset, uint32_t aLen);
194
  nsresult Truncate(uint32_t aOffset);
195
196
  bool CanAllocate(uint32_t aSize) const;
197
  void BuffersAllocationChanged(uint32_t aFreed, uint32_t aAllocated);
198
199
  mozilla::Atomic<uint32_t, ReleaseAcquire>& ChunksMemoryUsage() const;
200
201
  enum EState {
202
    INITIAL = 0,
203
    READING = 1,
204
    WRITING = 2,
205
    READY   = 3
206
  };
207
208
  uint32_t mIndex;
209
  EState   mState;
210
  nsresult mStatus;
211
212
  Atomic<bool> mActiveChunk; // Is true iff the chunk is in CacheFile::mChunks.
213
                             // Adding/removing chunk to/from mChunks as well as
214
                             // changing this member happens under the
215
                             // CacheFile's lock.
216
  bool mIsDirty : 1;
217
  bool mDiscardedChunk : 1;
218
219
  uint32_t   mBuffersSize;
220
  bool const mLimitAllocation : 1; // Whether this chunk respects limit for disk
221
                                   // chunks memory usage.
222
  bool const mIsPriority : 1;
223
224
  // Buffer containing the chunk data. Multiple read handles can access the same
225
  // buffer. When write handle is created and some read handle exists a new copy
226
  // of the buffer is created. This prevents invalidating the buffer when
227
  // CacheFileInputStream::ReadSegments calls the handler outside the lock.
228
  RefPtr<CacheFileChunkBuffer> mBuf;
229
230
  // We need to keep pointers of the old buffers for memory reporting.
231
  nsTArray<RefPtr<CacheFileChunkBuffer>> mOldBufs;
232
233
  // Read handle that is used during writing the chunk to the disk.
234
  nsAutoPtr<CacheFileChunkReadHandle> mWritingStateHandle;
235
236
  // Buffer that is used to read the chunk from the disk. It is allowed to write
237
  // a new data to chunk while we wait for the data from the disk. In this case
238
  // this buffer is merged with mBuf in OnDataRead().
239
  RefPtr<CacheFileChunkBuffer> mReadingStateBuf;
240
  CacheHash::Hash16_t          mExpectedHash;
241
242
  RefPtr<CacheFile>                mFile; // is null if chunk is cached to
243
                                          // prevent reference cycles
244
  nsCOMPtr<CacheFileChunkListener> mListener;
245
  nsTArray<ChunkListenerItem *>    mUpdateListeners;
246
  CacheFileUtils::ValidityMap      mValidityMap;
247
};
248
249
250
} // namespace net
251
} // namespace mozilla
252
253
#endif