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