• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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