1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_
6#define NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_
7
8#include <queue>
9#include <string>
10
11#include "base/files/file_path.h"
12#include "base/memory/ref_counted.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/memory/weak_ptr.h"
15#include "base/threading/thread_checker.h"
16#include "net/base/cache_type.h"
17#include "net/base/net_export.h"
18#include "net/base/net_log.h"
19#include "net/disk_cache/disk_cache.h"
20#include "net/disk_cache/simple/simple_entry_format.h"
21#include "net/disk_cache/simple/simple_entry_operation.h"
22
23namespace base {
24class TaskRunner;
25}
26
27namespace net {
28class GrowableIOBuffer;
29class IOBuffer;
30}
31
32namespace disk_cache {
33
34class SimpleBackendImpl;
35class SimpleSynchronousEntry;
36class SimpleEntryStat;
37struct SimpleEntryCreationResults;
38
39// SimpleEntryImpl is the IO thread interface to an entry in the very simple
40// disk cache. It proxies for the SimpleSynchronousEntry, which performs IO
41// on the worker thread.
42class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
43    public base::RefCounted<SimpleEntryImpl>,
44    public base::SupportsWeakPtr<SimpleEntryImpl> {
45  friend class base::RefCounted<SimpleEntryImpl>;
46 public:
47  enum OperationsMode {
48    NON_OPTIMISTIC_OPERATIONS,
49    OPTIMISTIC_OPERATIONS,
50  };
51
52  SimpleEntryImpl(net::CacheType cache_type,
53                  const base::FilePath& path,
54                  uint64 entry_hash,
55                  OperationsMode operations_mode,
56                  SimpleBackendImpl* backend,
57                  net::NetLog* net_log);
58
59  // Adds another reader/writer to this entry, if possible, returning |this| to
60  // |entry|.
61  int OpenEntry(Entry** entry, const CompletionCallback& callback);
62
63  // Creates this entry, if possible. Returns |this| to |entry|.
64  int CreateEntry(Entry** entry, const CompletionCallback& callback);
65
66  // Identical to Backend::Doom() except that it accepts a CompletionCallback.
67  int DoomEntry(const CompletionCallback& callback);
68
69  const std::string& key() const { return key_; }
70  uint64 entry_hash() const { return entry_hash_; }
71  void SetKey(const std::string& key);
72
73  // From Entry:
74  virtual void Doom() OVERRIDE;
75  virtual void Close() OVERRIDE;
76  virtual std::string GetKey() const OVERRIDE;
77  virtual base::Time GetLastUsed() const OVERRIDE;
78  virtual base::Time GetLastModified() const OVERRIDE;
79  virtual int32 GetDataSize(int index) const OVERRIDE;
80  virtual int ReadData(int stream_index,
81                       int offset,
82                       net::IOBuffer* buf,
83                       int buf_len,
84                       const CompletionCallback& callback) OVERRIDE;
85  virtual int WriteData(int stream_index,
86                        int offset,
87                        net::IOBuffer* buf,
88                        int buf_len,
89                        const CompletionCallback& callback,
90                        bool truncate) OVERRIDE;
91  virtual int ReadSparseData(int64 offset,
92                             net::IOBuffer* buf,
93                             int buf_len,
94                             const CompletionCallback& callback) OVERRIDE;
95  virtual int WriteSparseData(int64 offset,
96                              net::IOBuffer* buf,
97                              int buf_len,
98                              const CompletionCallback& callback) OVERRIDE;
99  virtual int GetAvailableRange(int64 offset,
100                                int len,
101                                int64* start,
102                                const CompletionCallback& callback) OVERRIDE;
103  virtual bool CouldBeSparse() const OVERRIDE;
104  virtual void CancelSparseIO() OVERRIDE;
105  virtual int ReadyForSparseIO(const CompletionCallback& callback) OVERRIDE;
106
107 private:
108  class ScopedOperationRunner;
109  friend class ScopedOperationRunner;
110
111  enum State {
112    // The state immediately after construction, but before |synchronous_entry_|
113    // has been assigned. This is the state at construction, and is the only
114    // legal state to destruct an entry in.
115    STATE_UNINITIALIZED,
116
117    // This entry is available for regular IO.
118    STATE_READY,
119
120    // IO is currently in flight, operations must wait for completion before
121    // launching.
122    STATE_IO_PENDING,
123
124    // A failure occurred in the current or previous operation. All operations
125    // after that must fail, until we receive a Close().
126    STATE_FAILURE,
127  };
128
129  // Used in histograms, please only add entries at the end.
130  enum CheckCrcResult {
131    CRC_CHECK_NEVER_READ_TO_END = 0,
132    CRC_CHECK_NOT_DONE = 1,
133    CRC_CHECK_DONE = 2,
134    CRC_CHECK_NEVER_READ_AT_ALL = 3,
135    CRC_CHECK_MAX = 4,
136  };
137
138  virtual ~SimpleEntryImpl();
139
140  // Must be used to invoke a client-provided completion callback for an
141  // operation initiated through the backend (e.g. create, open) so that clients
142  // don't get notified after they deleted the backend (which they would not
143  // expect).
144  void PostClientCallback(const CompletionCallback& callback, int result);
145
146  // Sets entry to STATE_UNINITIALIZED.
147  void MakeUninitialized();
148
149  // Return this entry to a user of the API in |out_entry|. Increments the user
150  // count.
151  void ReturnEntryToCaller(Entry** out_entry);
152
153  // Ensures that |this| is no longer referenced by our |backend_|, this
154  // guarantees that this entry cannot have OpenEntry/CreateEntry called again.
155  void RemoveSelfFromBackend();
156
157  // An error occured, and the SimpleSynchronousEntry should have Doomed
158  // us at this point. We need to remove |this| from the Backend and the
159  // index.
160  void MarkAsDoomed();
161
162  // Runs the next operation in the queue, if any and if there is no other
163  // operation running at the moment.
164  // WARNING: May delete |this|, as an operation in the queue can contain
165  // the last reference.
166  void RunNextOperationIfNeeded();
167
168  void OpenEntryInternal(bool have_index,
169                         const CompletionCallback& callback,
170                         Entry** out_entry);
171
172  void CreateEntryInternal(bool have_index,
173                           const CompletionCallback& callback,
174                           Entry** out_entry);
175
176  void CloseInternal();
177
178  void ReadDataInternal(int index,
179                        int offset,
180                        net::IOBuffer* buf,
181                        int buf_len,
182                        const CompletionCallback& callback);
183
184  void WriteDataInternal(int index,
185                         int offset,
186                         net::IOBuffer* buf,
187                         int buf_len,
188                         const CompletionCallback& callback,
189                         bool truncate);
190
191  void ReadSparseDataInternal(int64 sparse_offset,
192                              net::IOBuffer* buf,
193                              int buf_len,
194                              const CompletionCallback& callback);
195
196  void WriteSparseDataInternal(int64 sparse_offset,
197                               net::IOBuffer* buf,
198                               int buf_len,
199                               const CompletionCallback& callback);
200
201  void GetAvailableRangeInternal(int64 sparse_offset,
202                                 int len,
203                                 int64* out_start,
204                                 const CompletionCallback& callback);
205
206  void DoomEntryInternal(const CompletionCallback& callback);
207
208  // Called after a SimpleSynchronousEntry has completed CreateEntry() or
209  // OpenEntry(). If |in_sync_entry| is non-NULL, creation is successful and we
210  // can return |this| SimpleEntryImpl to |*out_entry|. Runs
211  // |completion_callback|.
212  void CreationOperationComplete(
213      const CompletionCallback& completion_callback,
214      const base::TimeTicks& start_time,
215      scoped_ptr<SimpleEntryCreationResults> in_results,
216      Entry** out_entry,
217      net::NetLog::EventType end_event_type);
218
219  // Called after we've closed and written the EOF record to our entry. Until
220  // this point it hasn't been safe to OpenEntry() the same entry, but from this
221  // point it is.
222  void CloseOperationComplete();
223
224  // Internal utility method used by other completion methods. Calls
225  // |completion_callback| after updating state and dooming on errors.
226  void EntryOperationComplete(const CompletionCallback& completion_callback,
227                              const SimpleEntryStat& entry_stat,
228                              scoped_ptr<int> result);
229
230  // Called after an asynchronous read. Updates |crc32s_| if possible.
231  void ReadOperationComplete(int stream_index,
232                             int offset,
233                             const CompletionCallback& completion_callback,
234                             scoped_ptr<uint32> read_crc32,
235                             scoped_ptr<SimpleEntryStat> entry_stat,
236                             scoped_ptr<int> result);
237
238  // Called after an asynchronous write completes.
239  void WriteOperationComplete(int stream_index,
240                              const CompletionCallback& completion_callback,
241                              scoped_ptr<SimpleEntryStat> entry_stat,
242                              scoped_ptr<int> result);
243
244  void ReadSparseOperationComplete(
245      const CompletionCallback& completion_callback,
246      scoped_ptr<base::Time> last_used,
247      scoped_ptr<int> result);
248
249  void WriteSparseOperationComplete(
250      const CompletionCallback& completion_callback,
251      scoped_ptr<SimpleEntryStat> entry_stat,
252      scoped_ptr<int> result);
253
254  void GetAvailableRangeOperationComplete(
255      const CompletionCallback& completion_callback,
256      scoped_ptr<int> result);
257
258  // Called after an asynchronous doom completes.
259  void DoomOperationComplete(const CompletionCallback& callback,
260                             State state_to_restore,
261                             int result);
262
263  // Called after validating the checksums on an entry. Passes through the
264  // original result if successful, propogates the error if the checksum does
265  // not validate.
266  void ChecksumOperationComplete(
267      int stream_index,
268      int orig_result,
269      const CompletionCallback& completion_callback,
270      scoped_ptr<int> result);
271
272  // Called after completion of asynchronous IO and receiving file metadata for
273  // the entry in |entry_stat|. Updates the metadata in the entry and in the
274  // index to make them available on next IO operations.
275  void UpdateDataFromEntryStat(const SimpleEntryStat& entry_stat);
276
277  int64 GetDiskUsage() const;
278
279  // Used to report histograms.
280  void RecordReadIsParallelizable(const SimpleEntryOperation& operation) const;
281  void RecordWriteDependencyType(const SimpleEntryOperation& operation) const;
282
283  // Reads from the stream 0 data kept in memory.
284  int ReadStream0Data(net::IOBuffer* buf, int offset, int buf_len);
285
286  // Copies data from |buf| to the internal in-memory buffer for stream 0. If
287  // |truncate| is set to true, the target buffer will be truncated at |offset|
288  // + |buf_len| before being written.
289  int SetStream0Data(net::IOBuffer* buf,
290                     int offset, int buf_len,
291                     bool truncate);
292
293  // Updates |crc32s_| and |crc32s_end_offset_| for a write of the data in
294  // |buffer| on |stream_index|, starting at |offset| and of length |length|.
295  void AdvanceCrc(net::IOBuffer* buffer,
296                  int offset,
297                  int length,
298                  int stream_index);
299
300  // All nonstatic SimpleEntryImpl methods should always be called on the IO
301  // thread, in all cases. |io_thread_checker_| documents and enforces this.
302  base::ThreadChecker io_thread_checker_;
303
304  const base::WeakPtr<SimpleBackendImpl> backend_;
305  const net::CacheType cache_type_;
306  const scoped_refptr<base::TaskRunner> worker_pool_;
307  const base::FilePath path_;
308  const uint64 entry_hash_;
309  const bool use_optimistic_operations_;
310  std::string key_;
311
312  // |last_used_|, |last_modified_| and |data_size_| are copied from the
313  // synchronous entry at the completion of each item of asynchronous IO.
314  // TODO(clamy): Unify last_used_ with data in the index.
315  base::Time last_used_;
316  base::Time last_modified_;
317  int32 data_size_[kSimpleEntryStreamCount];
318  int32 sparse_data_size_;
319
320  // Number of times this object has been returned from Backend::OpenEntry() and
321  // Backend::CreateEntry() without subsequent Entry::Close() calls. Used to
322  // notify the backend when this entry not used by any callers.
323  int open_count_;
324
325  bool doomed_;
326
327  State state_;
328
329  // When possible, we compute a crc32, for the data in each entry as we read or
330  // write. For each stream, |crc32s_[index]| is the crc32 of that stream from
331  // [0 .. |crc32s_end_offset_|). If |crc32s_end_offset_[index] == 0| then the
332  // value of |crc32s_[index]| is undefined.
333  int32 crc32s_end_offset_[kSimpleEntryStreamCount];
334  uint32 crc32s_[kSimpleEntryStreamCount];
335
336  // If |have_written_[index]| is true, we have written to the file that
337  // contains stream |index|.
338  bool have_written_[kSimpleEntryStreamCount];
339
340  // Reflects how much CRC checking has been done with the entry. This state is
341  // reported on closing each entry stream.
342  CheckCrcResult crc_check_state_[kSimpleEntryStreamCount];
343
344  // The |synchronous_entry_| is the worker thread object that performs IO on
345  // entries. It's owned by this SimpleEntryImpl whenever |executing_operation_|
346  // is false (i.e. when an operation is not pending on the worker pool). When
347  // an operation is being executed no one owns the synchronous entry. Therefore
348  // SimpleEntryImpl should not be deleted while an operation is running as that
349  // would leak the SimpleSynchronousEntry.
350  SimpleSynchronousEntry* synchronous_entry_;
351
352  std::queue<SimpleEntryOperation> pending_operations_;
353
354  net::BoundNetLog net_log_;
355
356  scoped_ptr<SimpleEntryOperation> executing_operation_;
357
358  // Unlike other streams, stream 0 data is read from the disk when the entry is
359  // opened, and then kept in memory. All read/write operations on stream 0
360  // affect the |stream_0_data_| buffer. When the entry is closed,
361  // |stream_0_data_| is written to the disk.
362  // Stream 0 is kept in memory because it is stored in the same file as stream
363  // 1 on disk, to reduce the number of file descriptors and save disk space.
364  // This strategy allows stream 1 to change size easily. Since stream 0 is only
365  // used to write HTTP headers, the memory consumption of keeping it in memory
366  // is acceptable.
367  scoped_refptr<net::GrowableIOBuffer> stream_0_data_;
368};
369
370}  // namespace disk_cache
371
372#endif  // NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_
373