• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_IO_H_
6 #define NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_IO_H_
7 
8 #include <set>
9 
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/synchronization/lock.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   // Notifies the controller about the end of the operation, from the background
52   // thread.
53   void NotifyController();
54 
55   int result_;  // Final operation result.
56 
57  private:
58   friend class base::RefCountedThreadSafe<BackgroundIO>;
59 
60   // An event to signal when the operation completes.
61   base::WaitableEvent io_completed_;
62   InFlightIO* controller_;  // The controller that tracks all operations.
63   base::Lock controller_lock_;  // A lock protecting clearing of controller_.
64 
65   DISALLOW_COPY_AND_ASSIGN(BackgroundIO);
66 };
67 
68 // This class keeps track of asynchronous IO operations. A single instance
69 // of this class is meant to be used to start an asynchronous operation (using
70 // PostXX, exposed by a derived class). This class will post the operation to a
71 // worker thread, hanlde the notification when the operation finishes and
72 // perform the callback on the same thread that was used to start the operation.
73 //
74 // The regular sequence of calls is:
75 //                 Thread_1                          Worker_thread
76 //    1.     DerivedInFlightIO::PostXX()
77 //    2.                         -> PostTask ->
78 //    3.    InFlightIO::OnOperationPosted()
79 //    4.                                        DerivedBackgroundIO::XX()
80 //    5.                                         IO operation completes
81 //    6.                                       InFlightIO::OnIOComplete()
82 //    7.                         <- PostTask <-
83 //    8.  BackgroundIO::OnIOSignalled()
84 //    9.  InFlightIO::InvokeCallback()
85 //   10. DerivedInFlightIO::OnOperationComplete()
86 //   11.       invoke callback
87 //
88 // Shutdown is a special case that is handled though WaitForPendingIO() instead
89 // of just waiting for step 7.
90 class InFlightIO {
91  public:
92   InFlightIO();
93   virtual ~InFlightIO();
94 
95   // Blocks the current thread until all IO operations tracked by this object
96   // complete.
97   void WaitForPendingIO();
98 
99   // Drops current pending operations without waiting for them to complete.
100   void DropPendingIO();
101 
102   // Called on a background thread when |operation| completes.
103   void OnIOComplete(BackgroundIO* operation);
104 
105   // Invokes the users' completion callback at the end of the IO operation.
106   // |cancel_task| is true if the actual task posted to the thread is still
107   // queued (because we are inside WaitForPendingIO), and false if said task is
108   // the one performing the call.
109   void InvokeCallback(BackgroundIO* operation, bool cancel_task);
110 
111  protected:
112   // This method is called to signal the completion of the |operation|. |cancel|
113   // is true if the operation is being cancelled. This method is called on the
114   // thread that created this object.
115   virtual void OnOperationComplete(BackgroundIO* operation, bool cancel) = 0;
116 
117   // Signals this object that the derived class just posted the |operation| to
118   // be executed on a background thread. This method must be called on the same
119   // thread used to create this object.
120   void OnOperationPosted(BackgroundIO* operation);
121 
122  private:
123   typedef std::set<scoped_refptr<BackgroundIO> > IOList;
124 
125   IOList io_list_;  // List of pending, in-flight io operations.
126   scoped_refptr<base::MessageLoopProxy> callback_thread_;
127 
128   bool running_;  // True after the first posted operation completes.
129   bool single_thread_;  // True if we only have one thread.
130 
131   DISALLOW_COPY_AND_ASSIGN(InFlightIO);
132 };
133 
134 }  // namespace disk_cache
135 
136 #endif  // NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_IO_H_
137