in_flight_backend_io.h revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
1// Copyright (c) 2012 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_BLOCKFILE_IN_FLIGHT_BACKEND_IO_H_
6#define NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_BACKEND_IO_H_
7
8#include <list>
9#include <string>
10
11#include "base/memory/ref_counted.h"
12#include "base/single_thread_task_runner.h"
13#include "base/time/time.h"
14#include "net/base/completion_callback.h"
15#include "net/base/io_buffer.h"
16#include "net/disk_cache/blockfile/in_flight_io.h"
17
18namespace disk_cache {
19
20class BackendImpl;
21class Entry;
22class EntryImpl;
23
24// This class represents a single asynchronous disk cache IO operation while it
25// is being bounced between threads.
26class BackendIO : public BackgroundIO {
27 public:
28  BackendIO(InFlightIO* controller, BackendImpl* backend,
29            const net::CompletionCallback& callback);
30
31  // Runs the actual operation on the background thread.
32  void ExecuteOperation();
33
34  // Callback implementation.
35  void OnIOComplete(int result);
36
37  // Called when we are finishing this operation. If |cancel| is true, the user
38  // callback will not be invoked.
39  void OnDone(bool cancel);
40
41  // Returns true if this operation is directed to an entry (vs. the backend).
42  bool IsEntryOperation();
43
44  net::CompletionCallback callback() const { return callback_; }
45
46  // Grabs an extra reference of entry_.
47  void ReferenceEntry();
48
49  // The operations we proxy:
50  void Init();
51  void OpenEntry(const std::string& key, Entry** entry);
52  void CreateEntry(const std::string& key, Entry** entry);
53  void DoomEntry(const std::string& key);
54  void DoomAllEntries();
55  void DoomEntriesBetween(const base::Time initial_time,
56                          const base::Time end_time);
57  void DoomEntriesSince(const base::Time initial_time);
58  void OpenNextEntry(void** iter, Entry** next_entry);
59  void OpenPrevEntry(void** iter, Entry** prev_entry);
60  void EndEnumeration(void* iterator);
61  void OnExternalCacheHit(const std::string& key);
62  void CloseEntryImpl(EntryImpl* entry);
63  void DoomEntryImpl(EntryImpl* entry);
64  void FlushQueue();  // Dummy operation.
65  void RunTask(const base::Closure& task);
66  void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
67                int buf_len);
68  void WriteData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
69                 int buf_len, bool truncate);
70  void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
71                      int buf_len);
72  void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
73                       int buf_len);
74  void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start);
75  void CancelSparseIO(EntryImpl* entry);
76  void ReadyForSparseIO(EntryImpl* entry);
77
78 private:
79  // There are two types of operations to proxy: regular backend operations are
80  // executed sequentially (queued by the message loop). On the other hand,
81  // operations targeted to a given entry can be long lived and support multiple
82  // simultaneous users (multiple reads or writes to the same entry), and they
83  // are subject to throttling, so we keep an explicit queue.
84  enum Operation {
85    OP_NONE = 0,
86    OP_INIT,
87    OP_OPEN,
88    OP_CREATE,
89    OP_DOOM,
90    OP_DOOM_ALL,
91    OP_DOOM_BETWEEN,
92    OP_DOOM_SINCE,
93    OP_OPEN_NEXT,
94    OP_OPEN_PREV,
95    OP_END_ENUMERATION,
96    OP_ON_EXTERNAL_CACHE_HIT,
97    OP_CLOSE_ENTRY,
98    OP_DOOM_ENTRY,
99    OP_FLUSH_QUEUE,
100    OP_RUN_TASK,
101    OP_MAX_BACKEND,
102    OP_READ,
103    OP_WRITE,
104    OP_READ_SPARSE,
105    OP_WRITE_SPARSE,
106    OP_GET_RANGE,
107    OP_CANCEL_IO,
108    OP_IS_READY
109  };
110
111  virtual ~BackendIO();
112
113  // Returns true if this operation returns an entry.
114  bool ReturnsEntry();
115
116  // Returns the time that has passed since the operation was created.
117  base::TimeDelta ElapsedTime() const;
118
119  void ExecuteBackendOperation();
120  void ExecuteEntryOperation();
121
122  BackendImpl* backend_;
123  net::CompletionCallback callback_;
124  Operation operation_;
125
126  // The arguments of all the operations we proxy:
127  std::string key_;
128  Entry** entry_ptr_;
129  base::Time initial_time_;
130  base::Time end_time_;
131  void** iter_ptr_;
132  void* iter_;
133  EntryImpl* entry_;
134  int index_;
135  int offset_;
136  scoped_refptr<net::IOBuffer> buf_;
137  int buf_len_;
138  bool truncate_;
139  int64 offset64_;
140  int64* start_;
141  base::TimeTicks start_time_;
142  base::Closure task_;
143
144  DISALLOW_COPY_AND_ASSIGN(BackendIO);
145};
146
147// The specialized controller that keeps track of current operations.
148class InFlightBackendIO : public InFlightIO {
149 public:
150  InFlightBackendIO(
151      BackendImpl* backend,
152      const scoped_refptr<base::SingleThreadTaskRunner>& background_thread);
153  virtual ~InFlightBackendIO();
154
155  // Proxied operations.
156  void Init(const net::CompletionCallback& callback);
157  void OpenEntry(const std::string& key, Entry** entry,
158                 const net::CompletionCallback& callback);
159  void CreateEntry(const std::string& key, Entry** entry,
160                   const net::CompletionCallback& callback);
161  void DoomEntry(const std::string& key,
162                 const net::CompletionCallback& callback);
163  void DoomAllEntries(const net::CompletionCallback& callback);
164  void DoomEntriesBetween(const base::Time initial_time,
165                          const base::Time end_time,
166                          const net::CompletionCallback& callback);
167  void DoomEntriesSince(const base::Time initial_time,
168                        const net::CompletionCallback& callback);
169  void OpenNextEntry(void** iter, Entry** next_entry,
170                     const net::CompletionCallback& callback);
171  void OpenPrevEntry(void** iter, Entry** prev_entry,
172                     const net::CompletionCallback& callback);
173  void EndEnumeration(void* iterator);
174  void OnExternalCacheHit(const std::string& key);
175  void CloseEntryImpl(EntryImpl* entry);
176  void DoomEntryImpl(EntryImpl* entry);
177  void FlushQueue(const net::CompletionCallback& callback);
178  void RunTask(const base::Closure& task,
179               const net::CompletionCallback& callback);
180  void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
181                int buf_len, const net::CompletionCallback& callback);
182  void WriteData(
183      EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
184      int buf_len, bool truncate, const net::CompletionCallback& callback);
185  void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
186                      int buf_len, const net::CompletionCallback& callback);
187  void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
188                       int buf_len, const net::CompletionCallback& callback);
189  void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start,
190                         const net::CompletionCallback& callback);
191  void CancelSparseIO(EntryImpl* entry);
192  void ReadyForSparseIO(EntryImpl* entry,
193                        const net::CompletionCallback& callback);
194
195  // Blocks until all operations are cancelled or completed.
196  void WaitForPendingIO();
197
198  scoped_refptr<base::SingleThreadTaskRunner> background_thread() {
199    return background_thread_;
200  }
201
202  // Returns true if the current thread is the background thread.
203  bool BackgroundIsCurrentThread() {
204    return background_thread_->RunsTasksOnCurrentThread();
205  }
206
207  base::WeakPtr<InFlightBackendIO> GetWeakPtr();
208
209 protected:
210  virtual void OnOperationComplete(BackgroundIO* operation,
211                                   bool cancel) OVERRIDE;
212
213 private:
214  void PostOperation(BackendIO* operation);
215
216  BackendImpl* backend_;
217  scoped_refptr<base::SingleThreadTaskRunner> background_thread_;
218  base::WeakPtrFactory<InFlightBackendIO> ptr_factory_;
219
220  DISALLOW_COPY_AND_ASSIGN(InFlightBackendIO);
221};
222
223}  // namespace disk_cache
224
225#endif  // NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_BACKEND_IO_H_
226