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