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 namespace { |
| 18 |
| 19 typedef disk_cache::Entry::CompletionCallback CompletionCallback; |
| 20 typedef disk_cache::SimpleSynchronousEntry::SynchronousCreationCallback |
| 21 SynchronousCreationCallback; |
| 22 typedef disk_cache::SimpleSynchronousEntry::SynchronousOperationCallback |
| 23 SynchronousOperationCallback; |
| 24 |
| 25 } // namespace |
| 26 |
| 27 namespace disk_cache { |
| 28 |
| 29 using base::FilePath; |
| 30 using base::MessageLoopProxy; |
| 31 using base::Time; |
| 32 using base::WeakPtr; |
| 33 using base::WorkerPool; |
| 34 |
| 35 // static |
| 36 int SimpleEntryImpl::OpenEntry(const FilePath& path, |
| 37 const std::string& key, |
| 38 Entry** entry, |
| 39 const CompletionCallback& callback) { |
| 40 SynchronousCreationCallback sync_creation_callback = |
| 41 base::Bind(&SimpleEntryImpl::CreationOperationComplete, callback, entry); |
| 42 WorkerPool::PostTask(FROM_HERE, |
| 43 base::Bind(&SimpleSynchronousEntry::OpenEntry, path, key, |
| 44 MessageLoopProxy::current(), |
| 45 sync_creation_callback), |
| 46 true); |
| 47 return net::ERR_IO_PENDING; |
| 48 } |
| 49 |
| 50 // static |
| 51 int SimpleEntryImpl::CreateEntry(const FilePath& path, |
| 52 const std::string& key, |
| 53 Entry** entry, |
| 54 const CompletionCallback& callback) { |
| 55 SynchronousCreationCallback sync_creation_callback = |
| 56 base::Bind(&SimpleEntryImpl::CreationOperationComplete, callback, entry); |
| 57 WorkerPool::PostTask(FROM_HERE, |
| 58 base::Bind(&SimpleSynchronousEntry::CreateEntry, path, |
| 59 key, MessageLoopProxy::current(), |
| 60 sync_creation_callback), |
| 61 true); |
| 62 return net::ERR_IO_PENDING; |
| 63 } |
| 64 |
| 65 // static |
| 66 int SimpleEntryImpl::DoomEntry(const FilePath& path, |
| 67 const std::string& key, |
| 68 const CompletionCallback& callback) { |
| 69 WorkerPool::PostTask(FROM_HERE, |
| 70 base::Bind(&SimpleSynchronousEntry::DoomEntry, path, key, |
| 71 MessageLoopProxy::current(), callback), |
| 72 true); |
| 73 return net::ERR_IO_PENDING; |
| 74 } |
| 75 |
| 76 void SimpleEntryImpl::Doom() { |
| 77 if (synchronous_entry_in_use_by_worker_) { |
| 78 NOTIMPLEMENTED(); |
| 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 if (synchronous_entry_in_use_by_worker_) { |
| 91 NOTIMPLEMENTED(); |
| 92 delete this; |
| 93 return; |
| 94 } |
| 95 DCHECK(synchronous_entry_ || has_been_doomed_); |
| 96 if (!has_been_doomed_) { |
| 97 WorkerPool::PostTask(FROM_HERE, |
| 98 base::Bind(&SimpleSynchronousEntry::Close, |
| 99 base::Unretained(synchronous_entry_)), |
| 100 true); |
| 101 synchronous_entry_ = NULL; |
| 102 } |
| 103 // Entry::Close() is expected to release this entry. See disk_cache.h for |
| 104 // details. |
| 105 delete this; |
| 106 } |
| 107 |
| 108 std::string SimpleEntryImpl::GetKey() const { |
| 109 return key_; |
| 110 } |
| 111 |
| 112 Time SimpleEntryImpl::GetLastUsed() const { |
| 113 if (synchronous_entry_in_use_by_worker_) { |
| 114 NOTIMPLEMENTED(); |
| 115 CHECK(false); |
| 116 } |
| 117 return synchronous_entry_->last_used(); |
| 118 } |
| 119 |
| 120 Time SimpleEntryImpl::GetLastModified() const { |
| 121 if (synchronous_entry_in_use_by_worker_) { |
| 122 NOTIMPLEMENTED(); |
| 123 CHECK(false); |
| 124 } |
| 125 return synchronous_entry_->last_modified(); |
| 126 } |
| 127 |
| 128 int32 SimpleEntryImpl::GetDataSize(int index) const { |
| 129 if (synchronous_entry_in_use_by_worker_) { |
| 130 NOTIMPLEMENTED(); |
| 131 CHECK(false); |
| 132 } |
| 133 return synchronous_entry_->data_size(index); |
| 134 } |
| 135 |
| 136 int SimpleEntryImpl::ReadData(int index, |
| 137 int offset, |
| 138 net::IOBuffer* buf, |
| 139 int buf_len, |
| 140 const CompletionCallback& callback) { |
| 141 // TODO(gavinp): Add support for overlapping reads. The net::HttpCache does |
| 142 // make overlapping read requests when multiple transactions access the same |
| 143 // entry as read only. |
| 144 if (synchronous_entry_in_use_by_worker_) { |
| 145 NOTIMPLEMENTED(); |
| 146 CHECK(false); |
| 147 } |
| 148 synchronous_entry_in_use_by_worker_ = true; |
| 149 SynchronousOperationCallback sync_operation_callback = |
| 150 base::Bind(&SimpleEntryImpl::EntryOperationComplete, |
| 151 callback, weak_ptr_factory_.GetWeakPtr()); |
| 152 WorkerPool::PostTask(FROM_HERE, |
| 153 base::Bind(&SimpleSynchronousEntry::ReadData, |
| 154 base::Unretained(synchronous_entry_), |
| 155 index, offset, make_scoped_refptr(buf), |
| 156 buf_len, sync_operation_callback), |
| 157 true); |
| 158 return net::ERR_IO_PENDING; |
| 159 } |
| 160 |
| 161 int SimpleEntryImpl::WriteData(int index, |
| 162 int offset, |
| 163 net::IOBuffer* buf, |
| 164 int buf_len, |
| 165 const CompletionCallback& callback, |
| 166 bool truncate) { |
| 167 if (synchronous_entry_in_use_by_worker_) { |
| 168 NOTIMPLEMENTED(); |
| 169 CHECK(false); |
| 170 } |
| 171 synchronous_entry_in_use_by_worker_ = true; |
| 172 SynchronousOperationCallback sync_operation_callback = |
| 173 base::Bind(&SimpleEntryImpl::EntryOperationComplete, |
| 174 callback, weak_ptr_factory_.GetWeakPtr()); |
| 175 WorkerPool::PostTask(FROM_HERE, |
| 176 base::Bind(&SimpleSynchronousEntry::WriteData, |
| 177 base::Unretained(synchronous_entry_), |
| 178 index, offset, make_scoped_refptr(buf), |
| 179 buf_len, sync_operation_callback, truncate), |
| 180 true); |
| 181 return net::ERR_IO_PENDING; |
| 182 } |
| 183 |
| 184 int SimpleEntryImpl::ReadSparseData(int64 offset, |
| 185 net::IOBuffer* buf, |
| 186 int buf_len, |
| 187 const CompletionCallback& callback) { |
| 188 // TODO(gavinp): Determine if the simple backend should support sparse data. |
| 189 NOTIMPLEMENTED(); |
| 190 return net::ERR_FAILED; |
| 191 } |
| 192 |
| 193 int SimpleEntryImpl::WriteSparseData(int64 offset, |
| 194 net::IOBuffer* buf, |
| 195 int buf_len, |
| 196 const CompletionCallback& callback) { |
| 197 // TODO(gavinp): Determine if the simple backend should support sparse data. |
| 198 NOTIMPLEMENTED(); |
| 199 return net::ERR_FAILED; |
| 200 } |
| 201 |
| 202 int SimpleEntryImpl::GetAvailableRange(int64 offset, |
| 203 int len, |
| 204 int64* start, |
| 205 const CompletionCallback& callback) { |
| 206 // TODO(gavinp): Determine if the simple backend should support sparse data. |
| 207 NOTIMPLEMENTED(); |
| 208 return net::ERR_FAILED; |
| 209 } |
| 210 |
| 211 bool SimpleEntryImpl::CouldBeSparse() const { |
| 212 // TODO(gavinp): Determine if the simple backend should support sparse data. |
| 213 return false; |
| 214 } |
| 215 |
| 216 void SimpleEntryImpl::CancelSparseIO() { |
| 217 // TODO(gavinp): Determine if the simple backend should support sparse data. |
| 218 NOTIMPLEMENTED(); |
| 219 } |
| 220 |
| 221 int SimpleEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) { |
| 222 // TODO(gavinp): Determine if the simple backend should support sparse data. |
| 223 NOTIMPLEMENTED(); |
| 224 return net::ERR_FAILED; |
| 225 } |
| 226 |
| 227 SimpleEntryImpl::SimpleEntryImpl( |
| 228 SimpleSynchronousEntry* synchronous_entry) |
| 229 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), |
| 230 key_(synchronous_entry->key()), |
| 231 synchronous_entry_(synchronous_entry), |
| 232 synchronous_entry_in_use_by_worker_(false), |
| 233 has_been_doomed_(false) { |
| 234 DCHECK(synchronous_entry); |
| 235 } |
| 236 |
| 237 SimpleEntryImpl::~SimpleEntryImpl() { |
| 238 DCHECK(!synchronous_entry_); |
| 239 } |
| 240 |
| 241 // static |
| 242 void SimpleEntryImpl::CreationOperationComplete( |
| 243 const CompletionCallback& completion_callback, |
| 244 Entry** out_entry, |
| 245 SimpleSynchronousEntry* sync_entry) { |
| 246 if (!sync_entry) { |
| 247 completion_callback.Run(net::ERR_FAILED); |
| 248 return; |
| 249 } |
| 250 *out_entry = new SimpleEntryImpl(sync_entry); |
| 251 completion_callback.Run(net::OK); |
| 252 } |
| 253 |
| 254 // static |
| 255 void SimpleEntryImpl::EntryOperationComplete( |
| 256 const CompletionCallback& completion_callback, |
| 257 base::WeakPtr<SimpleEntryImpl> entry, |
| 258 int result) { |
| 259 if (entry) { |
| 260 DCHECK(entry->synchronous_entry_in_use_by_worker_); |
| 261 entry->synchronous_entry_in_use_by_worker_ = false; |
| 262 } |
| 263 completion_callback.Run(result); |
| 264 } |
| 265 |
| 266 } // namespace disk_cache |
OLD | NEW |