in_flight_backend_io.h revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
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 18namespace disk_cache { 19 20class BackendImpl; 21class Entry; 22class EntryImpl; 23 24// This class represents a single asynchronous disk cache IO operation while it 25// is being bounced between threads. 26class BackendIO : public BackgroundIO { 27 public: 28 BackendIO(InFlightIO* controller, BackendImpl* backend, 29 const 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 // Called when we are finishing this operation. If |cancel| is true, the user 38 // callback will not be invoked. 39 void OnDone(bool cancel); 40 41 // Returns true if this operation is directed to an entry (vs. the backend). 42 bool IsEntryOperation(); 43 44 net::CompletionCallback callback() const { return callback_; } 45 46 // Grabs an extra reference of entry_. 47 void ReferenceEntry(); 48 49 // The operations we proxy: 50 void Init(); 51 void OpenEntry(const std::string& key, Entry** entry); 52 void CreateEntry(const std::string& key, Entry** entry); 53 void DoomEntry(const std::string& key); 54 void DoomAllEntries(); 55 void DoomEntriesBetween(const base::Time initial_time, 56 const base::Time end_time); 57 void DoomEntriesSince(const base::Time initial_time); 58 void OpenNextEntry(void** iter, Entry** next_entry); 59 void OpenPrevEntry(void** iter, Entry** prev_entry); 60 void EndEnumeration(void* 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_OPEN_PREV, 95 OP_END_ENUMERATION, 96 OP_ON_EXTERNAL_CACHE_HIT, 97 OP_CLOSE_ENTRY, 98 OP_DOOM_ENTRY, 99 OP_FLUSH_QUEUE, 100 OP_RUN_TASK, 101 OP_MAX_BACKEND, 102 OP_READ, 103 OP_WRITE, 104 OP_READ_SPARSE, 105 OP_WRITE_SPARSE, 106 OP_GET_RANGE, 107 OP_CANCEL_IO, 108 OP_IS_READY 109 }; 110 111 virtual ~BackendIO(); 112 113 // Returns true if this operation returns an entry. 114 bool ReturnsEntry(); 115 116 // Returns the time that has passed since the operation was created. 117 base::TimeDelta ElapsedTime() const; 118 119 void ExecuteBackendOperation(); 120 void ExecuteEntryOperation(); 121 122 BackendImpl* backend_; 123 net::CompletionCallback callback_; 124 Operation operation_; 125 126 // The arguments of all the operations we proxy: 127 std::string key_; 128 Entry** entry_ptr_; 129 base::Time initial_time_; 130 base::Time end_time_; 131 void** iter_ptr_; 132 void* iter_; 133 EntryImpl* entry_; 134 int index_; 135 int offset_; 136 scoped_refptr<net::IOBuffer> buf_; 137 int buf_len_; 138 bool truncate_; 139 int64 offset64_; 140 int64* start_; 141 base::TimeTicks start_time_; 142 base::Closure task_; 143 144 DISALLOW_COPY_AND_ASSIGN(BackendIO); 145}; 146 147// The specialized controller that keeps track of current operations. 148class InFlightBackendIO : public InFlightIO { 149 public: 150 InFlightBackendIO( 151 BackendImpl* backend, 152 const scoped_refptr<base::SingleThreadTaskRunner>& background_thread); 153 virtual ~InFlightBackendIO(); 154 155 // Proxied operations. 156 void Init(const net::CompletionCallback& callback); 157 void OpenEntry(const std::string& key, Entry** entry, 158 const net::CompletionCallback& callback); 159 void CreateEntry(const std::string& key, Entry** entry, 160 const net::CompletionCallback& callback); 161 void DoomEntry(const std::string& key, 162 const net::CompletionCallback& callback); 163 void DoomAllEntries(const net::CompletionCallback& callback); 164 void DoomEntriesBetween(const base::Time initial_time, 165 const base::Time end_time, 166 const net::CompletionCallback& callback); 167 void DoomEntriesSince(const base::Time initial_time, 168 const net::CompletionCallback& callback); 169 void OpenNextEntry(void** iter, Entry** next_entry, 170 const net::CompletionCallback& callback); 171 void OpenPrevEntry(void** iter, Entry** prev_entry, 172 const net::CompletionCallback& callback); 173 void EndEnumeration(void* iterator); 174 void OnExternalCacheHit(const std::string& key); 175 void CloseEntryImpl(EntryImpl* entry); 176 void DoomEntryImpl(EntryImpl* entry); 177 void FlushQueue(const net::CompletionCallback& callback); 178 void RunTask(const base::Closure& task, 179 const net::CompletionCallback& callback); 180 void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, 181 int buf_len, const net::CompletionCallback& callback); 182 void WriteData( 183 EntryImpl* entry, int index, int offset, net::IOBuffer* buf, 184 int buf_len, bool truncate, const net::CompletionCallback& callback); 185 void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, 186 int buf_len, const net::CompletionCallback& callback); 187 void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, 188 int buf_len, const net::CompletionCallback& callback); 189 void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start, 190 const net::CompletionCallback& callback); 191 void CancelSparseIO(EntryImpl* entry); 192 void ReadyForSparseIO(EntryImpl* entry, 193 const net::CompletionCallback& callback); 194 195 // Blocks until all operations are cancelled or completed. 196 void WaitForPendingIO(); 197 198 scoped_refptr<base::SingleThreadTaskRunner> background_thread() { 199 return background_thread_; 200 } 201 202 // Returns true if the current thread is the background thread. 203 bool BackgroundIsCurrentThread() { 204 return background_thread_->RunsTasksOnCurrentThread(); 205 } 206 207 base::WeakPtr<InFlightBackendIO> GetWeakPtr(); 208 209 protected: 210 virtual void OnOperationComplete(BackgroundIO* operation, 211 bool cancel) OVERRIDE; 212 213 private: 214 void PostOperation(BackendIO* operation); 215 216 BackendImpl* backend_; 217 scoped_refptr<base::SingleThreadTaskRunner> background_thread_; 218 base::WeakPtrFactory<InFlightBackendIO> ptr_factory_; 219 220 DISALLOW_COPY_AND_ASSIGN(InFlightBackendIO); 221}; 222 223} // namespace disk_cache 224 225#endif // NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_BACKEND_IO_H_ 226