1 // Copyright 2012 The Chromium Authors
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/blockfile/in_flight_backend_io.h"
6
7 #include <utility>
8
9 #include "base/check_op.h"
10 #include "base/compiler_specific.h"
11 #include "base/functional/bind.h"
12 #include "base/functional/callback_helpers.h"
13 #include "base/location.h"
14 #include "base/notreached.h"
15 #include "base/task/single_thread_task_runner.h"
16 #include "net/base/net_errors.h"
17 #include "net/disk_cache/blockfile/backend_impl.h"
18 #include "net/disk_cache/blockfile/entry_impl.h"
19 #include "net/disk_cache/blockfile/histogram_macros.h"
20
21 // Provide a BackendImpl object to macros from histogram_macros.h.
22 #define CACHE_UMA_BACKEND_IMPL_OBJ backend_
23
24 namespace disk_cache {
25
26 namespace {
27
28 // Used to leak a strong reference to an EntryImpl to the user of disk_cache.
LeakEntryImpl(scoped_refptr<EntryImpl> entry)29 EntryImpl* LeakEntryImpl(scoped_refptr<EntryImpl> entry) {
30 // Balanced on OP_CLOSE_ENTRY handling in BackendIO::ExecuteBackendOperation.
31 if (entry)
32 entry->AddRef();
33 return entry.get();
34 }
35
36 } // namespace
37
BackendIO(InFlightBackendIO * controller,BackendImpl * backend,net::CompletionOnceCallback callback)38 BackendIO::BackendIO(InFlightBackendIO* controller,
39 BackendImpl* backend,
40 net::CompletionOnceCallback callback)
41 : BackendIO(controller, backend) {
42 callback_ = std::move(callback);
43 }
44
BackendIO(InFlightBackendIO * controller,BackendImpl * backend,EntryResultCallback callback)45 BackendIO::BackendIO(InFlightBackendIO* controller,
46 BackendImpl* backend,
47 EntryResultCallback callback)
48 : BackendIO(controller, backend) {
49 entry_result_callback_ = std::move(callback);
50 }
51
BackendIO(InFlightBackendIO * controller,BackendImpl * backend,RangeResultCallback callback)52 BackendIO::BackendIO(InFlightBackendIO* controller,
53 BackendImpl* backend,
54 RangeResultCallback callback)
55 : BackendIO(controller, backend) {
56 range_result_callback_ = std::move(callback);
57 }
58
BackendIO(InFlightBackendIO * controller,BackendImpl * backend)59 BackendIO::BackendIO(InFlightBackendIO* controller, BackendImpl* backend)
60 : BackgroundIO(controller),
61 backend_(backend),
62 background_task_runner_(controller->background_thread()) {
63 DCHECK(background_task_runner_);
64 start_time_ = base::TimeTicks::Now();
65 }
66
67 // Runs on the background thread.
ExecuteOperation()68 void BackendIO::ExecuteOperation() {
69 if (IsEntryOperation())
70 return ExecuteEntryOperation();
71
72 ExecuteBackendOperation();
73 }
74
75 // Runs on the background thread.
OnIOComplete(int result)76 void BackendIO::OnIOComplete(int result) {
77 DCHECK(IsEntryOperation());
78 DCHECK_NE(result, net::ERR_IO_PENDING);
79 result_ = result;
80 NotifyController();
81 }
82
83 // Runs on the primary thread.
OnDone(bool cancel)84 void BackendIO::OnDone(bool cancel) {
85 if (IsEntryOperation()) {
86 CACHE_UMA(TIMES, "TotalIOTime", 0, ElapsedTime());
87 if (operation_ == OP_READ) {
88 CACHE_UMA(TIMES, "TotalIOTimeRead", 0, ElapsedTime());
89 } else if (operation_ == OP_WRITE) {
90 CACHE_UMA(TIMES, "TotalIOTimeWrite", 0, ElapsedTime());
91 }
92 }
93
94 if (ReturnsEntry() && result_ == net::OK) {
95 static_cast<EntryImpl*>(out_entry_)->OnEntryCreated(backend_);
96 if (cancel)
97 out_entry_.ExtractAsDangling()->Close();
98 }
99 ClearController();
100 }
101
IsEntryOperation()102 bool BackendIO::IsEntryOperation() {
103 return operation_ > OP_MAX_BACKEND;
104 }
105
RunCallback(int result)106 void BackendIO::RunCallback(int result) {
107 std::move(callback_).Run(result);
108 }
109
RunEntryResultCallback()110 void BackendIO::RunEntryResultCallback() {
111 EntryResult entry_result;
112 if (result_ != net::OK) {
113 entry_result = EntryResult::MakeError(static_cast<net::Error>(result()));
114 } else if (out_entry_opened_) {
115 entry_result = EntryResult::MakeOpened(out_entry_);
116 } else {
117 entry_result = EntryResult::MakeCreated(out_entry_);
118 }
119 std::move(entry_result_callback_).Run(std::move(entry_result));
120 }
121
RunRangeResultCallback()122 void BackendIO::RunRangeResultCallback() {
123 std::move(range_result_callback_).Run(range_result_);
124 }
125
Init()126 void BackendIO::Init() {
127 operation_ = OP_INIT;
128 }
129
OpenOrCreateEntry(const std::string & key)130 void BackendIO::OpenOrCreateEntry(const std::string& key) {
131 operation_ = OP_OPEN_OR_CREATE;
132 key_ = key;
133 }
134
OpenEntry(const std::string & key)135 void BackendIO::OpenEntry(const std::string& key) {
136 operation_ = OP_OPEN;
137 key_ = key;
138 }
139
CreateEntry(const std::string & key)140 void BackendIO::CreateEntry(const std::string& key) {
141 operation_ = OP_CREATE;
142 key_ = key;
143 }
144
DoomEntry(const std::string & key)145 void BackendIO::DoomEntry(const std::string& key) {
146 operation_ = OP_DOOM;
147 key_ = key;
148 }
149
DoomAllEntries()150 void BackendIO::DoomAllEntries() {
151 operation_ = OP_DOOM_ALL;
152 }
153
DoomEntriesBetween(const base::Time initial_time,const base::Time end_time)154 void BackendIO::DoomEntriesBetween(const base::Time initial_time,
155 const base::Time end_time) {
156 operation_ = OP_DOOM_BETWEEN;
157 initial_time_ = initial_time;
158 end_time_ = end_time;
159 }
160
DoomEntriesSince(const base::Time initial_time)161 void BackendIO::DoomEntriesSince(const base::Time initial_time) {
162 operation_ = OP_DOOM_SINCE;
163 initial_time_ = initial_time;
164 }
165
CalculateSizeOfAllEntries()166 void BackendIO::CalculateSizeOfAllEntries() {
167 operation_ = OP_SIZE_ALL;
168 }
169
OpenNextEntry(Rankings::Iterator * iterator)170 void BackendIO::OpenNextEntry(Rankings::Iterator* iterator) {
171 operation_ = OP_OPEN_NEXT;
172 iterator_ = iterator;
173 }
174
EndEnumeration(std::unique_ptr<Rankings::Iterator> iterator)175 void BackendIO::EndEnumeration(std::unique_ptr<Rankings::Iterator> iterator) {
176 operation_ = OP_END_ENUMERATION;
177 scoped_iterator_ = std::move(iterator);
178 }
179
OnExternalCacheHit(const std::string & key)180 void BackendIO::OnExternalCacheHit(const std::string& key) {
181 operation_ = OP_ON_EXTERNAL_CACHE_HIT;
182 key_ = key;
183 }
184
CloseEntryImpl(EntryImpl * entry)185 void BackendIO::CloseEntryImpl(EntryImpl* entry) {
186 operation_ = OP_CLOSE_ENTRY;
187 entry_ = entry;
188 }
189
DoomEntryImpl(EntryImpl * entry)190 void BackendIO::DoomEntryImpl(EntryImpl* entry) {
191 operation_ = OP_DOOM_ENTRY;
192 entry_ = entry;
193 }
194
FlushQueue()195 void BackendIO::FlushQueue() {
196 operation_ = OP_FLUSH_QUEUE;
197 }
198
RunTask(base::OnceClosure task)199 void BackendIO::RunTask(base::OnceClosure task) {
200 operation_ = OP_RUN_TASK;
201 task_ = std::move(task);
202 }
203
ReadData(EntryImpl * entry,int index,int offset,net::IOBuffer * buf,int buf_len)204 void BackendIO::ReadData(EntryImpl* entry, int index, int offset,
205 net::IOBuffer* buf, int buf_len) {
206 operation_ = OP_READ;
207 entry_ = entry;
208 index_ = index;
209 offset_ = offset;
210 buf_ = buf;
211 buf_len_ = buf_len;
212 }
213
WriteData(EntryImpl * entry,int index,int offset,net::IOBuffer * buf,int buf_len,bool truncate)214 void BackendIO::WriteData(EntryImpl* entry, int index, int offset,
215 net::IOBuffer* buf, int buf_len, bool truncate) {
216 operation_ = OP_WRITE;
217 entry_ = entry;
218 index_ = index;
219 offset_ = offset;
220 buf_ = buf;
221 buf_len_ = buf_len;
222 truncate_ = truncate;
223 }
224
ReadSparseData(EntryImpl * entry,int64_t offset,net::IOBuffer * buf,int buf_len)225 void BackendIO::ReadSparseData(EntryImpl* entry,
226 int64_t offset,
227 net::IOBuffer* buf,
228 int buf_len) {
229 operation_ = OP_READ_SPARSE;
230 entry_ = entry;
231 offset64_ = offset;
232 buf_ = buf;
233 buf_len_ = buf_len;
234 }
235
WriteSparseData(EntryImpl * entry,int64_t offset,net::IOBuffer * buf,int buf_len)236 void BackendIO::WriteSparseData(EntryImpl* entry,
237 int64_t offset,
238 net::IOBuffer* buf,
239 int buf_len) {
240 operation_ = OP_WRITE_SPARSE;
241 entry_ = entry;
242 offset64_ = offset;
243 buf_ = buf;
244 buf_len_ = buf_len;
245 }
246
GetAvailableRange(EntryImpl * entry,int64_t offset,int len)247 void BackendIO::GetAvailableRange(EntryImpl* entry, int64_t offset, int len) {
248 operation_ = OP_GET_RANGE;
249 entry_ = entry;
250 offset64_ = offset;
251 buf_len_ = len;
252 }
253
CancelSparseIO(EntryImpl * entry)254 void BackendIO::CancelSparseIO(EntryImpl* entry) {
255 operation_ = OP_CANCEL_IO;
256 entry_ = entry;
257 }
258
ReadyForSparseIO(EntryImpl * entry)259 void BackendIO::ReadyForSparseIO(EntryImpl* entry) {
260 operation_ = OP_IS_READY;
261 entry_ = entry;
262 }
263
~BackendIO()264 BackendIO::~BackendIO() {
265 if (!did_notify_controller_io_signalled() && out_entry_) {
266 // At this point it's very likely the Entry does not have a
267 // `background_queue_` so that Close() would do nothing. Post an empty
268 // task to the background task runner, which should effectively destroy
269 // the entry as there are no more references. Destruction has to happen
270 // on the background task runner.
271 scoped_refptr<EntryImpl> entry(out_entry_.ExtractAsDangling());
272 // This balances the ref taken in LeakEntryImpl().
273 entry->Release();
274 // This should be the last ref.
275 DCHECK(entry->HasOneRef());
276 background_task_runner_->PostTask(
277 FROM_HERE, base::DoNothingWithBoundArgs(std::move(entry)));
278 }
279 }
280
ReturnsEntry()281 bool BackendIO::ReturnsEntry() {
282 return operation_ == OP_OPEN || operation_ == OP_CREATE ||
283 operation_ == OP_OPEN_NEXT || operation_ == OP_OPEN_OR_CREATE;
284 }
285
ElapsedTime() const286 base::TimeDelta BackendIO::ElapsedTime() const {
287 return base::TimeTicks::Now() - start_time_;
288 }
289
290 // Runs on the background thread.
ExecuteBackendOperation()291 void BackendIO::ExecuteBackendOperation() {
292 switch (operation_) {
293 case OP_INIT:
294 result_ = backend_->SyncInit();
295 break;
296 case OP_OPEN_OR_CREATE: {
297 scoped_refptr<EntryImpl> entry;
298 result_ = backend_->SyncOpenEntry(key_, &entry);
299
300 if (result_ == net::OK) {
301 out_entry_ = LeakEntryImpl(std::move(entry));
302 out_entry_opened_ = true;
303 break;
304 }
305
306 // Opening failed, create an entry instead.
307 result_ = backend_->SyncCreateEntry(key_, &entry);
308 out_entry_ = LeakEntryImpl(std::move(entry));
309 out_entry_opened_ = false;
310 break;
311 }
312 case OP_OPEN: {
313 scoped_refptr<EntryImpl> entry;
314 result_ = backend_->SyncOpenEntry(key_, &entry);
315 out_entry_ = LeakEntryImpl(std::move(entry));
316 out_entry_opened_ = true;
317 break;
318 }
319 case OP_CREATE: {
320 scoped_refptr<EntryImpl> entry;
321 result_ = backend_->SyncCreateEntry(key_, &entry);
322 out_entry_ = LeakEntryImpl(std::move(entry));
323 out_entry_opened_ = false;
324 break;
325 }
326 case OP_DOOM:
327 result_ = backend_->SyncDoomEntry(key_);
328 break;
329 case OP_DOOM_ALL:
330 result_ = backend_->SyncDoomAllEntries();
331 break;
332 case OP_DOOM_BETWEEN:
333 result_ = backend_->SyncDoomEntriesBetween(initial_time_, end_time_);
334 break;
335 case OP_DOOM_SINCE:
336 result_ = backend_->SyncDoomEntriesSince(initial_time_);
337 break;
338 case OP_SIZE_ALL:
339 result_ = backend_->SyncCalculateSizeOfAllEntries();
340 break;
341 case OP_OPEN_NEXT: {
342 scoped_refptr<EntryImpl> entry;
343 result_ = backend_->SyncOpenNextEntry(iterator_, &entry);
344 out_entry_ = LeakEntryImpl(std::move(entry));
345 out_entry_opened_ = true;
346 // `iterator_` is a proxied argument and not needed beyond this point. Set
347 // it to nullptr so as to not leave a dangling pointer around.
348 iterator_ = nullptr;
349 break;
350 }
351 case OP_END_ENUMERATION:
352 backend_->SyncEndEnumeration(std::move(scoped_iterator_));
353 result_ = net::OK;
354 break;
355 case OP_ON_EXTERNAL_CACHE_HIT:
356 backend_->SyncOnExternalCacheHit(key_);
357 result_ = net::OK;
358 break;
359 case OP_CLOSE_ENTRY:
360 // Collect the reference to |entry_| to balance with the AddRef() in
361 // LeakEntryImpl.
362 entry_.ExtractAsDangling()->Release();
363 result_ = net::OK;
364 break;
365 case OP_DOOM_ENTRY:
366 entry_->DoomImpl();
367 result_ = net::OK;
368 break;
369 case OP_FLUSH_QUEUE:
370 result_ = net::OK;
371 break;
372 case OP_RUN_TASK:
373 std::move(task_).Run();
374 result_ = net::OK;
375 break;
376 default:
377 NOTREACHED() << "Invalid Operation";
378 result_ = net::ERR_UNEXPECTED;
379 }
380 DCHECK_NE(net::ERR_IO_PENDING, result_);
381 NotifyController();
382 backend_->OnSyncBackendOpComplete();
383 }
384
385 // Runs on the background thread.
ExecuteEntryOperation()386 void BackendIO::ExecuteEntryOperation() {
387 switch (operation_) {
388 case OP_READ:
389 result_ =
390 entry_->ReadDataImpl(index_, offset_, buf_.get(), buf_len_,
391 base::BindOnce(&BackendIO::OnIOComplete, this));
392 break;
393 case OP_WRITE:
394 result_ = entry_->WriteDataImpl(
395 index_, offset_, buf_.get(), buf_len_,
396 base::BindOnce(&BackendIO::OnIOComplete, this), truncate_);
397 break;
398 case OP_READ_SPARSE:
399 result_ = entry_->ReadSparseDataImpl(
400 offset64_, buf_.get(), buf_len_,
401 base::BindOnce(&BackendIO::OnIOComplete, this));
402 break;
403 case OP_WRITE_SPARSE:
404 result_ = entry_->WriteSparseDataImpl(
405 offset64_, buf_.get(), buf_len_,
406 base::BindOnce(&BackendIO::OnIOComplete, this));
407 break;
408 case OP_GET_RANGE:
409 range_result_ = entry_->GetAvailableRangeImpl(offset64_, buf_len_);
410 result_ = range_result_.net_error;
411 break;
412 case OP_CANCEL_IO:
413 entry_->CancelSparseIOImpl();
414 result_ = net::OK;
415 break;
416 case OP_IS_READY:
417 result_ = entry_->ReadyForSparseIOImpl(
418 base::BindOnce(&BackendIO::OnIOComplete, this));
419 break;
420 default:
421 NOTREACHED() << "Invalid Operation";
422 result_ = net::ERR_UNEXPECTED;
423 }
424 buf_ = nullptr;
425 if (result_ != net::ERR_IO_PENDING)
426 NotifyController();
427 }
428
InFlightBackendIO(BackendImpl * backend,const scoped_refptr<base::SingleThreadTaskRunner> & background_thread)429 InFlightBackendIO::InFlightBackendIO(
430 BackendImpl* backend,
431 const scoped_refptr<base::SingleThreadTaskRunner>& background_thread)
432 : backend_(backend), background_thread_(background_thread) {}
433
434 InFlightBackendIO::~InFlightBackendIO() = default;
435
Init(net::CompletionOnceCallback callback)436 void InFlightBackendIO::Init(net::CompletionOnceCallback callback) {
437 auto operation =
438 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
439 operation->Init();
440 PostOperation(FROM_HERE, operation.get());
441 }
442
OpenOrCreateEntry(const std::string & key,EntryResultCallback callback)443 void InFlightBackendIO::OpenOrCreateEntry(const std::string& key,
444 EntryResultCallback callback) {
445 auto operation =
446 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
447 operation->OpenOrCreateEntry(key);
448 PostOperation(FROM_HERE, operation.get());
449 }
450
OpenEntry(const std::string & key,EntryResultCallback callback)451 void InFlightBackendIO::OpenEntry(const std::string& key,
452 EntryResultCallback callback) {
453 auto operation =
454 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
455 operation->OpenEntry(key);
456 PostOperation(FROM_HERE, operation.get());
457 }
458
CreateEntry(const std::string & key,EntryResultCallback callback)459 void InFlightBackendIO::CreateEntry(const std::string& key,
460 EntryResultCallback callback) {
461 auto operation =
462 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
463 operation->CreateEntry(key);
464 PostOperation(FROM_HERE, operation.get());
465 }
466
DoomEntry(const std::string & key,net::CompletionOnceCallback callback)467 void InFlightBackendIO::DoomEntry(const std::string& key,
468 net::CompletionOnceCallback callback) {
469 auto operation =
470 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
471 operation->DoomEntry(key);
472 PostOperation(FROM_HERE, operation.get());
473 }
474
DoomAllEntries(net::CompletionOnceCallback callback)475 void InFlightBackendIO::DoomAllEntries(net::CompletionOnceCallback callback) {
476 auto operation =
477 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
478 operation->DoomAllEntries();
479 PostOperation(FROM_HERE, operation.get());
480 }
481
DoomEntriesBetween(const base::Time initial_time,const base::Time end_time,net::CompletionOnceCallback callback)482 void InFlightBackendIO::DoomEntriesBetween(
483 const base::Time initial_time,
484 const base::Time end_time,
485 net::CompletionOnceCallback callback) {
486 auto operation =
487 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
488 operation->DoomEntriesBetween(initial_time, end_time);
489 PostOperation(FROM_HERE, operation.get());
490 }
491
CalculateSizeOfAllEntries(net::CompletionOnceCallback callback)492 void InFlightBackendIO::CalculateSizeOfAllEntries(
493 net::CompletionOnceCallback callback) {
494 auto operation =
495 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
496 operation->CalculateSizeOfAllEntries();
497 PostOperation(FROM_HERE, operation.get());
498 }
499
DoomEntriesSince(const base::Time initial_time,net::CompletionOnceCallback callback)500 void InFlightBackendIO::DoomEntriesSince(const base::Time initial_time,
501 net::CompletionOnceCallback callback) {
502 auto operation =
503 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
504 operation->DoomEntriesSince(initial_time);
505 PostOperation(FROM_HERE, operation.get());
506 }
507
OpenNextEntry(Rankings::Iterator * iterator,EntryResultCallback callback)508 void InFlightBackendIO::OpenNextEntry(Rankings::Iterator* iterator,
509 EntryResultCallback callback) {
510 auto operation =
511 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
512 operation->OpenNextEntry(iterator);
513 PostOperation(FROM_HERE, operation.get());
514 }
515
EndEnumeration(std::unique_ptr<Rankings::Iterator> iterator)516 void InFlightBackendIO::EndEnumeration(
517 std::unique_ptr<Rankings::Iterator> iterator) {
518 auto operation = base::MakeRefCounted<BackendIO>(
519 this, backend_, net::CompletionOnceCallback());
520 operation->EndEnumeration(std::move(iterator));
521 PostOperation(FROM_HERE, operation.get());
522 }
523
OnExternalCacheHit(const std::string & key)524 void InFlightBackendIO::OnExternalCacheHit(const std::string& key) {
525 auto operation = base::MakeRefCounted<BackendIO>(
526 this, backend_, net::CompletionOnceCallback());
527 operation->OnExternalCacheHit(key);
528 PostOperation(FROM_HERE, operation.get());
529 }
530
CloseEntryImpl(EntryImpl * entry)531 void InFlightBackendIO::CloseEntryImpl(EntryImpl* entry) {
532 auto operation = base::MakeRefCounted<BackendIO>(
533 this, backend_, net::CompletionOnceCallback());
534 operation->CloseEntryImpl(entry);
535 PostOperation(FROM_HERE, operation.get());
536 }
537
DoomEntryImpl(EntryImpl * entry)538 void InFlightBackendIO::DoomEntryImpl(EntryImpl* entry) {
539 auto operation = base::MakeRefCounted<BackendIO>(
540 this, backend_, net::CompletionOnceCallback());
541 operation->DoomEntryImpl(entry);
542 PostOperation(FROM_HERE, operation.get());
543 }
544
FlushQueue(net::CompletionOnceCallback callback)545 void InFlightBackendIO::FlushQueue(net::CompletionOnceCallback callback) {
546 auto operation =
547 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
548 operation->FlushQueue();
549 PostOperation(FROM_HERE, operation.get());
550 }
551
RunTask(base::OnceClosure task,net::CompletionOnceCallback callback)552 void InFlightBackendIO::RunTask(base::OnceClosure task,
553 net::CompletionOnceCallback callback) {
554 auto operation =
555 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
556 operation->RunTask(std::move(task));
557 PostOperation(FROM_HERE, operation.get());
558 }
559
ReadData(EntryImpl * entry,int index,int offset,net::IOBuffer * buf,int buf_len,net::CompletionOnceCallback callback)560 void InFlightBackendIO::ReadData(EntryImpl* entry,
561 int index,
562 int offset,
563 net::IOBuffer* buf,
564 int buf_len,
565 net::CompletionOnceCallback callback) {
566 auto operation =
567 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
568 operation->ReadData(entry, index, offset, buf, buf_len);
569 PostOperation(FROM_HERE, operation.get());
570 }
571
WriteData(EntryImpl * entry,int index,int offset,net::IOBuffer * buf,int buf_len,bool truncate,net::CompletionOnceCallback callback)572 void InFlightBackendIO::WriteData(EntryImpl* entry,
573 int index,
574 int offset,
575 net::IOBuffer* buf,
576 int buf_len,
577 bool truncate,
578 net::CompletionOnceCallback callback) {
579 auto operation =
580 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
581 operation->WriteData(entry, index, offset, buf, buf_len, truncate);
582 PostOperation(FROM_HERE, operation.get());
583 }
584
ReadSparseData(EntryImpl * entry,int64_t offset,net::IOBuffer * buf,int buf_len,net::CompletionOnceCallback callback)585 void InFlightBackendIO::ReadSparseData(EntryImpl* entry,
586 int64_t offset,
587 net::IOBuffer* buf,
588 int buf_len,
589 net::CompletionOnceCallback callback) {
590 auto operation =
591 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
592 operation->ReadSparseData(entry, offset, buf, buf_len);
593 PostOperation(FROM_HERE, operation.get());
594 }
595
WriteSparseData(EntryImpl * entry,int64_t offset,net::IOBuffer * buf,int buf_len,net::CompletionOnceCallback callback)596 void InFlightBackendIO::WriteSparseData(EntryImpl* entry,
597 int64_t offset,
598 net::IOBuffer* buf,
599 int buf_len,
600 net::CompletionOnceCallback callback) {
601 auto operation =
602 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
603 operation->WriteSparseData(entry, offset, buf, buf_len);
604 PostOperation(FROM_HERE, operation.get());
605 }
606
GetAvailableRange(EntryImpl * entry,int64_t offset,int len,RangeResultCallback callback)607 void InFlightBackendIO::GetAvailableRange(EntryImpl* entry,
608 int64_t offset,
609 int len,
610 RangeResultCallback callback) {
611 auto operation =
612 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
613 operation->GetAvailableRange(entry, offset, len);
614 PostOperation(FROM_HERE, operation.get());
615 }
616
CancelSparseIO(EntryImpl * entry)617 void InFlightBackendIO::CancelSparseIO(EntryImpl* entry) {
618 auto operation = base::MakeRefCounted<BackendIO>(
619 this, backend_, net::CompletionOnceCallback());
620 operation->CancelSparseIO(entry);
621 PostOperation(FROM_HERE, operation.get());
622 }
623
ReadyForSparseIO(EntryImpl * entry,net::CompletionOnceCallback callback)624 void InFlightBackendIO::ReadyForSparseIO(EntryImpl* entry,
625 net::CompletionOnceCallback callback) {
626 auto operation =
627 base::MakeRefCounted<BackendIO>(this, backend_, std::move(callback));
628 operation->ReadyForSparseIO(entry);
629 PostOperation(FROM_HERE, operation.get());
630 }
631
WaitForPendingIO()632 void InFlightBackendIO::WaitForPendingIO() {
633 InFlightIO::WaitForPendingIO();
634 }
635
OnOperationComplete(BackgroundIO * operation,bool cancel)636 void InFlightBackendIO::OnOperationComplete(BackgroundIO* operation,
637 bool cancel) {
638 BackendIO* op = static_cast<BackendIO*>(operation);
639 op->OnDone(cancel);
640
641 if (op->has_callback() && (!cancel || op->IsEntryOperation()))
642 op->RunCallback(op->result());
643
644 if (op->has_range_result_callback()) {
645 DCHECK(op->IsEntryOperation());
646 op->RunRangeResultCallback();
647 }
648
649 if (op->has_entry_result_callback() && !cancel) {
650 DCHECK(!op->IsEntryOperation());
651 op->RunEntryResultCallback();
652 }
653 }
654
PostOperation(const base::Location & from_here,BackendIO * operation)655 void InFlightBackendIO::PostOperation(const base::Location& from_here,
656 BackendIO* operation) {
657 background_thread_->PostTask(
658 from_here, base::BindOnce(&BackendIO::ExecuteOperation, operation));
659 OnOperationPosted(operation);
660 }
661
GetWeakPtr()662 base::WeakPtr<InFlightBackendIO> InFlightBackendIO::GetWeakPtr() {
663 return ptr_factory_.GetWeakPtr();
664 }
665
666 } // namespace disk_cache
667