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 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 196 scoped_refptr<base::MessageLoopProxy> background_thread() { 197 return background_thread_; 198 } 199 200 // Returns true if the current thread is the background thread. 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