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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 // underlying files. On POSIX, this is fine; the files are still open on the | 79 // underlying files. On POSIX, this is fine; the files are still open on the |
80 // SimpleSynchronousEntry, and operations can even happen on them. The files | 80 // SimpleSynchronousEntry, and operations can even happen on them. The files |
81 // will be removed from the filesystem when they are closed. | 81 // will be removed from the filesystem when they are closed. |
82 DoomEntry(path_, key_, CompletionCallback()); | 82 DoomEntry(path_, key_, CompletionCallback()); |
83 #else | 83 #else |
84 NOTIMPLEMENTED(); | 84 NOTIMPLEMENTED(); |
85 #endif | 85 #endif |
86 } | 86 } |
87 | 87 |
88 void SimpleEntryImpl::Close() { | 88 void SimpleEntryImpl::Close() { |
89 if (synchronous_entry_in_use_by_worker_) { | 89 if (!synchronous_entry_in_use_by_worker_) { |
90 NOTIMPLEMENTED(); | 90 WorkerPool::PostTask(FROM_HERE, |
91 delete this; | 91 base::Bind(&SimpleSynchronousEntry::Close, |
92 return; | 92 base::Unretained(synchronous_entry_)), |
| 93 true); |
93 } | 94 } |
94 DCHECK(synchronous_entry_); | |
95 WorkerPool::PostTask(FROM_HERE, | |
96 base::Bind(&SimpleSynchronousEntry::Close, | |
97 base::Unretained(synchronous_entry_)), | |
98 true); | |
99 synchronous_entry_ = NULL; | |
100 // Entry::Close() is expected to release this entry. See disk_cache.h for | 95 // Entry::Close() is expected to release this entry. See disk_cache.h for |
101 // details. | 96 // details. |
102 delete this; | 97 delete this; |
103 } | 98 } |
104 | 99 |
105 std::string SimpleEntryImpl::GetKey() const { | 100 std::string SimpleEntryImpl::GetKey() const { |
106 return key_; | 101 return key_; |
107 } | 102 } |
108 | 103 |
109 Time SimpleEntryImpl::GetLastUsed() const { | 104 Time SimpleEntryImpl::GetLastUsed() const { |
110 return last_used_; | 105 return last_used_; |
111 } | 106 } |
112 | 107 |
113 Time SimpleEntryImpl::GetLastModified() const { | 108 Time SimpleEntryImpl::GetLastModified() const { |
114 return last_modified_; | 109 return last_modified_; |
115 } | 110 } |
116 | 111 |
117 int32 SimpleEntryImpl::GetDataSize(int index) const { | 112 int32 SimpleEntryImpl::GetDataSize(int index) const { |
118 return data_size_[index]; | 113 return data_size_[index]; |
119 } | 114 } |
120 | 115 |
121 int SimpleEntryImpl::ReadData(int index, | 116 int SimpleEntryImpl::ReadData(int index, |
122 int offset, | 117 int offset, |
123 net::IOBuffer* buf, | 118 net::IOBuffer* buf, |
124 int buf_len, | 119 int buf_len, |
125 const CompletionCallback& callback) { | 120 const CompletionCallback& callback) { |
126 // TODO(gavinp): Add support for overlapping reads. The net::HttpCache does | 121 // TODO(gavinp): Add support for overlapping reads. The net::HttpCache does |
127 // make overlapping read requests when multiple transactions access the same | 122 // make overlapping read requests when multiple transactions access the same |
128 // entry as read only. | 123 // entry as read only. This might make calling SimpleSynchronousEntry::Close() |
| 124 // correctly more tricky (see SimpleEntryImpl::EntryOperationComplete). |
129 if (synchronous_entry_in_use_by_worker_) { | 125 if (synchronous_entry_in_use_by_worker_) { |
130 NOTIMPLEMENTED(); | 126 NOTIMPLEMENTED(); |
131 CHECK(false); | 127 CHECK(false); |
132 } | 128 } |
133 synchronous_entry_in_use_by_worker_ = true; | 129 synchronous_entry_in_use_by_worker_ = true; |
134 SynchronousOperationCallback sync_operation_callback = | 130 SynchronousOperationCallback sync_operation_callback = |
135 base::Bind(&SimpleEntryImpl::EntryOperationComplete, | 131 base::Bind(&SimpleEntryImpl::EntryOperationComplete, |
136 callback, weak_ptr_factory_.GetWeakPtr()); | 132 callback, weak_ptr_factory_.GetWeakPtr(), synchronous_entry_); |
137 WorkerPool::PostTask(FROM_HERE, | 133 WorkerPool::PostTask(FROM_HERE, |
138 base::Bind(&SimpleSynchronousEntry::ReadData, | 134 base::Bind(&SimpleSynchronousEntry::ReadData, |
139 base::Unretained(synchronous_entry_), | 135 base::Unretained(synchronous_entry_), |
140 index, offset, make_scoped_refptr(buf), | 136 index, offset, make_scoped_refptr(buf), |
141 buf_len, sync_operation_callback), | 137 buf_len, sync_operation_callback), |
142 true); | 138 true); |
143 return net::ERR_IO_PENDING; | 139 return net::ERR_IO_PENDING; |
144 } | 140 } |
145 | 141 |
146 int SimpleEntryImpl::WriteData(int index, | 142 int SimpleEntryImpl::WriteData(int index, |
147 int offset, | 143 int offset, |
148 net::IOBuffer* buf, | 144 net::IOBuffer* buf, |
149 int buf_len, | 145 int buf_len, |
150 const CompletionCallback& callback, | 146 const CompletionCallback& callback, |
151 bool truncate) { | 147 bool truncate) { |
152 if (synchronous_entry_in_use_by_worker_) { | 148 if (synchronous_entry_in_use_by_worker_) { |
153 NOTIMPLEMENTED(); | 149 NOTIMPLEMENTED(); |
154 CHECK(false); | 150 CHECK(false); |
155 } | 151 } |
156 synchronous_entry_in_use_by_worker_ = true; | 152 synchronous_entry_in_use_by_worker_ = true; |
157 SynchronousOperationCallback sync_operation_callback = | 153 SynchronousOperationCallback sync_operation_callback = |
158 base::Bind(&SimpleEntryImpl::EntryOperationComplete, | 154 base::Bind(&SimpleEntryImpl::EntryOperationComplete, |
159 callback, weak_ptr_factory_.GetWeakPtr()); | 155 callback, weak_ptr_factory_.GetWeakPtr(), synchronous_entry_); |
160 WorkerPool::PostTask(FROM_HERE, | 156 WorkerPool::PostTask(FROM_HERE, |
161 base::Bind(&SimpleSynchronousEntry::WriteData, | 157 base::Bind(&SimpleSynchronousEntry::WriteData, |
162 base::Unretained(synchronous_entry_), | 158 base::Unretained(synchronous_entry_), |
163 index, offset, make_scoped_refptr(buf), | 159 index, offset, make_scoped_refptr(buf), |
164 buf_len, sync_operation_callback, truncate), | 160 buf_len, sync_operation_callback, truncate), |
165 true); | 161 true); |
166 return net::ERR_IO_PENDING; | 162 return net::ERR_IO_PENDING; |
167 } | 163 } |
168 | 164 |
169 int SimpleEntryImpl::ReadSparseData(int64 offset, | 165 int SimpleEntryImpl::ReadSparseData(int64 offset, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), | 210 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), |
215 path_(synchronous_entry->path()), | 211 path_(synchronous_entry->path()), |
216 key_(synchronous_entry->key()), | 212 key_(synchronous_entry->key()), |
217 synchronous_entry_(synchronous_entry), | 213 synchronous_entry_(synchronous_entry), |
218 synchronous_entry_in_use_by_worker_(false) { | 214 synchronous_entry_in_use_by_worker_(false) { |
219 DCHECK(synchronous_entry); | 215 DCHECK(synchronous_entry); |
220 SetSynchronousData(); | 216 SetSynchronousData(); |
221 } | 217 } |
222 | 218 |
223 SimpleEntryImpl::~SimpleEntryImpl() { | 219 SimpleEntryImpl::~SimpleEntryImpl() { |
224 DCHECK(!synchronous_entry_); | |
225 } | 220 } |
226 | 221 |
227 // static | 222 // static |
228 void SimpleEntryImpl::CreationOperationComplete( | 223 void SimpleEntryImpl::CreationOperationComplete( |
229 const CompletionCallback& completion_callback, | 224 const CompletionCallback& completion_callback, |
230 Entry** out_entry, | 225 Entry** out_entry, |
231 SimpleSynchronousEntry* sync_entry) { | 226 SimpleSynchronousEntry* sync_entry) { |
232 if (!sync_entry) { | 227 if (!sync_entry) { |
233 completion_callback.Run(net::ERR_FAILED); | 228 completion_callback.Run(net::ERR_FAILED); |
234 return; | 229 return; |
235 } | 230 } |
236 *out_entry = new SimpleEntryImpl(sync_entry); | 231 *out_entry = new SimpleEntryImpl(sync_entry); |
237 completion_callback.Run(net::OK); | 232 completion_callback.Run(net::OK); |
238 } | 233 } |
239 | 234 |
240 // static | 235 // static |
241 void SimpleEntryImpl::EntryOperationComplete( | 236 void SimpleEntryImpl::EntryOperationComplete( |
242 const CompletionCallback& completion_callback, | 237 const CompletionCallback& completion_callback, |
243 base::WeakPtr<SimpleEntryImpl> entry, | 238 base::WeakPtr<SimpleEntryImpl> entry, |
| 239 SimpleSynchronousEntry* sync_entry, |
244 int result) { | 240 int result) { |
245 if (entry) { | 241 if (entry) { |
246 DCHECK(entry->synchronous_entry_in_use_by_worker_); | 242 DCHECK(entry->synchronous_entry_in_use_by_worker_); |
247 entry->synchronous_entry_in_use_by_worker_ = false; | 243 entry->synchronous_entry_in_use_by_worker_ = false; |
248 entry->SetSynchronousData(); | 244 entry->SetSynchronousData(); |
| 245 } else { |
| 246 // |entry| must have had Close() called while this operation was in flight. |
| 247 // Since the simple cache now only supports one pending entry operation in |
| 248 // flight at a time, it's safe to now call Close() on |sync_entry|. |
| 249 WorkerPool::PostTask(FROM_HERE, |
| 250 base::Bind(&SimpleSynchronousEntry::Close, |
| 251 base::Unretained(sync_entry)), |
| 252 true); |
249 } | 253 } |
250 completion_callback.Run(result); | 254 completion_callback.Run(result); |
251 } | 255 } |
252 | 256 |
253 void SimpleEntryImpl::SetSynchronousData() { | 257 void SimpleEntryImpl::SetSynchronousData() { |
254 DCHECK(!synchronous_entry_in_use_by_worker_); | 258 DCHECK(!synchronous_entry_in_use_by_worker_); |
255 | 259 |
256 // TODO(felipeg): These copies to avoid data races are not optimal. While | 260 // TODO(felipeg): These copies to avoid data races are not optimal. While |
257 // adding an IO thread index (for fast misses etc...), we can store this data | 261 // adding an IO thread index (for fast misses etc...), we can store this data |
258 // in that structure. This also solves problems with last_used() on ext4 | 262 // in that structure. This also solves problems with last_used() on ext4 |
259 // filesystems not being accurate. | 263 // filesystems not being accurate. |
260 | 264 |
261 last_used_ = synchronous_entry_->last_used(); | 265 last_used_ = synchronous_entry_->last_used(); |
262 last_modified_ = synchronous_entry_->last_modified(); | 266 last_modified_ = synchronous_entry_->last_modified(); |
263 for (int i = 0; i < kSimpleEntryFileCount; ++i) | 267 for (int i = 0; i < kSimpleEntryFileCount; ++i) |
264 data_size_[i] = synchronous_entry_->data_size(i); | 268 data_size_[i] = synchronous_entry_->data_size(i); |
265 } | 269 } |
266 | 270 |
267 } // namespace disk_cache | 271 } // namespace disk_cache |
OLD | NEW |