| OLD | NEW | 
|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "net/disk_cache/simple/simple_entry_impl.h" | 5 #include "net/disk_cache/simple/simple_entry_impl.h" | 
| 6 | 6 | 
| 7 #include "base/bind.h" | 7 #include "base/bind.h" | 
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" | 
| 9 #include "base/callback.h" | 9 #include "base/callback.h" | 
| 10 #include "base/location.h" | 10 #include "base/location.h" | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 27 }  // namespace | 27 }  // namespace | 
| 28 | 28 | 
| 29 namespace disk_cache { | 29 namespace disk_cache { | 
| 30 | 30 | 
| 31 using base::FilePath; | 31 using base::FilePath; | 
| 32 using base::MessageLoopProxy; | 32 using base::MessageLoopProxy; | 
| 33 using base::Time; | 33 using base::Time; | 
| 34 using base::WorkerPool; | 34 using base::WorkerPool; | 
| 35 | 35 | 
| 36 // static | 36 // static | 
| 37 int SimpleEntryImpl::OpenEntry(const scoped_refptr<SimpleIndex>& index, | 37 int SimpleEntryImpl::OpenEntry(SimpleIndex* index, | 
| 38                                const FilePath& path, | 38                                const FilePath& path, | 
| 39                                const std::string& key, | 39                                const std::string& key, | 
| 40                                Entry** entry, | 40                                Entry** entry, | 
| 41                                const CompletionCallback& callback) { | 41                                const CompletionCallback& callback) { | 
| 42   // TODO(gavinp): More closely unify the last_used_ in the | 42   // TODO(gavinp): More closely unify the last_used_ in the | 
| 43   // SimpleSynchronousEntry  and the SimpleIndex. | 43   // SimpleSynchronousEntry  and the SimpleIndex. | 
| 44   if (!index || index->UseIfExists(key)) { | 44   if (!index || index->UseIfExists(key)) { | 
| 45     scoped_refptr<SimpleEntryImpl> new_entry = | 45     scoped_refptr<SimpleEntryImpl> new_entry = | 
| 46         new SimpleEntryImpl(index, path, key); | 46         new SimpleEntryImpl(index, path, key); | 
| 47     SynchronousCreationCallback sync_creation_callback = | 47     SynchronousCreationCallback sync_creation_callback = | 
| 48         base::Bind(&SimpleEntryImpl::CreationOperationComplete, | 48         base::Bind(&SimpleEntryImpl::CreationOperationComplete, | 
| 49                    new_entry, entry, callback); | 49                    new_entry, entry, callback); | 
| 50     WorkerPool::PostTask(FROM_HERE, | 50     WorkerPool::PostTask(FROM_HERE, | 
| 51                          base::Bind(&SimpleSynchronousEntry::OpenEntry, path, | 51                          base::Bind(&SimpleSynchronousEntry::OpenEntry, path, | 
| 52                                     key, MessageLoopProxy::current(), | 52                                     key, MessageLoopProxy::current(), | 
| 53                                     sync_creation_callback), | 53                                     sync_creation_callback), | 
| 54                          true); | 54                          true); | 
| 55     return net::ERR_IO_PENDING; | 55     return net::ERR_IO_PENDING; | 
| 56   } | 56   } | 
| 57   return net::ERR_FAILED; | 57   return net::ERR_FAILED; | 
| 58 } | 58 } | 
| 59 | 59 | 
| 60 // static | 60 // static | 
| 61 int SimpleEntryImpl::CreateEntry(const scoped_refptr<SimpleIndex>& index, | 61 int SimpleEntryImpl::CreateEntry(SimpleIndex* index, | 
| 62                                  const FilePath& path, | 62                                  const FilePath& path, | 
| 63                                  const std::string& key, | 63                                  const std::string& key, | 
| 64                                  Entry** entry, | 64                                  Entry** entry, | 
| 65                                  const CompletionCallback& callback) { | 65                                  const CompletionCallback& callback) { | 
| 66   scoped_refptr<SimpleEntryImpl> new_entry = | 66   scoped_refptr<SimpleEntryImpl> new_entry = | 
| 67       new SimpleEntryImpl(index, path, key); | 67       new SimpleEntryImpl(index, path, key); | 
| 68   SynchronousCreationCallback sync_creation_callback = | 68   SynchronousCreationCallback sync_creation_callback = | 
| 69       base::Bind(&SimpleEntryImpl::CreationOperationComplete, | 69       base::Bind(&SimpleEntryImpl::CreationOperationComplete, | 
| 70                  new_entry, entry, callback); | 70                  new_entry, entry, callback); | 
| 71   WorkerPool::PostTask(FROM_HERE, | 71   WorkerPool::PostTask(FROM_HERE, | 
| 72                        base::Bind(&SimpleSynchronousEntry::CreateEntry, path, | 72                        base::Bind(&SimpleSynchronousEntry::CreateEntry, path, | 
| 73                                   key, MessageLoopProxy::current(), | 73                                   key, MessageLoopProxy::current(), | 
| 74                                   sync_creation_callback), | 74                                   sync_creation_callback), | 
| 75                        true); | 75                        true); | 
| 76   return net::ERR_IO_PENDING; | 76   return net::ERR_IO_PENDING; | 
| 77 } | 77 } | 
| 78 | 78 | 
| 79 // static | 79 // static | 
| 80 int SimpleEntryImpl::DoomEntry(const scoped_refptr<SimpleIndex>& index, | 80 int SimpleEntryImpl::DoomEntry(SimpleIndex* index, | 
| 81                                const FilePath& path, | 81                                const FilePath& path, | 
| 82                                const std::string& key, | 82                                const std::string& key, | 
| 83                                const CompletionCallback& callback) { | 83                                const CompletionCallback& callback) { | 
| 84   index->Remove(key); | 84   index->Remove(key); | 
| 85   WorkerPool::PostTask(FROM_HERE, | 85   WorkerPool::PostTask(FROM_HERE, | 
| 86                        base::Bind(&SimpleSynchronousEntry::DoomEntry, path, key, | 86                        base::Bind(&SimpleSynchronousEntry::DoomEntry, path, key, | 
| 87                                   MessageLoopProxy::current(), callback), | 87                                   MessageLoopProxy::current(), callback), | 
| 88                        true); | 88                        true); | 
| 89   return net::ERR_IO_PENDING; | 89   return net::ERR_IO_PENDING; | 
| 90 } | 90 } | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 136   DCHECK(io_thread_checker_.CalledOnValidThread()); | 136   DCHECK(io_thread_checker_.CalledOnValidThread()); | 
| 137   // TODO(gavinp): Add support for overlapping reads. The net::HttpCache does | 137   // TODO(gavinp): Add support for overlapping reads. The net::HttpCache does | 
| 138   // make overlapping read requests when multiple transactions access the same | 138   // make overlapping read requests when multiple transactions access the same | 
| 139   // entry as read only. This might make calling SimpleSynchronousEntry::Close() | 139   // entry as read only. This might make calling SimpleSynchronousEntry::Close() | 
| 140   // correctly more tricky (see SimpleEntryImpl::EntryOperationComplete). | 140   // correctly more tricky (see SimpleEntryImpl::EntryOperationComplete). | 
| 141   if (synchronous_entry_in_use_by_worker_) { | 141   if (synchronous_entry_in_use_by_worker_) { | 
| 142     NOTIMPLEMENTED(); | 142     NOTIMPLEMENTED(); | 
| 143     CHECK(false); | 143     CHECK(false); | 
| 144   } | 144   } | 
| 145   synchronous_entry_in_use_by_worker_ = true; | 145   synchronous_entry_in_use_by_worker_ = true; | 
| 146   index_->UseIfExists(key_); | 146   if (index_) | 
|  | 147     index_->UseIfExists(key_); | 
| 147   SynchronousOperationCallback sync_operation_callback = | 148   SynchronousOperationCallback sync_operation_callback = | 
| 148       base::Bind(&SimpleEntryImpl::EntryOperationComplete, | 149       base::Bind(&SimpleEntryImpl::EntryOperationComplete, | 
| 149                  this, callback); | 150                  this, callback); | 
| 150   WorkerPool::PostTask(FROM_HERE, | 151   WorkerPool::PostTask(FROM_HERE, | 
| 151                        base::Bind(&SimpleSynchronousEntry::ReadData, | 152                        base::Bind(&SimpleSynchronousEntry::ReadData, | 
| 152                                   base::Unretained(synchronous_entry_), | 153                                   base::Unretained(synchronous_entry_), | 
| 153                                   index, offset, make_scoped_refptr(buf), | 154                                   index, offset, make_scoped_refptr(buf), | 
| 154                                   buf_len, sync_operation_callback), | 155                                   buf_len, sync_operation_callback), | 
| 155                        true); | 156                        true); | 
| 156   return net::ERR_IO_PENDING; | 157   return net::ERR_IO_PENDING; | 
| 157 } | 158 } | 
| 158 | 159 | 
| 159 int SimpleEntryImpl::WriteData(int index, | 160 int SimpleEntryImpl::WriteData(int index, | 
| 160                                int offset, | 161                                int offset, | 
| 161                                net::IOBuffer* buf, | 162                                net::IOBuffer* buf, | 
| 162                                int buf_len, | 163                                int buf_len, | 
| 163                                const CompletionCallback& callback, | 164                                const CompletionCallback& callback, | 
| 164                                bool truncate) { | 165                                bool truncate) { | 
| 165   DCHECK(io_thread_checker_.CalledOnValidThread()); | 166   DCHECK(io_thread_checker_.CalledOnValidThread()); | 
| 166   if (synchronous_entry_in_use_by_worker_) { | 167   if (synchronous_entry_in_use_by_worker_) { | 
| 167     NOTIMPLEMENTED(); | 168     NOTIMPLEMENTED(); | 
| 168     CHECK(false); | 169     CHECK(false); | 
| 169   } | 170   } | 
| 170   synchronous_entry_in_use_by_worker_ = true; | 171   synchronous_entry_in_use_by_worker_ = true; | 
| 171   index_->UseIfExists(key_); | 172   if (index_) | 
|  | 173     index_->UseIfExists(key_); | 
| 172   SynchronousOperationCallback sync_operation_callback = | 174   SynchronousOperationCallback sync_operation_callback = | 
| 173       base::Bind(&SimpleEntryImpl::EntryOperationComplete, | 175       base::Bind(&SimpleEntryImpl::EntryOperationComplete, | 
| 174                  this, callback); | 176                  this, callback); | 
| 175   WorkerPool::PostTask(FROM_HERE, | 177   WorkerPool::PostTask(FROM_HERE, | 
| 176                        base::Bind(&SimpleSynchronousEntry::WriteData, | 178                        base::Bind(&SimpleSynchronousEntry::WriteData, | 
| 177                                   base::Unretained(synchronous_entry_), | 179                                   base::Unretained(synchronous_entry_), | 
| 178                                   index, offset, make_scoped_refptr(buf), | 180                                   index, offset, make_scoped_refptr(buf), | 
| 179                                   buf_len, sync_operation_callback, truncate), | 181                                   buf_len, sync_operation_callback, truncate), | 
| 180                        true); | 182                        true); | 
| 181   return net::ERR_IO_PENDING; | 183   return net::ERR_IO_PENDING; | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 223   NOTIMPLEMENTED(); | 225   NOTIMPLEMENTED(); | 
| 224 } | 226 } | 
| 225 | 227 | 
| 226 int SimpleEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) { | 228 int SimpleEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) { | 
| 227   DCHECK(io_thread_checker_.CalledOnValidThread()); | 229   DCHECK(io_thread_checker_.CalledOnValidThread()); | 
| 228   // TODO(gavinp): Determine if the simple backend should support sparse data. | 230   // TODO(gavinp): Determine if the simple backend should support sparse data. | 
| 229   NOTIMPLEMENTED(); | 231   NOTIMPLEMENTED(); | 
| 230   return net::ERR_FAILED; | 232   return net::ERR_FAILED; | 
| 231 } | 233 } | 
| 232 | 234 | 
| 233 SimpleEntryImpl::SimpleEntryImpl(const scoped_refptr<SimpleIndex>& index, | 235 SimpleEntryImpl::SimpleEntryImpl(SimpleIndex* index, | 
| 234                                  const base::FilePath& path, | 236                                  const FilePath& path, | 
| 235                                  const std::string& key) | 237                                  const std::string& key) | 
| 236     : constructor_thread_(base::MessageLoopProxy::current()), | 238     : constructor_thread_(MessageLoopProxy::current()), | 
| 237       index_(index), | 239       index_(index->AsWeakPtr()), | 
| 238       path_(path), | 240       path_(path), | 
| 239       key_(key), | 241       key_(key), | 
| 240       synchronous_entry_(NULL), | 242       synchronous_entry_(NULL), | 
| 241       synchronous_entry_in_use_by_worker_(false) { | 243       synchronous_entry_in_use_by_worker_(false) { | 
| 242 } | 244 } | 
| 243 | 245 | 
| 244 SimpleEntryImpl::~SimpleEntryImpl() { | 246 SimpleEntryImpl::~SimpleEntryImpl() { | 
| 245   if (synchronous_entry_) { | 247   if (synchronous_entry_) { | 
| 246     base::Closure close_sync_entry = | 248     base::Closure close_sync_entry = | 
| 247         base::Bind(&SimpleSynchronousEntry::Close, | 249         base::Bind(&SimpleSynchronousEntry::Close, | 
| 248                    base::Unretained(synchronous_entry_)); | 250                    base::Unretained(synchronous_entry_)); | 
| 249     // We aren't guaranteed to be able to run IO on our constructor thread, but | 251     // We aren't guaranteed to be able to run IO on our constructor thread, but | 
| 250     // we are also not guaranteed to be allowed to run WorkerPool::PostTask on | 252     // we are also not guaranteed to be allowed to run WorkerPool::PostTask on | 
| 251     // our other threads. | 253     // our other threads. | 
| 252     if (constructor_thread_->BelongsToCurrentThread()) | 254     if (constructor_thread_->BelongsToCurrentThread()) | 
| 253       WorkerPool::PostTask(FROM_HERE, close_sync_entry, true); | 255       WorkerPool::PostTask(FROM_HERE, close_sync_entry, true); | 
| 254     else | 256     else | 
| 255       close_sync_entry.Run(); | 257       close_sync_entry.Run(); | 
| 256   } | 258   } | 
| 257 } | 259 } | 
| 258 | 260 | 
| 259 void SimpleEntryImpl::CreationOperationComplete( | 261 void SimpleEntryImpl::CreationOperationComplete( | 
| 260     Entry** out_entry, | 262     Entry** out_entry, | 
| 261     const CompletionCallback& completion_callback, | 263     const CompletionCallback& completion_callback, | 
| 262     SimpleSynchronousEntry* sync_entry) { | 264     SimpleSynchronousEntry* sync_entry) { | 
| 263   DCHECK(io_thread_checker_.CalledOnValidThread()); | 265   DCHECK(io_thread_checker_.CalledOnValidThread()); | 
| 264   if (!sync_entry) { | 266   if (!sync_entry) { | 
| 265     completion_callback.Run(net::ERR_FAILED); | 267     completion_callback.Run(net::ERR_FAILED); | 
| 266     // If OpenEntry failed, we must remove it from our index. | 268     // If OpenEntry failed, we must remove it from our index. | 
| 267     index_->Remove(key_); | 269     if (index_) | 
|  | 270       index_->Remove(key_); | 
| 268     // The reference held by the Callback calling us will go out of scope and | 271     // The reference held by the Callback calling us will go out of scope and | 
| 269     // delete |this| on leaving this scope. | 272     // delete |this| on leaving this scope. | 
| 270     return; | 273     return; | 
| 271   } | 274   } | 
| 272   // Adding a reference to self will keep |this| alive after the scope of our | 275   // The Backend interface requires us to return |this|, and keep the Entry | 
| 273   // Callback calling us is destroyed. | 276   // alive until Entry::Close(). Adding a reference to self will keep |this| | 
|  | 277   // alive after the scope of the Callback calling us is destroyed. | 
| 274   AddRef();  // Balanced in Close(). | 278   AddRef();  // Balanced in Close(). | 
| 275   synchronous_entry_ = sync_entry; | 279   synchronous_entry_ = sync_entry; | 
| 276   SetSynchronousData(); | 280   SetSynchronousData(); | 
| 277   index_->Insert(key_); | 281   if (index_) | 
|  | 282     index_->Insert(key_); | 
| 278   *out_entry = this; | 283   *out_entry = this; | 
| 279   completion_callback.Run(net::OK); | 284   completion_callback.Run(net::OK); | 
| 280 } | 285 } | 
| 281 | 286 | 
| 282 void SimpleEntryImpl::EntryOperationComplete( | 287 void SimpleEntryImpl::EntryOperationComplete( | 
| 283     const CompletionCallback& completion_callback, | 288     const CompletionCallback& completion_callback, | 
| 284     int result) { | 289     int result) { | 
| 285   DCHECK(io_thread_checker_.CalledOnValidThread()); | 290   DCHECK(io_thread_checker_.CalledOnValidThread()); | 
| 286   DCHECK(synchronous_entry_); | 291   DCHECK(synchronous_entry_); | 
| 287   DCHECK(synchronous_entry_in_use_by_worker_); | 292   DCHECK(synchronous_entry_in_use_by_worker_); | 
| 288   synchronous_entry_in_use_by_worker_ = false; | 293   synchronous_entry_in_use_by_worker_ = false; | 
| 289   SetSynchronousData(); | 294   SetSynchronousData(); | 
| 290   if (result >= 0) { | 295   if (index_) { | 
| 291     index_->UpdateEntrySize(synchronous_entry_->key(), | 296     if (result >= 0) { | 
| 292                             synchronous_entry_->GetFileSize()); | 297       index_->UpdateEntrySize(synchronous_entry_->key(), | 
| 293   } else { | 298                               synchronous_entry_->GetFileSize()); | 
| 294     index_->Remove(synchronous_entry_->key()); | 299     } else { | 
|  | 300       index_->Remove(synchronous_entry_->key()); | 
|  | 301     } | 
| 295   } | 302   } | 
| 296   completion_callback.Run(result); | 303   completion_callback.Run(result); | 
| 297 } | 304 } | 
| 298 | 305 | 
| 299 void SimpleEntryImpl::SetSynchronousData() { | 306 void SimpleEntryImpl::SetSynchronousData() { | 
| 300   DCHECK(io_thread_checker_.CalledOnValidThread()); | 307   DCHECK(io_thread_checker_.CalledOnValidThread()); | 
| 301   DCHECK(!synchronous_entry_in_use_by_worker_); | 308   DCHECK(!synchronous_entry_in_use_by_worker_); | 
| 302   // TODO(felipeg): These copies to avoid data races are not optimal. While | 309   // TODO(felipeg): These copies to avoid data races are not optimal. While | 
| 303   // adding an IO thread index (for fast misses etc...), we can store this data | 310   // adding an IO thread index (for fast misses etc...), we can store this data | 
| 304   // in that structure. This also solves problems with last_used() on ext4 | 311   // in that structure. This also solves problems with last_used() on ext4 | 
| 305   // filesystems not being accurate. | 312   // filesystems not being accurate. | 
| 306   last_used_ = synchronous_entry_->last_used(); | 313   last_used_ = synchronous_entry_->last_used(); | 
| 307   last_modified_ = synchronous_entry_->last_modified(); | 314   last_modified_ = synchronous_entry_->last_modified(); | 
| 308   for (int i = 0; i < kSimpleEntryFileCount; ++i) | 315   for (int i = 0; i < kSimpleEntryFileCount; ++i) | 
| 309     data_size_[i] = synchronous_entry_->data_size(i); | 316     data_size_[i] = synchronous_entry_->data_size(i); | 
| 310 } | 317 } | 
| 311 | 318 | 
| 312 }  // namespace disk_cache | 319 }  // namespace disk_cache | 
| OLD | NEW | 
|---|