• 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 #ifndef NET_DISK_CACHE_IN_FLIGHT_IO_H_
6 #define NET_DISK_CACHE_IN_FLIGHT_IO_H_
7 #pragma once
8 
9 #include <set>
10 
11 #include "base/message_loop_proxy.h"
12 #include "base/synchronization/waitable_event.h"
13 
14 namespace disk_cache {
15 
16 class InFlightIO;
17 
18 // This class represents a single asynchronous IO operation while it is being
19 // bounced between threads.
20 class BackgroundIO : public base::RefCountedThreadSafe<BackgroundIO> {
21  public:
22   // Other than the actual parameters for the IO operation (including the
23   // |callback| that must be notified at the end), we need the controller that
24   // is keeping track of all operations. When done, we notify the controller
25   // (we do NOT invoke the callback), in the worker thead that completed the
26   // operation.
27   explicit BackgroundIO(InFlightIO* controller);
28 
29   // This method signals the controller that this operation is finished, in the
30   // original thread. In practice, this is a RunableMethod that allows
31   // cancellation.
32   void OnIOSignalled();
33 
34   // Allows the cancellation of the task to notify the controller (step number 8
35   // in the diagram below). In practice, if the controller waits for the
36   // operation to finish it doesn't have to wait for the final task to be
37   // processed by the message loop so calling this method prevents its delivery.
38   // Note that this method is not intended to cancel the actual IO operation or
39   // to prevent the first notification to take place (OnIOComplete).
40   void Cancel();
41 
result()42   int result() { return result_; }
43 
io_completed()44   base::WaitableEvent* io_completed() {
45     return &io_completed_;
46   }
47 
48  protected:
49   virtual ~BackgroundIO();
50 
51   InFlightIO* controller_;  // The controller that tracks all operations.
52   int result_;  // Final operation result.
53 
54  private:
55   friend class base::RefCountedThreadSafe<BackgroundIO>;
56 
57   // Notifies the controller about the end of the operation, from the background
58   // thread.
59   void NotifyController();
60 
61   // An event to signal when the operation completes.
62   base::WaitableEvent io_completed_;
63 
64   DISALLOW_COPY_AND_ASSIGN(BackgroundIO);
65 };
66 
67 // This class keeps track of asynchronous IO operations. A single instance
68 // of this class is meant to be used to start an asynchronous operation (using
69 // PostXX, exposed by a derived class). This class will post the operation to a
70 // worker thread, hanlde the notification when the operation finishes and
71 // perform the callback on the same thread that was used to start the operation.
72 //
73 // The regular sequence of calls is:
74 //                 Thread_1                          Worker_thread
75 //    1.     DerivedInFlightIO::PostXX()
76 //    2.                         -> PostTask ->
77 //    3.    InFlightIO::OnOperationPosted()
78 //    4.                                        DerivedBackgroundIO::XX()
79 //    5.                                         IO operation completes
80 //    6.                                       InFlightIO::OnIOComplete()
81 //    7.                         <- PostTask <-
82 //    8.  BackgroundIO::OnIOSignalled()
83 //    9.  InFlightIO::InvokeCallback()
84 //   10. DerivedInFlightIO::OnOperationComplete()
85 //   11.       invoke callback
86 //
87 // Shutdown is a special case that is handled though WaitForPendingIO() instead
88 // of just waiting for step 7.
89 class InFlightIO {
90  public:
91   InFlightIO();
92   virtual ~InFlightIO();
93 
94   // Blocks the current thread until all IO operations tracked by this object
95   // complete.
96   void WaitForPendingIO();
97 
98   // Called on a background thread when |operation| completes.
99   void OnIOComplete(BackgroundIO* operation);
100 
101   // Invokes the users' completion callback at the end of the IO operation.
102   // |cancel_task| is true if the actual task posted to the thread is still
103   // queued (because we are inside WaitForPendingIO), and false if said task is
104   // the one performing the call.
105   void InvokeCallback(BackgroundIO* operation, bool cancel_task);
106 
107  protected:
108   // This method is called to signal the completion of the |operation|. |cancel|
109   // is true if the operation is being cancelled. This method is called on the
110   // thread that created this object.
111   virtual void OnOperationComplete(BackgroundIO* operation, bool cancel) = 0;
112 
113   // Signals this object that the derived class just posted the |operation| to
114   // be executed on a background thread. This method must be called on the same
115   // thread used to create this object.
116   void OnOperationPosted(BackgroundIO* operation);
117 
118  private:
119   typedef std::set<scoped_refptr<BackgroundIO> > IOList;
120 
121   IOList io_list_;  // List of pending, in-flight io operations.
122   scoped_refptr<base::MessageLoopProxy> callback_thread_;
123 
124   bool running_;  // True after the first posted operation completes.
125   bool single_thread_;  // True if we only have one thread.
126 
127   DISALLOW_COPY_AND_ASSIGN(InFlightIO);
128 };
129 
130 }  // namespace disk_cache
131 
132 #endif  // NET_DISK_CACHE_IN_FLIGHT_IO_H_
133