• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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 <stdint.h>
9 
10 #include <string>
11 
12 #include "base/memory/raw_ptr.h"
13 #include "base/memory/scoped_refptr.h"
14 #include "base/task/single_thread_task_runner.h"
15 #include "base/time/time.h"
16 #include "net/base/completion_once_callback.h"
17 #include "net/base/io_buffer.h"
18 #include "net/disk_cache/blockfile/in_flight_io.h"
19 #include "net/disk_cache/blockfile/rankings.h"
20 #include "net/disk_cache/disk_cache.h"
21 
22 namespace base {
23 class Location;
24 }
25 
26 namespace disk_cache {
27 
28 class BackendImpl;
29 class EntryImpl;
30 class InFlightBackendIO;
31 
32 // This class represents a single asynchronous disk cache IO operation while it
33 // is being bounced between threads.
34 class BackendIO : public BackgroundIO {
35  public:
36   BackendIO(InFlightBackendIO* controller,
37             BackendImpl* backend,
38             net::CompletionOnceCallback callback);
39 
40   BackendIO(InFlightBackendIO* controller,
41             BackendImpl* backend,
42             EntryResultCallback callback);
43 
44   BackendIO(InFlightBackendIO* controller,
45             BackendImpl* backend,
46             RangeResultCallback callback);
47 
48   BackendIO(const BackendIO&) = delete;
49   BackendIO& operator=(const BackendIO&) = delete;
50 
51   // Runs the actual operation on the background thread.
52   void ExecuteOperation();
53 
54   // Callback implementation.
55   void OnIOComplete(int result);
56 
57   // Called when we are finishing this operation. If |cancel| is true, the user
58   // callback will not be invoked.
59   void OnDone(bool cancel);
60 
61   // Returns true if this operation is directed to an entry (vs. the backend).
62   bool IsEntryOperation();
63 
has_callback()64   bool has_callback() const { return !callback_.is_null(); }
65   void RunCallback(int result);
66 
has_entry_result_callback()67   bool has_entry_result_callback() const {
68     return !entry_result_callback_.is_null();
69   }
70   void RunEntryResultCallback();
71 
has_range_result_callback()72   bool has_range_result_callback() const {
73     return !range_result_callback_.is_null();
74   }
75   void RunRangeResultCallback();
76 
77   // The operations we proxy:
78   void Init();
79   void OpenOrCreateEntry(const std::string& key);
80   void OpenEntry(const std::string& key);
81   void CreateEntry(const std::string& key);
82   void DoomEntry(const std::string& key);
83   void DoomAllEntries();
84   void DoomEntriesBetween(const base::Time initial_time,
85                           const base::Time end_time);
86   void DoomEntriesSince(const base::Time initial_time);
87   void CalculateSizeOfAllEntries();
88   void OpenNextEntry(Rankings::Iterator* iterator);
89   void EndEnumeration(std::unique_ptr<Rankings::Iterator> iterator);
90   void OnExternalCacheHit(const std::string& key);
91   void CloseEntryImpl(EntryImpl* entry);
92   void DoomEntryImpl(EntryImpl* entry);
93   void FlushQueue();  // Dummy operation.
94   void RunTask(base::OnceClosure task);
95   void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
96                 int buf_len);
97   void WriteData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
98                  int buf_len, bool truncate);
99   void ReadSparseData(EntryImpl* entry,
100                       int64_t offset,
101                       net::IOBuffer* buf,
102                       int buf_len);
103   void WriteSparseData(EntryImpl* entry,
104                        int64_t offset,
105                        net::IOBuffer* buf,
106                        int buf_len);
107   void GetAvailableRange(EntryImpl* entry, int64_t offset, int len);
108   void CancelSparseIO(EntryImpl* entry);
109   void ReadyForSparseIO(EntryImpl* entry);
110 
111  private:
112   BackendIO(InFlightBackendIO* controller, BackendImpl* backend);
113 
114   // There are two types of operations to proxy: regular backend operations are
115   // executed sequentially (queued by the message loop). On the other hand,
116   // operations targeted to a given entry can be long lived and support multiple
117   // simultaneous users (multiple reads or writes to the same entry), and they
118   // are subject to throttling, so we keep an explicit queue.
119   enum Operation {
120     OP_NONE = 0,
121     OP_INIT,
122     OP_OPEN_OR_CREATE,
123     OP_OPEN,
124     OP_CREATE,
125     OP_DOOM,
126     OP_DOOM_ALL,
127     OP_DOOM_BETWEEN,
128     OP_DOOM_SINCE,
129     OP_SIZE_ALL,
130     OP_OPEN_NEXT,
131     OP_END_ENUMERATION,
132     OP_ON_EXTERNAL_CACHE_HIT,
133     OP_CLOSE_ENTRY,
134     OP_DOOM_ENTRY,
135     OP_FLUSH_QUEUE,
136     OP_RUN_TASK,
137     OP_MAX_BACKEND,
138     OP_READ,
139     OP_WRITE,
140     OP_READ_SPARSE,
141     OP_WRITE_SPARSE,
142     OP_GET_RANGE,
143     OP_CANCEL_IO,
144     OP_IS_READY
145   };
146 
147   ~BackendIO() override;
148 
149   // Returns true if this operation returns an entry.
150   bool ReturnsEntry();
151 
152   // Returns the time that has passed since the operation was created.
153   base::TimeDelta ElapsedTime() const;
154 
155   void ExecuteBackendOperation();
156   void ExecuteEntryOperation();
157 
158   raw_ptr<BackendImpl, DanglingUntriaged> backend_;
159   net::CompletionOnceCallback callback_;
160   Operation operation_ = OP_NONE;
161 
162   // Used for ops that open or create entries.
163   EntryResultCallback entry_result_callback_;
164   // if set, already has the user's ref added.
165   raw_ptr<EntryImpl, DanglingUntriaged> out_entry_ = nullptr;
166   bool out_entry_opened_ = false;
167 
168   // For GetAvailableRange
169   RangeResultCallback range_result_callback_;
170   RangeResult range_result_;
171 
172   // The arguments of all the operations we proxy:
173   std::string key_;
174   base::Time initial_time_;
175   base::Time end_time_;
176   raw_ptr<Rankings::Iterator> iterator_ = nullptr;
177   std::unique_ptr<Rankings::Iterator> scoped_iterator_;
178   raw_ptr<EntryImpl, DanglingUntriaged> entry_ = nullptr;
179   int index_ = 0;
180   int offset_ = 0;
181   scoped_refptr<net::IOBuffer> buf_;
182   int buf_len_ = 0;
183   bool truncate_ = false;
184   int64_t offset64_ = 0;
185   base::TimeTicks start_time_;
186   base::OnceClosure task_;
187 
188   scoped_refptr<base::SingleThreadTaskRunner> background_task_runner_;
189 };
190 
191 // The specialized controller that keeps track of current operations.
192 class InFlightBackendIO : public InFlightIO {
193  public:
194   InFlightBackendIO(
195       BackendImpl* backend,
196       const scoped_refptr<base::SingleThreadTaskRunner>& background_thread);
197 
198   InFlightBackendIO(const InFlightBackendIO&) = delete;
199   InFlightBackendIO& operator=(const InFlightBackendIO&) = delete;
200 
201   ~InFlightBackendIO() override;
202 
203   // Proxied operations.
204   void Init(net::CompletionOnceCallback callback);
205   void OpenOrCreateEntry(const std::string& key, EntryResultCallback callback);
206   void OpenEntry(const std::string& key, EntryResultCallback callback);
207   void CreateEntry(const std::string& key, EntryResultCallback callback);
208   void DoomEntry(const std::string& key, net::CompletionOnceCallback callback);
209   void DoomAllEntries(net::CompletionOnceCallback callback);
210   void DoomEntriesBetween(const base::Time initial_time,
211                           const base::Time end_time,
212                           net::CompletionOnceCallback callback);
213   void DoomEntriesSince(const base::Time initial_time,
214                         net::CompletionOnceCallback callback);
215   void CalculateSizeOfAllEntries(net::CompletionOnceCallback callback);
216   void OpenNextEntry(Rankings::Iterator* iterator,
217                      EntryResultCallback callback);
218   void EndEnumeration(std::unique_ptr<Rankings::Iterator> iterator);
219   void OnExternalCacheHit(const std::string& key);
220   void CloseEntryImpl(EntryImpl* entry);
221   void DoomEntryImpl(EntryImpl* entry);
222   void FlushQueue(net::CompletionOnceCallback callback);
223   void RunTask(base::OnceClosure task, net::CompletionOnceCallback callback);
224   void ReadData(EntryImpl* entry,
225                 int index,
226                 int offset,
227                 net::IOBuffer* buf,
228                 int buf_len,
229                 net::CompletionOnceCallback callback);
230   void WriteData(EntryImpl* entry,
231                  int index,
232                  int offset,
233                  net::IOBuffer* buf,
234                  int buf_len,
235                  bool truncate,
236                  net::CompletionOnceCallback callback);
237   void ReadSparseData(EntryImpl* entry,
238                       int64_t offset,
239                       net::IOBuffer* buf,
240                       int buf_len,
241                       net::CompletionOnceCallback callback);
242   void WriteSparseData(EntryImpl* entry,
243                        int64_t offset,
244                        net::IOBuffer* buf,
245                        int buf_len,
246                        net::CompletionOnceCallback callback);
247   void GetAvailableRange(EntryImpl* entry,
248                          int64_t offset,
249                          int len,
250                          RangeResultCallback callback);
251   void CancelSparseIO(EntryImpl* entry);
252   void ReadyForSparseIO(EntryImpl* entry, net::CompletionOnceCallback callback);
253 
254   // Blocks until all operations are cancelled or completed.
255   void WaitForPendingIO();
256 
background_thread()257   scoped_refptr<base::SingleThreadTaskRunner> background_thread() {
258     return background_thread_;
259   }
260 
261   // Returns true if the current sequence is the background thread.
BackgroundIsCurrentSequence()262   bool BackgroundIsCurrentSequence() {
263     return background_thread_->RunsTasksInCurrentSequence();
264   }
265 
266   base::WeakPtr<InFlightBackendIO> GetWeakPtr();
267 
268  protected:
269   void OnOperationComplete(BackgroundIO* operation, bool cancel) override;
270 
271  private:
272   void PostOperation(const base::Location& from_here, BackendIO* operation);
273   raw_ptr<BackendImpl> backend_;
274   scoped_refptr<base::SingleThreadTaskRunner> background_thread_;
275   base::WeakPtrFactory<InFlightBackendIO> ptr_factory_{this};
276 };
277 
278 }  // namespace disk_cache
279 
280 #endif  // NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_BACKEND_IO_H_
281