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