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 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 182 scoped_refptr<base::MessageLoopProxy> background_thread() { 183 return background_thread_; 184 } 185 186 // Returns true if the current thread is the background thread. 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