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 #include "net/disk_cache/blockfile/rankings.h" 18 19 namespace disk_cache { 20 21 class BackendImpl; 22 class Entry; 23 class EntryImpl; 24 25 // This class represents a single asynchronous disk cache IO operation while it 26 // is being bounced between threads. 27 class BackendIO : public BackgroundIO { 28 public: 29 BackendIO(InFlightIO* controller, BackendImpl* backend, 30 const net::CompletionCallback& callback); 31 32 // Runs the actual operation on the background thread. 33 void ExecuteOperation(); 34 35 // Callback implementation. 36 void OnIOComplete(int result); 37 38 // Called when we are finishing this operation. If |cancel| is true, the user 39 // callback will not be invoked. 40 void OnDone(bool cancel); 41 42 // Returns true if this operation is directed to an entry (vs. the backend). 43 bool IsEntryOperation(); 44 callback()45 net::CompletionCallback callback() const { return callback_; } 46 47 // Grabs an extra reference of entry_. 48 void ReferenceEntry(); 49 50 // The operations we proxy: 51 void Init(); 52 void OpenEntry(const std::string& key, Entry** entry); 53 void CreateEntry(const std::string& key, Entry** entry); 54 void DoomEntry(const std::string& key); 55 void DoomAllEntries(); 56 void DoomEntriesBetween(const base::Time initial_time, 57 const base::Time end_time); 58 void DoomEntriesSince(const base::Time initial_time); 59 void OpenNextEntry(Rankings::Iterator* iterator, Entry** next_entry); 60 void EndEnumeration(scoped_ptr<Rankings::Iterator> 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_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 Rankings::Iterator* iterator_; 131 scoped_ptr<Rankings::Iterator> scoped_iterator_; 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( 150 BackendImpl* backend, 151 const scoped_refptr<base::SingleThreadTaskRunner>& background_thread); 152 virtual ~InFlightBackendIO(); 153 154 // Proxied operations. 155 void Init(const net::CompletionCallback& callback); 156 void OpenEntry(const std::string& key, Entry** entry, 157 const net::CompletionCallback& callback); 158 void CreateEntry(const std::string& key, Entry** entry, 159 const net::CompletionCallback& callback); 160 void DoomEntry(const std::string& key, 161 const net::CompletionCallback& callback); 162 void DoomAllEntries(const net::CompletionCallback& callback); 163 void DoomEntriesBetween(const base::Time initial_time, 164 const base::Time end_time, 165 const net::CompletionCallback& callback); 166 void DoomEntriesSince(const base::Time initial_time, 167 const net::CompletionCallback& callback); 168 void OpenNextEntry(Rankings::Iterator* iterator, Entry** next_entry, 169 const net::CompletionCallback& callback); 170 void EndEnumeration(scoped_ptr<Rankings::Iterator> iterator); 171 void OnExternalCacheHit(const std::string& key); 172 void CloseEntryImpl(EntryImpl* entry); 173 void DoomEntryImpl(EntryImpl* entry); 174 void FlushQueue(const net::CompletionCallback& callback); 175 void RunTask(const base::Closure& task, 176 const net::CompletionCallback& callback); 177 void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, 178 int buf_len, const net::CompletionCallback& callback); 179 void WriteData( 180 EntryImpl* entry, int index, int offset, net::IOBuffer* buf, 181 int buf_len, bool truncate, const net::CompletionCallback& callback); 182 void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, 183 int buf_len, const net::CompletionCallback& callback); 184 void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, 185 int buf_len, const net::CompletionCallback& callback); 186 void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start, 187 const net::CompletionCallback& callback); 188 void CancelSparseIO(EntryImpl* entry); 189 void ReadyForSparseIO(EntryImpl* entry, 190 const net::CompletionCallback& callback); 191 192 // Blocks until all operations are cancelled or completed. 193 void WaitForPendingIO(); 194 background_thread()195 scoped_refptr<base::SingleThreadTaskRunner> background_thread() { 196 return background_thread_; 197 } 198 199 // Returns true if the current thread is the background thread. BackgroundIsCurrentThread()200 bool BackgroundIsCurrentThread() { 201 return background_thread_->RunsTasksOnCurrentThread(); 202 } 203 204 base::WeakPtr<InFlightBackendIO> GetWeakPtr(); 205 206 protected: 207 virtual void OnOperationComplete(BackgroundIO* operation, 208 bool cancel) OVERRIDE; 209 210 private: 211 void PostOperation(BackendIO* operation); 212 213 BackendImpl* backend_; 214 scoped_refptr<base::SingleThreadTaskRunner> background_thread_; 215 base::WeakPtrFactory<InFlightBackendIO> ptr_factory_; 216 217 DISALLOW_COPY_AND_ASSIGN(InFlightBackendIO); 218 }; 219 220 } // namespace disk_cache 221 222 #endif // NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_BACKEND_IO_H_ 223