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