Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2013 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 #include "net/disk_cache/simple/simple_entry_impl.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/bind_helpers.h" | |
| 9 #include "base/callback.h" | |
| 10 #include "base/location.h" | |
| 11 #include "base/message_loop_proxy.h" | |
| 12 #include "base/threading/worker_pool.h" | |
| 13 #include "net/base/io_buffer.h" | |
| 14 #include "net/base/net_errors.h" | |
| 15 #include "net/disk_cache/simple/simple_synchronous_entry.h" | |
| 16 | |
| 17 | |
|
rvargas (doing something else)
2013/02/13 01:48:46
remove extra line
gavinp
2013/02/14 15:29:55
Done.
| |
| 18 namespace { | |
| 19 | |
| 20 typedef disk_cache::Entry::CompletionCallback CompletionCallback; | |
| 21 typedef disk_cache::SimpleSynchronousEntry::SynchronousEntryCallback | |
| 22 SynchronousEntryCallback; | |
| 23 | |
| 24 } // namespace | |
| 25 | |
| 26 namespace disk_cache { | |
| 27 | |
| 28 using base::FilePath; | |
| 29 using base::MessageLoopProxy; | |
| 30 using base::Time; | |
| 31 using base::WeakPtr; | |
| 32 using base::WorkerPool; | |
| 33 | |
| 34 // static | |
| 35 int SimpleEntryImpl::OpenEntry(const FilePath& path, | |
| 36 const std::string& key, | |
| 37 Entry** entry, | |
| 38 const CompletionCallback& callback) { | |
| 39 SynchronousEntryCallback sync_entry_callback = | |
| 40 base::Bind(&SimpleEntryImpl::CreationOperationComplete, callback, entry); | |
| 41 WorkerPool::PostTask(FROM_HERE, | |
| 42 base::Bind(&SimpleSynchronousEntry::OpenEntry, path, key, | |
| 43 MessageLoopProxy::current(), | |
| 44 sync_entry_callback), | |
| 45 true); | |
| 46 return net::ERR_IO_PENDING; | |
| 47 } | |
| 48 | |
| 49 // static | |
| 50 int SimpleEntryImpl::CreateEntry(const FilePath& path, | |
| 51 const std::string& key, | |
| 52 Entry** entry, | |
| 53 const CompletionCallback& callback) { | |
| 54 SynchronousEntryCallback sync_entry_callback = | |
| 55 base::Bind(&SimpleEntryImpl::CreationOperationComplete, callback, entry); | |
| 56 WorkerPool::PostTask(FROM_HERE, | |
| 57 base::Bind(&SimpleSynchronousEntry::CreateEntry, path, | |
| 58 key, MessageLoopProxy::current(), | |
| 59 sync_entry_callback), | |
| 60 true); | |
| 61 return net::ERR_IO_PENDING; | |
| 62 } | |
| 63 | |
| 64 // static | |
| 65 int SimpleEntryImpl::DoomEntry(const FilePath& path, | |
| 66 const std::string& key, | |
| 67 const CompletionCallback& callback) { | |
| 68 WorkerPool::PostTask(FROM_HERE, | |
| 69 base::Bind(&SimpleSynchronousEntry::DoomEntry, path, key, | |
| 70 MessageLoopProxy::current(), callback), | |
| 71 true); | |
| 72 return net::ERR_IO_PENDING; | |
| 73 } | |
| 74 | |
| 75 void SimpleEntryImpl::Doom() { | |
| 76 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 77 if (synchronous_entry_in_use_by_worker_) { | |
| 78 NOTIMPLEMENTED() << ": Overlapping an asynchronous operation."; | |
| 79 return; | |
| 80 } | |
| 81 WorkerPool::PostTask(FROM_HERE, | |
| 82 base::Bind(&SimpleSynchronousEntry::DoomAndClose, | |
| 83 base::Unretained(synchronous_entry_)), | |
| 84 true); | |
| 85 synchronous_entry_ = NULL; | |
| 86 has_been_doomed_ = true; | |
| 87 } | |
| 88 | |
| 89 void SimpleEntryImpl::Close() { | |
| 90 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 91 if (synchronous_entry_in_use_by_worker_) { | |
| 92 NOTIMPLEMENTED() << ": Overlapping an asynchronous operation."; | |
| 93 delete this; | |
| 94 return; | |
| 95 } | |
| 96 DCHECK(synchronous_entry_ || has_been_doomed_); | |
| 97 if (!has_been_doomed_) { | |
| 98 WorkerPool::PostTask(FROM_HERE, | |
| 99 base::Bind(&SimpleSynchronousEntry::Close, | |
| 100 base::Unretained(synchronous_entry_)), | |
| 101 true); | |
| 102 synchronous_entry_ = NULL; | |
| 103 } | |
| 104 // Entry::Close() is expected to release this entry. See disk_cache.h for | |
| 105 // details. | |
| 106 delete this; | |
| 107 } | |
| 108 | |
| 109 std::string SimpleEntryImpl::GetKey() const { | |
| 110 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 111 return key_; | |
| 112 } | |
| 113 | |
| 114 Time SimpleEntryImpl::GetLastUsed() const { | |
| 115 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 116 if (synchronous_entry_in_use_by_worker_) { | |
| 117 NOTIMPLEMENTED() << ": Synchronous operations overlapping an asynchronous " | |
| 118 << "operation."; | |
| 119 NOTREACHED(); | |
|
rvargas (doing something else)
2013/02/13 01:48:46
nit: sounds like this should be removed (not a cod
gavinp
2013/02/14 15:29:55
Done. I replaced them with CHECK(false), which is
| |
| 120 } | |
| 121 return synchronous_entry_->last_used(); | |
| 122 } | |
| 123 | |
| 124 Time SimpleEntryImpl::GetLastModified() const { | |
| 125 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 126 if (synchronous_entry_in_use_by_worker_) { | |
| 127 NOTIMPLEMENTED() << ": Synchronous operations overlapping an asynchronous " | |
| 128 << "operation."; | |
| 129 NOTREACHED(); | |
| 130 } | |
| 131 return synchronous_entry_->last_modified(); | |
| 132 } | |
| 133 | |
| 134 int32 SimpleEntryImpl::GetDataSize(int index) const { | |
| 135 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 136 if (synchronous_entry_in_use_by_worker_) { | |
| 137 NOTIMPLEMENTED() << ": Synchronous operations overlapping an asynchronous " | |
| 138 << "operation."; | |
| 139 NOTREACHED(); | |
| 140 } | |
| 141 return synchronous_entry_->data_size(index); | |
| 142 } | |
| 143 | |
| 144 int SimpleEntryImpl::ReadData(int index, | |
| 145 int offset, | |
| 146 net::IOBuffer* buf, | |
| 147 int buf_len, | |
| 148 const CompletionCallback& callback) { | |
| 149 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 150 // TODO(gavinp): Add support for overlapping reads. The net::HttpCache does | |
| 151 // make overlapping read requests when multiple transactions access the same | |
| 152 // entry as read only. | |
| 153 if (synchronous_entry_in_use_by_worker_) { | |
| 154 NOTIMPLEMENTED() << ": Overlapping calls to ReadData."; | |
| 155 NOTREACHED(); | |
| 156 } | |
| 157 synchronous_entry_in_use_by_worker_ = true; | |
| 158 SynchronousEntryCallback sync_entry_callback = | |
| 159 base::Bind(&SimpleEntryImpl::EntryOperationComplete, | |
| 160 callback, weak_ptr_factory_.GetWeakPtr()); | |
| 161 WorkerPool::PostTask(FROM_HERE, | |
| 162 base::Bind(&SimpleSynchronousEntry::ReadData, | |
| 163 base::Unretained(synchronous_entry_), | |
| 164 index, offset, scoped_refptr<IOBuffer>(buf), | |
|
rvargas (doing something else)
2013/02/13 01:48:46
make_scoped_refptr (if you want to force a scoped
gavinp
2013/02/14 15:29:55
Done.
| |
| 165 buf_len, sync_entry_callback), | |
| 166 true); | |
| 167 return net::ERR_IO_PENDING; | |
| 168 } | |
| 169 | |
| 170 int SimpleEntryImpl::WriteData(int index, | |
| 171 int offset, | |
| 172 net::IOBuffer* buf, | |
| 173 int buf_len, | |
| 174 const CompletionCallback& callback, | |
| 175 bool truncate) { | |
| 176 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 177 if (synchronous_entry_in_use_by_worker_) { | |
| 178 NOTIMPLEMENTED() << ": Overlapping calls to WriteData."; | |
| 179 NOTREACHED(); | |
| 180 } | |
| 181 synchronous_entry_in_use_by_worker_ = true; | |
| 182 SynchronousEntryCallback sync_entry_callback = | |
| 183 base::Bind(&SimpleEntryImpl::EntryOperationComplete, | |
| 184 callback, weak_ptr_factory_.GetWeakPtr()); | |
| 185 WorkerPool::PostTask(FROM_HERE, | |
| 186 base::Bind(&SimpleSynchronousEntry::WriteData, | |
| 187 base::Unretained(synchronous_entry_), | |
| 188 index, offset, scoped_refptr<IOBuffer>(buf), | |
| 189 buf_len, sync_entry_callback, truncate), | |
| 190 true); | |
| 191 return net::ERR_IO_PENDING; | |
| 192 } | |
| 193 | |
| 194 int SimpleEntryImpl::ReadSparseData(int64 offset, | |
| 195 net::IOBuffer* buf, | |
| 196 int buf_len, | |
| 197 const CompletionCallback& callback) { | |
| 198 // TODO(gavinp): Determine if the simple backend should support sparse data. | |
| 199 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 200 NOTIMPLEMENTED(); | |
| 201 return net::ERR_FAILED; | |
| 202 } | |
| 203 | |
| 204 int SimpleEntryImpl::WriteSparseData(int64 offset, | |
| 205 net::IOBuffer* buf, | |
| 206 int buf_len, | |
| 207 const CompletionCallback& callback) { | |
| 208 // TODO(gavinp): Determine if the simple backend should support sparse data. | |
| 209 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 210 NOTIMPLEMENTED(); | |
| 211 return net::ERR_FAILED; | |
| 212 } | |
| 213 | |
| 214 int SimpleEntryImpl::GetAvailableRange(int64 offset, | |
| 215 int len, | |
| 216 int64* start, | |
| 217 const CompletionCallback& callback) { | |
| 218 // TODO(gavinp): Determine if the simple backend should support sparse data. | |
| 219 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 220 NOTIMPLEMENTED(); | |
| 221 return net::ERR_FAILED; | |
| 222 } | |
| 223 | |
| 224 bool SimpleEntryImpl::CouldBeSparse() const { | |
| 225 // TODO(gavinp): Determine if the simple backend should support sparse data. | |
| 226 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 227 return false; | |
| 228 } | |
| 229 | |
| 230 void SimpleEntryImpl::CancelSparseIO() { | |
| 231 // TODO(gavinp): Determine if the simple backend should support sparse data. | |
| 232 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 233 NOTIMPLEMENTED(); | |
| 234 } | |
| 235 | |
| 236 int SimpleEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) { | |
| 237 // TODO(gavinp): Determine if the simple backend should support sparse data. | |
| 238 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 239 NOTIMPLEMENTED(); | |
| 240 return net::ERR_FAILED; | |
| 241 } | |
| 242 | |
| 243 SimpleEntryImpl::SimpleEntryImpl( | |
| 244 SimpleSynchronousEntry* synchronous_entry) | |
| 245 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), | |
| 246 key_(synchronous_entry->key()), | |
| 247 synchronous_entry_(synchronous_entry), | |
| 248 synchronous_entry_in_use_by_worker_(false), | |
| 249 has_been_doomed_(false) { | |
| 250 DCHECK(synchronous_entry); | |
| 251 } | |
| 252 | |
| 253 SimpleEntryImpl::~SimpleEntryImpl() { | |
| 254 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 255 DCHECK(!synchronous_entry_) << "synchronous_entry_ = " << synchronous_entry_; | |
|
rvargas (doing something else)
2013/02/13 01:48:46
In general I would not bother to add more logging
gavinp
2013/02/14 15:29:55
Done.
| |
| 256 } | |
| 257 | |
| 258 // static | |
| 259 void SimpleEntryImpl::CreationOperationComplete( | |
| 260 const CompletionCallback& completion_callback, | |
| 261 Entry** out_entry, | |
| 262 SimpleSynchronousEntry* sync_entry, | |
| 263 int result) { | |
| 264 DCHECK_NE(net::ERR_IO_PENDING, result); | |
| 265 | |
| 266 if (result != net::OK) { | |
| 267 DCHECK(!sync_entry) << "sync_entry = " << sync_entry; | |
| 268 completion_callback.Run(result); | |
| 269 return; | |
| 270 } | |
| 271 DCHECK(sync_entry); | |
| 272 *out_entry = new SimpleEntryImpl(sync_entry); | |
| 273 DCHECK(*out_entry); | |
| 274 completion_callback.Run(net::OK); | |
| 275 } | |
| 276 | |
| 277 // static | |
| 278 void SimpleEntryImpl::EntryOperationComplete( | |
| 279 const CompletionCallback& completion_callback, | |
| 280 base::WeakPtr<SimpleEntryImpl> entry, | |
| 281 SimpleSynchronousEntry* sync_entry, | |
|
rvargas (doing something else)
2013/02/13 01:48:46
is it really worth passing sync_entry back just to
gavinp
2013/02/14 15:29:55
No. Removed.
| |
| 282 int result) { | |
| 283 DCHECK(sync_entry); | |
| 284 if (entry) { | |
| 285 DCHECK(entry->synchronous_entry_in_use_by_worker_); | |
| 286 DCHECK_EQ(entry->synchronous_entry_, sync_entry); | |
| 287 entry->synchronous_entry_in_use_by_worker_ = false; | |
| 288 } | |
| 289 completion_callback.Run(result); | |
| 290 } | |
| 291 | |
| 292 } // namespace disk_cache | |
| OLD | NEW |