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