OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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/in_flight_backend_io.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/bind_helpers.h" | |
9 #include "base/compiler_specific.h" | |
10 #include "base/logging.h" | |
11 #include "net/base/net_errors.h" | |
12 #include "net/disk_cache/backend_impl.h" | |
13 #include "net/disk_cache/entry_impl.h" | |
14 #include "net/disk_cache/histogram_macros.h" | |
15 | |
16 // Provide a BackendImpl object to macros from histogram_macros.h. | |
17 #define CACHE_UMA_BACKEND_IMPL_OBJ backend_ | |
18 | |
19 namespace disk_cache { | |
20 | |
21 BackendIO::BackendIO(InFlightIO* controller, BackendImpl* backend, | |
22 const net::CompletionCallback& callback) | |
23 : BackgroundIO(controller), | |
24 backend_(backend), | |
25 callback_(callback), | |
26 operation_(OP_NONE), | |
27 entry_ptr_(NULL), | |
28 iter_ptr_(NULL), | |
29 iter_(NULL), | |
30 entry_(NULL), | |
31 index_(0), | |
32 offset_(0), | |
33 buf_len_(0), | |
34 truncate_(false), | |
35 offset64_(0), | |
36 start_(NULL) { | |
37 start_time_ = base::TimeTicks::Now(); | |
38 } | |
39 | |
40 // Runs on the background thread. | |
41 void BackendIO::ExecuteOperation() { | |
42 if (IsEntryOperation()) | |
43 return ExecuteEntryOperation(); | |
44 | |
45 ExecuteBackendOperation(); | |
46 } | |
47 | |
48 // Runs on the background thread. | |
49 void BackendIO::OnIOComplete(int result) { | |
50 DCHECK(IsEntryOperation()); | |
51 DCHECK_NE(result, net::ERR_IO_PENDING); | |
52 result_ = result; | |
53 NotifyController(); | |
54 } | |
55 | |
56 // Runs on the primary thread. | |
57 void BackendIO::OnDone(bool cancel) { | |
58 if (IsEntryOperation()) { | |
59 CACHE_UMA(TIMES, "TotalIOTime", 0, ElapsedTime()); | |
60 } | |
61 | |
62 if (!ReturnsEntry()) | |
63 return; | |
64 | |
65 if (result() == net::OK) { | |
66 static_cast<EntryImpl*>(*entry_ptr_)->OnEntryCreated(backend_); | |
67 if (cancel) | |
68 (*entry_ptr_)->Close(); | |
69 } | |
70 } | |
71 | |
72 bool BackendIO::IsEntryOperation() { | |
73 return operation_ > OP_MAX_BACKEND; | |
74 } | |
75 | |
76 // Runs on the background thread. | |
77 void BackendIO::ReferenceEntry() { | |
78 entry_->AddRef(); | |
79 } | |
80 | |
81 void BackendIO::Init() { | |
82 operation_ = OP_INIT; | |
83 } | |
84 | |
85 void BackendIO::OpenEntry(const std::string& key, Entry** entry) { | |
86 operation_ = OP_OPEN; | |
87 key_ = key; | |
88 entry_ptr_ = entry; | |
89 } | |
90 | |
91 void BackendIO::CreateEntry(const std::string& key, Entry** entry) { | |
92 operation_ = OP_CREATE; | |
93 key_ = key; | |
94 entry_ptr_ = entry; | |
95 } | |
96 | |
97 void BackendIO::DoomEntry(const std::string& key) { | |
98 operation_ = OP_DOOM; | |
99 key_ = key; | |
100 } | |
101 | |
102 void BackendIO::DoomAllEntries() { | |
103 operation_ = OP_DOOM_ALL; | |
104 } | |
105 | |
106 void BackendIO::DoomEntriesBetween(const base::Time initial_time, | |
107 const base::Time end_time) { | |
108 operation_ = OP_DOOM_BETWEEN; | |
109 initial_time_ = initial_time; | |
110 end_time_ = end_time; | |
111 } | |
112 | |
113 void BackendIO::DoomEntriesSince(const base::Time initial_time) { | |
114 operation_ = OP_DOOM_SINCE; | |
115 initial_time_ = initial_time; | |
116 } | |
117 | |
118 void BackendIO::OpenNextEntry(void** iter, Entry** next_entry) { | |
119 operation_ = OP_OPEN_NEXT; | |
120 iter_ptr_ = iter; | |
121 entry_ptr_ = next_entry; | |
122 } | |
123 | |
124 void BackendIO::OpenPrevEntry(void** iter, Entry** prev_entry) { | |
125 operation_ = OP_OPEN_PREV; | |
126 iter_ptr_ = iter; | |
127 entry_ptr_ = prev_entry; | |
128 } | |
129 | |
130 void BackendIO::EndEnumeration(void* iterator) { | |
131 operation_ = OP_END_ENUMERATION; | |
132 iter_ = iterator; | |
133 } | |
134 | |
135 void BackendIO::OnExternalCacheHit(const std::string& key) { | |
136 operation_ = OP_ON_EXTERNAL_CACHE_HIT; | |
137 key_ = key; | |
138 } | |
139 | |
140 void BackendIO::CloseEntryImpl(EntryImpl* entry) { | |
141 operation_ = OP_CLOSE_ENTRY; | |
142 entry_ = entry; | |
143 } | |
144 | |
145 void BackendIO::DoomEntryImpl(EntryImpl* entry) { | |
146 operation_ = OP_DOOM_ENTRY; | |
147 entry_ = entry; | |
148 } | |
149 | |
150 void BackendIO::FlushQueue() { | |
151 operation_ = OP_FLUSH_QUEUE; | |
152 } | |
153 | |
154 void BackendIO::RunTask(const base::Closure& task) { | |
155 operation_ = OP_RUN_TASK; | |
156 task_ = task; | |
157 } | |
158 | |
159 void BackendIO::ReadData(EntryImpl* entry, int index, int offset, | |
160 net::IOBuffer* buf, int buf_len) { | |
161 operation_ = OP_READ; | |
162 entry_ = entry; | |
163 index_ = index; | |
164 offset_ = offset; | |
165 buf_ = buf; | |
166 buf_len_ = buf_len; | |
167 } | |
168 | |
169 void BackendIO::WriteData(EntryImpl* entry, int index, int offset, | |
170 net::IOBuffer* buf, int buf_len, bool truncate) { | |
171 operation_ = OP_WRITE; | |
172 entry_ = entry; | |
173 index_ = index; | |
174 offset_ = offset; | |
175 buf_ = buf; | |
176 buf_len_ = buf_len; | |
177 truncate_ = truncate; | |
178 } | |
179 | |
180 void BackendIO::ReadSparseData(EntryImpl* entry, int64 offset, | |
181 net::IOBuffer* buf, int buf_len) { | |
182 operation_ = OP_READ_SPARSE; | |
183 entry_ = entry; | |
184 offset64_ = offset; | |
185 buf_ = buf; | |
186 buf_len_ = buf_len; | |
187 } | |
188 | |
189 void BackendIO::WriteSparseData(EntryImpl* entry, int64 offset, | |
190 net::IOBuffer* buf, int buf_len) { | |
191 operation_ = OP_WRITE_SPARSE; | |
192 entry_ = entry; | |
193 offset64_ = offset; | |
194 buf_ = buf; | |
195 buf_len_ = buf_len; | |
196 } | |
197 | |
198 void BackendIO::GetAvailableRange(EntryImpl* entry, int64 offset, int len, | |
199 int64* start) { | |
200 operation_ = OP_GET_RANGE; | |
201 entry_ = entry; | |
202 offset64_ = offset; | |
203 buf_len_ = len; | |
204 start_ = start; | |
205 } | |
206 | |
207 void BackendIO::CancelSparseIO(EntryImpl* entry) { | |
208 operation_ = OP_CANCEL_IO; | |
209 entry_ = entry; | |
210 } | |
211 | |
212 void BackendIO::ReadyForSparseIO(EntryImpl* entry) { | |
213 operation_ = OP_IS_READY; | |
214 entry_ = entry; | |
215 } | |
216 | |
217 BackendIO::~BackendIO() {} | |
218 | |
219 bool BackendIO::ReturnsEntry() { | |
220 return (operation_ == OP_OPEN || operation_ == OP_CREATE || | |
221 operation_ == OP_OPEN_NEXT || operation_ == OP_OPEN_PREV); | |
222 } | |
223 | |
224 base::TimeDelta BackendIO::ElapsedTime() const { | |
225 return base::TimeTicks::Now() - start_time_; | |
226 } | |
227 | |
228 // Runs on the background thread. | |
229 void BackendIO::ExecuteBackendOperation() { | |
230 switch (operation_) { | |
231 case OP_INIT: | |
232 result_ = backend_->SyncInit(); | |
233 break; | |
234 case OP_OPEN: | |
235 result_ = backend_->SyncOpenEntry(key_, entry_ptr_); | |
236 break; | |
237 case OP_CREATE: | |
238 result_ = backend_->SyncCreateEntry(key_, entry_ptr_); | |
239 break; | |
240 case OP_DOOM: | |
241 result_ = backend_->SyncDoomEntry(key_); | |
242 break; | |
243 case OP_DOOM_ALL: | |
244 result_ = backend_->SyncDoomAllEntries(); | |
245 break; | |
246 case OP_DOOM_BETWEEN: | |
247 result_ = backend_->SyncDoomEntriesBetween(initial_time_, end_time_); | |
248 break; | |
249 case OP_DOOM_SINCE: | |
250 result_ = backend_->SyncDoomEntriesSince(initial_time_); | |
251 break; | |
252 case OP_OPEN_NEXT: | |
253 result_ = backend_->SyncOpenNextEntry(iter_ptr_, entry_ptr_); | |
254 break; | |
255 case OP_OPEN_PREV: | |
256 result_ = backend_->SyncOpenPrevEntry(iter_ptr_, entry_ptr_); | |
257 break; | |
258 case OP_END_ENUMERATION: | |
259 backend_->SyncEndEnumeration(iter_); | |
260 result_ = net::OK; | |
261 break; | |
262 case OP_ON_EXTERNAL_CACHE_HIT: | |
263 backend_->SyncOnExternalCacheHit(key_); | |
264 result_ = net::OK; | |
265 break; | |
266 case OP_CLOSE_ENTRY: | |
267 entry_->Release(); | |
268 result_ = net::OK; | |
269 break; | |
270 case OP_DOOM_ENTRY: | |
271 entry_->DoomImpl(); | |
272 result_ = net::OK; | |
273 break; | |
274 case OP_FLUSH_QUEUE: | |
275 result_ = net::OK; | |
276 break; | |
277 case OP_RUN_TASK: | |
278 task_.Run(); | |
279 result_ = net::OK; | |
280 break; | |
281 default: | |
282 NOTREACHED() << "Invalid Operation"; | |
283 result_ = net::ERR_UNEXPECTED; | |
284 } | |
285 DCHECK_NE(net::ERR_IO_PENDING, result_); | |
286 NotifyController(); | |
287 } | |
288 | |
289 // Runs on the background thread. | |
290 void BackendIO::ExecuteEntryOperation() { | |
291 switch (operation_) { | |
292 case OP_READ: | |
293 result_ = | |
294 entry_->ReadDataImpl(index_, offset_, buf_.get(), buf_len_, | |
295 base::Bind(&BackendIO::OnIOComplete, this)); | |
296 break; | |
297 case OP_WRITE: | |
298 result_ = | |
299 entry_->WriteDataImpl(index_, offset_, buf_.get(), buf_len_, | |
300 base::Bind(&BackendIO::OnIOComplete, this), | |
301 truncate_); | |
302 break; | |
303 case OP_READ_SPARSE: | |
304 result_ = entry_->ReadSparseDataImpl( | |
305 offset64_, buf_.get(), buf_len_, | |
306 base::Bind(&BackendIO::OnIOComplete, this)); | |
307 break; | |
308 case OP_WRITE_SPARSE: | |
309 result_ = entry_->WriteSparseDataImpl( | |
310 offset64_, buf_.get(), buf_len_, | |
311 base::Bind(&BackendIO::OnIOComplete, this)); | |
312 break; | |
313 case OP_GET_RANGE: | |
314 result_ = entry_->GetAvailableRangeImpl(offset64_, buf_len_, start_); | |
315 break; | |
316 case OP_CANCEL_IO: | |
317 entry_->CancelSparseIOImpl(); | |
318 result_ = net::OK; | |
319 break; | |
320 case OP_IS_READY: | |
321 result_ = entry_->ReadyForSparseIOImpl( | |
322 base::Bind(&BackendIO::OnIOComplete, this)); | |
323 break; | |
324 default: | |
325 NOTREACHED() << "Invalid Operation"; | |
326 result_ = net::ERR_UNEXPECTED; | |
327 } | |
328 buf_ = NULL; | |
329 if (result_ != net::ERR_IO_PENDING) | |
330 NotifyController(); | |
331 } | |
332 | |
333 InFlightBackendIO::InFlightBackendIO(BackendImpl* backend, | |
334 base::MessageLoopProxy* background_thread) | |
335 : backend_(backend), | |
336 background_thread_(background_thread), | |
337 ptr_factory_(this) { | |
338 } | |
339 | |
340 InFlightBackendIO::~InFlightBackendIO() { | |
341 } | |
342 | |
343 void InFlightBackendIO::Init(const net::CompletionCallback& callback) { | |
344 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
345 operation->Init(); | |
346 PostOperation(operation.get()); | |
347 } | |
348 | |
349 void InFlightBackendIO::OpenEntry(const std::string& key, Entry** entry, | |
350 const net::CompletionCallback& callback) { | |
351 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
352 operation->OpenEntry(key, entry); | |
353 PostOperation(operation.get()); | |
354 } | |
355 | |
356 void InFlightBackendIO::CreateEntry(const std::string& key, Entry** entry, | |
357 const net::CompletionCallback& callback) { | |
358 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
359 operation->CreateEntry(key, entry); | |
360 PostOperation(operation.get()); | |
361 } | |
362 | |
363 void InFlightBackendIO::DoomEntry(const std::string& key, | |
364 const net::CompletionCallback& callback) { | |
365 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
366 operation->DoomEntry(key); | |
367 PostOperation(operation.get()); | |
368 } | |
369 | |
370 void InFlightBackendIO::DoomAllEntries( | |
371 const net::CompletionCallback& callback) { | |
372 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
373 operation->DoomAllEntries(); | |
374 PostOperation(operation.get()); | |
375 } | |
376 | |
377 void InFlightBackendIO::DoomEntriesBetween(const base::Time initial_time, | |
378 const base::Time end_time, | |
379 const net::CompletionCallback& callback) { | |
380 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
381 operation->DoomEntriesBetween(initial_time, end_time); | |
382 PostOperation(operation.get()); | |
383 } | |
384 | |
385 void InFlightBackendIO::DoomEntriesSince( | |
386 const base::Time initial_time, const net::CompletionCallback& callback) { | |
387 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
388 operation->DoomEntriesSince(initial_time); | |
389 PostOperation(operation.get()); | |
390 } | |
391 | |
392 void InFlightBackendIO::OpenNextEntry(void** iter, Entry** next_entry, | |
393 const net::CompletionCallback& callback) { | |
394 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
395 operation->OpenNextEntry(iter, next_entry); | |
396 PostOperation(operation.get()); | |
397 } | |
398 | |
399 void InFlightBackendIO::OpenPrevEntry(void** iter, Entry** prev_entry, | |
400 const net::CompletionCallback& callback) { | |
401 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
402 operation->OpenPrevEntry(iter, prev_entry); | |
403 PostOperation(operation.get()); | |
404 } | |
405 | |
406 void InFlightBackendIO::EndEnumeration(void* iterator) { | |
407 scoped_refptr<BackendIO> operation( | |
408 new BackendIO(this, backend_, net::CompletionCallback())); | |
409 operation->EndEnumeration(iterator); | |
410 PostOperation(operation.get()); | |
411 } | |
412 | |
413 void InFlightBackendIO::OnExternalCacheHit(const std::string& key) { | |
414 scoped_refptr<BackendIO> operation( | |
415 new BackendIO(this, backend_, net::CompletionCallback())); | |
416 operation->OnExternalCacheHit(key); | |
417 PostOperation(operation.get()); | |
418 } | |
419 | |
420 void InFlightBackendIO::CloseEntryImpl(EntryImpl* entry) { | |
421 scoped_refptr<BackendIO> operation( | |
422 new BackendIO(this, backend_, net::CompletionCallback())); | |
423 operation->CloseEntryImpl(entry); | |
424 PostOperation(operation.get()); | |
425 } | |
426 | |
427 void InFlightBackendIO::DoomEntryImpl(EntryImpl* entry) { | |
428 scoped_refptr<BackendIO> operation( | |
429 new BackendIO(this, backend_, net::CompletionCallback())); | |
430 operation->DoomEntryImpl(entry); | |
431 PostOperation(operation.get()); | |
432 } | |
433 | |
434 void InFlightBackendIO::FlushQueue(const net::CompletionCallback& callback) { | |
435 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
436 operation->FlushQueue(); | |
437 PostOperation(operation.get()); | |
438 } | |
439 | |
440 void InFlightBackendIO::RunTask( | |
441 const base::Closure& task, const net::CompletionCallback& callback) { | |
442 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
443 operation->RunTask(task); | |
444 PostOperation(operation.get()); | |
445 } | |
446 | |
447 void InFlightBackendIO::ReadData(EntryImpl* entry, int index, int offset, | |
448 net::IOBuffer* buf, int buf_len, | |
449 const net::CompletionCallback& callback) { | |
450 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
451 operation->ReadData(entry, index, offset, buf, buf_len); | |
452 PostOperation(operation.get()); | |
453 } | |
454 | |
455 void InFlightBackendIO::WriteData(EntryImpl* entry, int index, int offset, | |
456 net::IOBuffer* buf, int buf_len, | |
457 bool truncate, | |
458 const net::CompletionCallback& callback) { | |
459 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
460 operation->WriteData(entry, index, offset, buf, buf_len, truncate); | |
461 PostOperation(operation.get()); | |
462 } | |
463 | |
464 void InFlightBackendIO::ReadSparseData( | |
465 EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len, | |
466 const net::CompletionCallback& callback) { | |
467 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
468 operation->ReadSparseData(entry, offset, buf, buf_len); | |
469 PostOperation(operation.get()); | |
470 } | |
471 | |
472 void InFlightBackendIO::WriteSparseData( | |
473 EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len, | |
474 const net::CompletionCallback& callback) { | |
475 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
476 operation->WriteSparseData(entry, offset, buf, buf_len); | |
477 PostOperation(operation.get()); | |
478 } | |
479 | |
480 void InFlightBackendIO::GetAvailableRange( | |
481 EntryImpl* entry, int64 offset, int len, int64* start, | |
482 const net::CompletionCallback& callback) { | |
483 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
484 operation->GetAvailableRange(entry, offset, len, start); | |
485 PostOperation(operation.get()); | |
486 } | |
487 | |
488 void InFlightBackendIO::CancelSparseIO(EntryImpl* entry) { | |
489 scoped_refptr<BackendIO> operation( | |
490 new BackendIO(this, backend_, net::CompletionCallback())); | |
491 operation->CancelSparseIO(entry); | |
492 PostOperation(operation.get()); | |
493 } | |
494 | |
495 void InFlightBackendIO::ReadyForSparseIO( | |
496 EntryImpl* entry, const net::CompletionCallback& callback) { | |
497 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
498 operation->ReadyForSparseIO(entry); | |
499 PostOperation(operation.get()); | |
500 } | |
501 | |
502 void InFlightBackendIO::WaitForPendingIO() { | |
503 InFlightIO::WaitForPendingIO(); | |
504 } | |
505 | |
506 void InFlightBackendIO::OnOperationComplete(BackgroundIO* operation, | |
507 bool cancel) { | |
508 BackendIO* op = static_cast<BackendIO*>(operation); | |
509 op->OnDone(cancel); | |
510 | |
511 if (!op->callback().is_null() && (!cancel || op->IsEntryOperation())) | |
512 op->callback().Run(op->result()); | |
513 } | |
514 | |
515 void InFlightBackendIO::PostOperation(BackendIO* operation) { | |
516 background_thread_->PostTask(FROM_HERE, | |
517 base::Bind(&BackendIO::ExecuteOperation, operation)); | |
518 OnOperationPosted(operation); | |
519 } | |
520 | |
521 base::WeakPtr<InFlightBackendIO> InFlightBackendIO::GetWeakPtr() { | |
522 return ptr_factory_.GetWeakPtr(); | |
523 } | |
524 | |
525 } // namespace | |
OLD | NEW |