Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: net/disk_cache/simple/simple_entry_impl.cc

Issue 12192005: Add new simple disk cache backend. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix dcheck Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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
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 // A PendingCreationOperation represents a pending operation that is creating a
35 // new SimpleSynchronousEntry, such as OpenEntry() or CreateEntry(). It ensures
36 // that a SimpleEntryImpl is only created after the underlying synchronous
37 // operation has succeeded.
38 class SimpleEntryImpl::PendingCreationOperation {
felipeg 2013/02/12 13:25:20 As discussed by chat, we don't really need a class
gavinp 2013/02/12 15:45:57 Great suggestion. I was being too ornate.
39 public:
40 static SynchronousEntryCallback Create(
41 const CompletionCallback& completion_callback,
42 Entry** out_entry);
43
44 private:
45 PendingCreationOperation(const CompletionCallback& completion_callback,
46 Entry** out_entry);
47
48 void OnIOComplete(SimpleSynchronousEntry* sync_entry, int result);
49
50 CompletionCallback completion_callback_;
51 Entry** out_entry_;
52 };
53
54 // A PendingEntryOperation represents an operation on a SynchronousEntry while
55 // it is in flight. It informs the owning SimpleEntryImpl of IO completion if
56 // necessary, as well as calling the IO completion callback.
57 class SimpleEntryImpl::PendingEntryOperation {
felipeg 2013/02/12 13:25:20 ditto.
gavinp 2013/02/12 15:45:57 ditto!
58 public:
59 static SynchronousEntryCallback Create(
60 const WeakPtr<SimpleEntryImpl>& entry,
61 const CompletionCallback& completion_callback);
62
63 private:
64 PendingEntryOperation(const WeakPtr<SimpleEntryImpl>& entry,
65 const CompletionCallback& completion_callback);
66
67 void OnIOComplete(SimpleSynchronousEntry* sync_entry, int result);
68
69 WeakPtr<SimpleEntryImpl> entry_;
70 CompletionCallback completion_callback_;
71 };
72
73 // static
74 SynchronousEntryCallback SimpleEntryImpl::PendingCreationOperation::Create(
75 const CompletionCallback& completion_callback,
76 Entry** out_entry) {
77 PendingCreationOperation* operation =
78 new PendingCreationOperation(completion_callback, out_entry);
79 DCHECK(operation);
80 return base::Bind(&PendingCreationOperation::OnIOComplete,
81 base::Owned(operation));
82 }
83
84 SimpleEntryImpl::PendingCreationOperation::PendingCreationOperation(
85 const CompletionCallback& completion_callback,
86 Entry** out_entry) : completion_callback_(completion_callback),
87 out_entry_(out_entry) {
88 }
89
90 void SimpleEntryImpl::PendingCreationOperation::OnIOComplete(
91 SimpleSynchronousEntry* sync_entry,
92 int result) {
93 DCHECK_NE(net::ERR_IO_PENDING, result);
94
95 if (result != net::OK) {
96 DCHECK(!sync_entry) << "sync_entry = " << sync_entry;
97 completion_callback_.Run(result);
98 return;
99 }
100 DCHECK(sync_entry);
101 *out_entry_ = new SimpleEntryImpl(sync_entry);
102 DCHECK(*out_entry_);
103 completion_callback_.Run(net::OK);
104 }
105
106 // static
107 SynchronousEntryCallback SimpleEntryImpl::PendingEntryOperation::Create(
108 const WeakPtr<SimpleEntryImpl>& entry,
109 const CompletionCallback& completion_callback) {
110 PendingEntryOperation* operation = new PendingEntryOperation(entry,
111 completion_callback);
112 DCHECK(operation);
113 return base::Bind(&PendingEntryOperation::OnIOComplete,
114 base::Owned(operation));
115 }
116
117 SimpleEntryImpl::PendingEntryOperation::PendingEntryOperation(
118 const WeakPtr<SimpleEntryImpl>& entry,
119 const CompletionCallback& completion_callback)
120 : entry_(entry),
121 completion_callback_(completion_callback) {
122 }
123
124 void SimpleEntryImpl::PendingEntryOperation::OnIOComplete(
125 SimpleSynchronousEntry* sync_entry,
126 int result) {
127 DCHECK(sync_entry);
128 if (entry_)
129 entry_->SetSynchronousEntry(sync_entry);
130 completion_callback_.Run(result);
131 }
132
133 // static
134 int SimpleEntryImpl::OpenEntry(const FilePath& path,
135 const std::string& key,
136 Entry** entry,
137 const CompletionCallback& callback) {
138 SynchronousEntryCallback sync_entry_callback =
139 PendingCreationOperation::Create(callback, entry);
140
141 WorkerPool::PostTask(FROM_HERE,
142 base::Bind(&SimpleSynchronousEntry::OpenEntry, path, key,
143 MessageLoopProxy::current(),
144 sync_entry_callback),
145 true);
146 return net::ERR_IO_PENDING;
147 }
148
149 // static
150 int SimpleEntryImpl::CreateEntry(const FilePath& path,
151 const std::string& key,
152 Entry** entry,
153 const CompletionCallback& callback) {
154 SynchronousEntryCallback sync_entry_callback =
155 PendingCreationOperation::Create(callback, entry);
156 WorkerPool::PostTask(FROM_HERE,
157 base::Bind(&SimpleSynchronousEntry::CreateEntry, path,
158 key, MessageLoopProxy::current(),
159 sync_entry_callback),
160 true);
161 return net::ERR_IO_PENDING;
162 }
163
164 // static
165 int SimpleEntryImpl::DoomEntry(const FilePath& path,
166 const std::string& key,
167 const CompletionCallback& callback) {
168 WorkerPool::PostTask(FROM_HERE,
169 base::Bind(&SimpleSynchronousEntry::DoomEntry, path, key,
170 MessageLoopProxy::current(), callback),
171 true);
172 return net::ERR_IO_PENDING;
173 }
174
175 void SimpleEntryImpl::Doom() {
176 DCHECK(thread_checker_.CalledOnValidThread());
177 if (!synchronous_entry_) {
178 NOTIMPLEMENTED() << ": Overlapping an asynchronous operation.";
179 return;
180 }
181 WorkerPool::PostTask(FROM_HERE,
182 base::Bind(&SimpleSynchronousEntry::DoomAndClose,
183 base::Unretained(ReleaseSynchronousEntry())),
184 true);
185 has_been_doomed_ = true;
186 }
187
188 void SimpleEntryImpl::Close() {
189 DCHECK(thread_checker_.CalledOnValidThread());
190 if (!synchronous_entry_) {
191 NOTIMPLEMENTED() << ": Overlapping an asynchronous operation.";
192 delete this;
193 return;
194 }
195 if (!has_been_doomed_) {
196 WorkerPool::PostTask(FROM_HERE,
197 base::Bind(&SimpleSynchronousEntry::Close,
198 base::Unretained(
199 ReleaseSynchronousEntry())),
200 true);
201 }
202 // Entry::Close() is expected to release this entry. See disk_cache.h for
203 // details.
204 delete this;
205 }
206
207 std::string SimpleEntryImpl::GetKey() const {
208 DCHECK(thread_checker_.CalledOnValidThread());
209 return key_;
210 }
211
212 Time SimpleEntryImpl::GetLastUsed() const {
213 DCHECK(thread_checker_.CalledOnValidThread());
214 if (!synchronous_entry_) {
215 NOTIMPLEMENTED() << ": Synchronous operations overlapping an asynchronous "
216 << "operation.";
217 NOTREACHED();
218 }
219 return synchronous_entry_->last_used();
220 }
221
222 Time SimpleEntryImpl::GetLastModified() const {
223 DCHECK(thread_checker_.CalledOnValidThread());
224 if (!synchronous_entry_) {
225 NOTIMPLEMENTED() << ": Synchronous operations overlapping an asynchronous "
226 << "operation.";
227 NOTREACHED();
228 }
229 return synchronous_entry_->last_modified();
230 }
231
232 int32 SimpleEntryImpl::GetDataSize(int index) const {
233 DCHECK(thread_checker_.CalledOnValidThread());
234 if (!synchronous_entry_) {
235 NOTIMPLEMENTED() << ": Synchronous operations overlapping an asynchronous "
236 << "operation.";
237 NOTREACHED();
238 }
239 return synchronous_entry_->data_size(index);
240 }
241
242 int SimpleEntryImpl::ReadData(int index,
243 int offset,
244 net::IOBuffer* buf,
245 int buf_len,
246 const CompletionCallback& callback) {
247 DCHECK(thread_checker_.CalledOnValidThread());
248 // TODO(gavinp): Add support for overlapping reads. The net::HttpCache does
249 // make overlapping read requests when multiple transactions access the same
250 // entry as read only.
251 if (!synchronous_entry_) {
252 NOTIMPLEMENTED() << ": Overlapping calls to ReadData.";
253 NOTREACHED();
254 }
255 SynchronousEntryCallback sync_entry_callback =
256 PendingEntryOperation::Create(weak_ptr_factory_.GetWeakPtr(), callback);
257 WorkerPool::PostTask(FROM_HERE,
258 base::Bind(&SimpleSynchronousEntry::ReadData,
259 base::Unretained(ReleaseSynchronousEntry()),
260 index, offset, scoped_refptr<IOBuffer>(buf),
261 buf_len, sync_entry_callback),
262 true);
263 return net::ERR_IO_PENDING;
264 }
265
266 int SimpleEntryImpl::WriteData(int index,
267 int offset,
268 net::IOBuffer* buf,
269 int buf_len,
270 const CompletionCallback& callback,
271 bool truncate) {
272 DCHECK(thread_checker_.CalledOnValidThread());
273 if (!synchronous_entry_) {
274 NOTIMPLEMENTED() << ": Overlapping calls to WriteData.";
275 NOTREACHED();
276 }
277 SynchronousEntryCallback sync_entry_callback =
278 PendingEntryOperation::Create(weak_ptr_factory_.GetWeakPtr(), callback);
279 WorkerPool::PostTask(FROM_HERE,
280 base::Bind(&SimpleSynchronousEntry::WriteData,
281 base::Unretained(ReleaseSynchronousEntry()),
282 index, offset, scoped_refptr<IOBuffer>(buf),
283 buf_len, sync_entry_callback, truncate),
284 true);
285 return net::ERR_IO_PENDING;
286 }
287
288 int SimpleEntryImpl::ReadSparseData(int64 offset,
289 net::IOBuffer* buf,
290 int buf_len,
291 const CompletionCallback& callback) {
292 // TODO(gavinp): Determine if the simple backend should support sparse data.
293 DCHECK(thread_checker_.CalledOnValidThread());
294 NOTIMPLEMENTED();
295 return net::ERR_FAILED;
296 }
297
298 int SimpleEntryImpl::WriteSparseData(int64 offset,
299 net::IOBuffer* buf,
300 int buf_len,
301 const CompletionCallback& callback) {
302 // TODO(gavinp): Determine if the simple backend should support sparse data.
303 DCHECK(thread_checker_.CalledOnValidThread());
304 NOTIMPLEMENTED();
305 return net::ERR_FAILED;
306 }
307
308 int SimpleEntryImpl::GetAvailableRange(int64 offset,
309 int len,
310 int64* start,
311 const CompletionCallback& callback) {
312 // TODO(gavinp): Determine if the simple backend should support sparse data.
313 DCHECK(thread_checker_.CalledOnValidThread());
314 NOTIMPLEMENTED();
315 return net::ERR_FAILED;
316 }
317
318 bool SimpleEntryImpl::CouldBeSparse() const {
319 // TODO(gavinp): Determine if the simple backend should support sparse data.
320 DCHECK(thread_checker_.CalledOnValidThread());
321 return false;
322 }
323
324 void SimpleEntryImpl::CancelSparseIO() {
325 // TODO(gavinp): Determine if the simple backend should support sparse data.
326 DCHECK(thread_checker_.CalledOnValidThread());
327 NOTIMPLEMENTED();
328 }
329
330 int SimpleEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) {
331 // TODO(gavinp): Determine if the simple backend should support sparse data.
332 DCHECK(thread_checker_.CalledOnValidThread());
333 NOTIMPLEMENTED();
334 return net::ERR_FAILED;
335 }
336
337 SimpleEntryImpl::SimpleEntryImpl(
338 SimpleSynchronousEntry* synchronous_entry)
339 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
340 key_(synchronous_entry->key()),
341 synchronous_entry_(synchronous_entry),
342 has_been_doomed_(false) {
343 DCHECK(synchronous_entry);
344 }
345
346 SimpleEntryImpl::~SimpleEntryImpl() {
347 DCHECK(thread_checker_.CalledOnValidThread());
348 DCHECK(!synchronous_entry_) << "synchronous_entry_ = " << synchronous_entry_;
349 }
350
351 SimpleSynchronousEntry* SimpleEntryImpl::ReleaseSynchronousEntry() {
352 DCHECK(synchronous_entry_);
353 SimpleSynchronousEntry* retval = synchronous_entry_;
354 synchronous_entry_ = NULL;
355 return retval;
356 }
357
358 void SimpleEntryImpl::SetSynchronousEntry(
359 SimpleSynchronousEntry* synchronous_entry) {
360 DCHECK(!synchronous_entry_) << "synchronous_entry_ = " << synchronous_entry_;
361 synchronous_entry_ = synchronous_entry;
362 }
363
364 } // namespace disk_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698