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/very_simple/very_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/net_errors.h" | |
| 14 #include "net/disk_cache/very_simple/very_simple_synchronous_entry.h" | |
| 15 | |
| 16 namespace disk_cache { | |
| 17 | |
| 18 using base::Bind; | |
| 19 using base::Callback; | |
| 20 using base::FilePath; | |
| 21 using base::MessageLoopProxy; | |
| 22 using base::Owned; | |
| 23 using base::Time; | |
| 24 using base::Unretained; | |
| 25 using base::WorkerPool; | |
| 26 | |
| 27 namespace { | |
|
rvargas (doing something else)
2013/02/06 03:28:40
nit: can this be out of disk_cache?
gavinp
2013/02/08 23:17:51
Done.
| |
| 28 | |
| 29 typedef Entry::CompletionCallback CompletionCallback; | |
| 30 typedef VerySimpleSynchronousEntry::SynchronousEntryCallback | |
| 31 SynchronousEntryCallback; | |
| 32 typedef Callback<VerySimpleEntryImpl*(VerySimpleSynchronousEntry*)> | |
| 33 EntryFactoryCallback; | |
| 34 typedef Callback<void(VerySimpleSynchronousEntry*)> SetSyncCallback; | |
| 35 | |
| 36 // PendingCreationOperation represents a pending operation that is creating a | |
| 37 // new VerySimpleSynchronousEntry, such as OpenEntry() or CreateEntry(). After | |
| 38 // the new synchronous entry has been created, it uses its factory to create | |
| 39 // a VerySimpleEntryImpl and pass it back to the original caller. | |
| 40 class PendingCreationOperation { | |
| 41 public: | |
| 42 static SynchronousEntryCallback Create( | |
| 43 const EntryFactoryCallback& entry_factory_callback, | |
| 44 const CompletionCallback& completion_callback, | |
| 45 Entry** out_entry) { | |
| 46 PendingCreationOperation* operation = | |
|
rvargas (doing something else)
2013/02/06 03:28:40
Could you separate the implementation from the dec
gavinp
2013/02/08 23:17:51
Done.
| |
| 47 new PendingCreationOperation(entry_factory_callback, | |
| 48 completion_callback, | |
| 49 out_entry); | |
| 50 DCHECK(operation); | |
| 51 return Bind(&PendingCreationOperation::OnIOComplete, | |
| 52 Owned(operation)); | |
| 53 } | |
| 54 | |
| 55 private: | |
| 56 PendingCreationOperation(const EntryFactoryCallback& entry_factory_callback, | |
| 57 const CompletionCallback& completion_callback, | |
| 58 Entry** out_entry) | |
| 59 : entry_factory_callback_(entry_factory_callback), | |
| 60 completion_callback_(completion_callback), | |
| 61 out_entry_(out_entry) { | |
| 62 } | |
| 63 | |
| 64 void OnIOComplete(VerySimpleSynchronousEntry* sync_entry, int result) { | |
| 65 DCHECK_NE(net::ERR_IO_PENDING, result); | |
| 66 | |
| 67 if (result != net::OK) { | |
| 68 DCHECK_EQ(static_cast<VerySimpleSynchronousEntry*>(NULL), sync_entry); | |
|
rvargas (doing something else)
2013/02/06 03:28:40
nit: DCHECK(!sync_entry)
gavinp
2013/02/08 23:17:51
Done. I had to add some printing cruft, since othe
| |
| 69 completion_callback_.Run(result); | |
| 70 return; | |
| 71 } | |
| 72 DCHECK(sync_entry); | |
| 73 *out_entry_ = entry_factory_callback_.Run(sync_entry); | |
|
rvargas (doing something else)
2013/02/06 03:28:40
I'm not so happy with this pattern of run a task a
gavinp
2013/02/08 23:17:51
I'm sorry to hear you're unhappy with this pattern
| |
| 74 DCHECK(*out_entry_); | |
| 75 completion_callback_.Run(net::OK); | |
| 76 } | |
| 77 | |
| 78 EntryFactoryCallback entry_factory_callback_; | |
| 79 CompletionCallback completion_callback_; | |
| 80 Entry** out_entry_; | |
| 81 }; | |
| 82 | |
| 83 class PendingOperation { | |
|
rvargas (doing something else)
2013/02/06 03:28:40
nit: class description
gavinp
2013/02/08 23:17:51
Done.
| |
| 84 public: | |
| 85 static SynchronousEntryCallback Create( | |
| 86 const SetSyncCallback& set_sync_callback, | |
| 87 const CompletionCallback& completion_callback) { | |
| 88 PendingOperation* operation = new PendingOperation(set_sync_callback, | |
|
rvargas (doing something else)
2013/02/06 03:28:40
ditto (implementation vs declaration)
gavinp
2013/02/08 23:17:51
Done.
| |
| 89 completion_callback); | |
| 90 DCHECK(operation); | |
| 91 return Bind(&PendingOperation::OnIOComplete, Owned(operation)); | |
| 92 } | |
| 93 | |
| 94 private: | |
| 95 PendingOperation(const SetSyncCallback& set_sync_callback, | |
| 96 const CompletionCallback& completion_callback) | |
| 97 : set_sync_callback_(set_sync_callback), | |
| 98 completion_callback_(completion_callback) { | |
| 99 } | |
| 100 | |
| 101 void OnIOComplete(VerySimpleSynchronousEntry* sync_entry, int result) { | |
| 102 set_sync_callback_.Run(sync_entry); | |
|
rvargas (doing something else)
2013/02/06 03:28:40
ditto
| |
| 103 completion_callback_.Run(result); | |
| 104 } | |
| 105 | |
| 106 SetSyncCallback set_sync_callback_; | |
| 107 CompletionCallback completion_callback_; | |
| 108 }; | |
| 109 | |
| 110 } // namespace | |
| 111 | |
| 112 // static | |
| 113 int VerySimpleEntryImpl::OpenEntry(const FilePath& path, | |
| 114 const std::string& key, | |
| 115 Entry** entry, | |
| 116 const CompletionCallback& callback) { | |
| 117 SynchronousEntryCallback sync_entry_callback = | |
| 118 PendingCreationOperation::Create( | |
| 119 Bind(&VerySimpleEntryImpl::Create), callback, entry); | |
| 120 WorkerPool::PostTask(FROM_HERE, | |
|
rvargas (doing something else)
2013/02/06 03:28:40
You know that in general we don't like the worker
gavinp
2013/02/08 23:17:51
I don't know this. Can you expand on this?
rvargas (doing something else)
2013/02/13 01:48:46
That is documented on the header of worker pool.
| |
| 121 Bind(&VerySimpleSynchronousEntry::OpenEntry, path, key, | |
| 122 MessageLoopProxy::current(), | |
| 123 sync_entry_callback), | |
| 124 true); | |
| 125 return net::ERR_IO_PENDING; | |
| 126 } | |
| 127 | |
| 128 // static | |
| 129 int VerySimpleEntryImpl::CreateEntry(const FilePath& path, | |
| 130 const std::string& key, | |
| 131 Entry** entry, | |
| 132 const CompletionCallback& callback) { | |
| 133 SynchronousEntryCallback sync_entry_callback = | |
| 134 PendingCreationOperation::Create( | |
| 135 Bind(&VerySimpleEntryImpl::Create), callback, entry); | |
| 136 WorkerPool::PostTask(FROM_HERE, | |
| 137 Bind(&VerySimpleSynchronousEntry::CreateEntry, path, key, | |
| 138 MessageLoopProxy::current(), | |
| 139 sync_entry_callback), | |
| 140 true); | |
| 141 return net::ERR_IO_PENDING; | |
| 142 } | |
| 143 | |
| 144 // static | |
| 145 int VerySimpleEntryImpl::DoomEntry(const FilePath& path, | |
| 146 const std::string& key, | |
| 147 const CompletionCallback& callback) { | |
| 148 WorkerPool::PostTask(FROM_HERE, | |
| 149 Bind(&VerySimpleSynchronousEntry::DoomEntry, path, key, | |
| 150 MessageLoopProxy::current(), callback), | |
| 151 true); | |
| 152 return net::ERR_IO_PENDING; | |
| 153 } | |
| 154 | |
| 155 void VerySimpleEntryImpl::Doom() { | |
| 156 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 157 WorkerPool::PostTask(FROM_HERE, | |
| 158 Bind(&VerySimpleSynchronousEntry::DoomAndClose, | |
|
rvargas (doing something else)
2013/02/06 03:28:40
DoomAndClose?
gavinp
2013/02/08 23:17:51
DoomAndClose!
rvargas (doing something else)
2013/02/13 01:48:46
I meant it was surprising behavior. As far as I ca
| |
| 159 Unretained(ReleaseSynchronousEntry())), | |
| 160 true); | |
| 161 has_been_doomed_ = true; | |
| 162 } | |
| 163 | |
| 164 void VerySimpleEntryImpl::Close() { | |
| 165 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 166 if (!has_been_doomed_) { | |
| 167 WorkerPool::PostTask(FROM_HERE, | |
| 168 Bind(&VerySimpleSynchronousEntry::Close, | |
| 169 Unretained(ReleaseSynchronousEntry())), | |
| 170 true); | |
| 171 } | |
| 172 // Entry::Close() is expected to release this entry. See disk_cache.h for | |
| 173 // details. | |
| 174 delete this; | |
| 175 } | |
| 176 | |
| 177 std::string VerySimpleEntryImpl::GetKey() const { | |
| 178 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 179 return key_; | |
| 180 } | |
| 181 | |
| 182 Time VerySimpleEntryImpl::GetLastUsed() const { | |
| 183 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 184 DCHECK(synchronous_entry_); | |
| 185 return synchronous_entry_->last_used(); | |
| 186 } | |
| 187 | |
| 188 Time VerySimpleEntryImpl::GetLastModified() const { | |
| 189 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 190 DCHECK(synchronous_entry_); | |
| 191 return synchronous_entry_->last_modified(); | |
| 192 } | |
| 193 | |
| 194 int32 VerySimpleEntryImpl::GetDataSize(int index) const { | |
| 195 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 196 DCHECK(synchronous_entry_); | |
| 197 return synchronous_entry_->data_size(index); | |
| 198 } | |
| 199 | |
| 200 int VerySimpleEntryImpl::ReadData(int index, | |
| 201 int offset, | |
| 202 net::IOBuffer* buf, | |
| 203 int buf_len, | |
| 204 const CompletionCallback& callback) { | |
| 205 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 206 DCHECK(synchronous_entry_); | |
| 207 SynchronousEntryCallback sync_entry_callback = | |
| 208 PendingOperation::Create(Bind(&VerySimpleEntryImpl::SetSynchronousEntry, | |
| 209 weak_ptr_factory_.GetWeakPtr()), | |
| 210 callback); | |
| 211 WorkerPool::PostTask(FROM_HERE, | |
| 212 Bind(&VerySimpleSynchronousEntry::ReadData, | |
| 213 Unretained(ReleaseSynchronousEntry()), index, | |
|
rvargas (doing something else)
2013/02/06 03:28:40
is this intended to enforce exclusive access to si
gavinp
2013/02/08 23:17:51
This is intended to enforce thread safety, and the
| |
| 214 offset, Unretained(buf), buf_len, | |
|
rvargas (doing something else)
2013/02/06 03:28:40
cannot be unretained
gavinp
2013/02/08 23:17:51
Tell me more?
rvargas (doing something else)
2013/02/13 01:48:46
that would mean keeping the buffer without grabbin
| |
| 215 sync_entry_callback), | |
| 216 true); | |
| 217 return net::ERR_IO_PENDING; | |
| 218 } | |
| 219 | |
| 220 int VerySimpleEntryImpl::WriteData(int index, | |
| 221 int offset, | |
| 222 net::IOBuffer* buf, | |
| 223 int buf_len, | |
| 224 const CompletionCallback& callback, | |
| 225 bool truncate) { | |
| 226 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 227 DCHECK(synchronous_entry_); | |
| 228 SynchronousEntryCallback sync_entry_callback = | |
| 229 PendingOperation::Create(Bind(&VerySimpleEntryImpl::SetSynchronousEntry, | |
| 230 weak_ptr_factory_.GetWeakPtr()), | |
| 231 callback); | |
| 232 WorkerPool::PostTask(FROM_HERE, | |
| 233 Bind(&VerySimpleSynchronousEntry::WriteData, | |
| 234 Unretained(ReleaseSynchronousEntry()), index, | |
| 235 offset, Unretained(buf), buf_len, | |
| 236 sync_entry_callback, truncate), | |
| 237 true); | |
| 238 return net::ERR_IO_PENDING; | |
| 239 } | |
| 240 | |
| 241 int VerySimpleEntryImpl::ReadSparseData(int64 offset, | |
| 242 net::IOBuffer* buf, | |
| 243 int buf_len, | |
| 244 const CompletionCallback& callback) { | |
| 245 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 246 return net::ERR_FAILED; | |
| 247 } | |
| 248 | |
| 249 int VerySimpleEntryImpl::WriteSparseData(int64 offset, | |
| 250 net::IOBuffer* buf, | |
| 251 int buf_len, | |
| 252 const CompletionCallback& callback) { | |
| 253 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 254 return net::ERR_FAILED; | |
| 255 } | |
| 256 | |
| 257 int VerySimpleEntryImpl::GetAvailableRange(int64 offset, | |
| 258 int len, | |
| 259 int64* start, | |
| 260 const CompletionCallback& callback) { | |
| 261 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 262 return net::ERR_FAILED; | |
| 263 } | |
| 264 | |
| 265 bool VerySimpleEntryImpl::CouldBeSparse() const { | |
| 266 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 267 return false; | |
| 268 } | |
| 269 | |
| 270 void VerySimpleEntryImpl::CancelSparseIO() { | |
| 271 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 272 } | |
| 273 | |
| 274 int VerySimpleEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) { | |
| 275 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 276 return net::ERR_FAILED; | |
| 277 } | |
| 278 | |
| 279 VerySimpleEntryImpl::VerySimpleEntryImpl( | |
| 280 VerySimpleSynchronousEntry* synchronous_entry) | |
| 281 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), | |
| 282 key_(synchronous_entry->key()), | |
|
rvargas (doing something else)
2013/02/06 03:28:40
why duplicate the key?
gavinp
2013/02/08 23:17:51
Thread safe access. In practice, if SimpleSynchron
rvargas (doing something else)
2013/02/13 01:48:46
The code is happy to reach into access times and s
| |
| 283 synchronous_entry_(synchronous_entry), | |
| 284 has_been_doomed_(false) { | |
| 285 DCHECK(synchronous_entry); | |
| 286 } | |
| 287 | |
| 288 VerySimpleEntryImpl::~VerySimpleEntryImpl() { | |
| 289 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 290 DCHECK_EQ(static_cast<VerySimpleSynchronousEntry*>(NULL), synchronous_entry_); | |
|
rvargas (doing something else)
2013/02/06 03:28:40
!sync_entry_
gavinp
2013/02/08 23:17:51
Done.
| |
| 291 } | |
| 292 | |
| 293 // static | |
| 294 VerySimpleEntryImpl* VerySimpleEntryImpl::Create( | |
| 295 VerySimpleSynchronousEntry* synchronous_entry) { | |
| 296 return new VerySimpleEntryImpl(synchronous_entry); | |
| 297 } | |
| 298 | |
| 299 VerySimpleSynchronousEntry* VerySimpleEntryImpl::ReleaseSynchronousEntry() { | |
| 300 DCHECK(synchronous_entry_); | |
| 301 VerySimpleSynchronousEntry* retval = synchronous_entry_; | |
| 302 synchronous_entry_ = NULL; | |
| 303 return retval; | |
| 304 } | |
| 305 | |
| 306 void VerySimpleEntryImpl::SetSynchronousEntry( | |
| 307 VerySimpleSynchronousEntry* synchronous_entry) { | |
| 308 DCHECK_EQ(static_cast<VerySimpleSynchronousEntry*>(NULL), synchronous_entry_); | |
| 309 synchronous_entry_ = synchronous_entry; | |
| 310 } | |
| 311 | |
| 312 } // namespace disk_cache | |
| OLD | NEW |