• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2006-2010 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_io.h"
6 
7 #include "base/logging.h"
8 
9 namespace disk_cache {
10 
BackgroundIO(InFlightIO * controller)11 BackgroundIO::BackgroundIO(InFlightIO* controller)
12     : controller_(controller), result_(-1), io_completed_(true, false) {
13 }
14 
15 // Runs on the primary thread.
OnIOSignalled()16 void BackgroundIO::OnIOSignalled() {
17   if (controller_)
18     controller_->InvokeCallback(this, false);
19 }
20 
Cancel()21 void BackgroundIO::Cancel() {
22   DCHECK(controller_);
23   controller_ = NULL;
24 }
25 
~BackgroundIO()26 BackgroundIO::~BackgroundIO() {}
27 
28 // Runs on the background thread.
NotifyController()29 void BackgroundIO::NotifyController() {
30   controller_->OnIOComplete(this);
31 }
32 
33 // ---------------------------------------------------------------------------
34 
InFlightIO()35 InFlightIO::InFlightIO()
36     : callback_thread_(base::MessageLoopProxy::CreateForCurrentThread()),
37       running_(false), single_thread_(false) {
38 }
39 
~InFlightIO()40 InFlightIO::~InFlightIO() {
41 }
42 
WaitForPendingIO()43 void InFlightIO::WaitForPendingIO() {
44   while (!io_list_.empty()) {
45     // Block the current thread until all pending IO completes.
46     IOList::iterator it = io_list_.begin();
47     InvokeCallback(*it, true);
48   }
49 }
50 
51 // Runs on a background thread.
OnIOComplete(BackgroundIO * operation)52 void InFlightIO::OnIOComplete(BackgroundIO* operation) {
53 #ifndef NDEBUG
54   if (callback_thread_->BelongsToCurrentThread()) {
55     DCHECK(single_thread_ || !running_);
56     single_thread_ = true;
57   }
58   running_ = true;
59 #endif
60 
61   callback_thread_->PostTask(FROM_HERE,
62                              NewRunnableMethod(operation,
63                                                &BackgroundIO::OnIOSignalled));
64   operation->io_completed()->Signal();
65 }
66 
67 // Runs on the primary thread.
InvokeCallback(BackgroundIO * operation,bool cancel_task)68 void InFlightIO::InvokeCallback(BackgroundIO* operation, bool cancel_task) {
69   operation->io_completed()->Wait();
70 
71   if (cancel_task)
72     operation->Cancel();
73 
74   // Make sure that we remove the operation from the list before invoking the
75   // callback (so that a subsequent cancel does not invoke the callback again).
76   DCHECK(io_list_.find(operation) != io_list_.end());
77   io_list_.erase(make_scoped_refptr(operation));
78   OnOperationComplete(operation, cancel_task);
79 }
80 
81 // Runs on the primary thread.
OnOperationPosted(BackgroundIO * operation)82 void InFlightIO::OnOperationPosted(BackgroundIO* operation) {
83   DCHECK(callback_thread_->BelongsToCurrentThread());
84   io_list_.insert(make_scoped_refptr(operation));
85 }
86 
87 }  // namespace disk_cache
88