• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_
6 #define MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_
7 
8 #include <map>
9 
10 #include "mojo/public/cpp/system/core.h"
11 
12 namespace mojo {
13 
14 class RunLoopHandler;
15 
16 class RunLoop {
17  public:
18   RunLoop();
19   ~RunLoop();
20 
21   // Sets up state needed for RunLoop. This must be invoked before creating a
22   // RunLoop.
23   static void SetUp();
24 
25   // Cleans state created by Setup().
26   static void TearDown();
27 
28   // Returns the RunLoop for the current thread. Returns NULL if not yet
29   // created.
30   static RunLoop* current();
31 
32   // Registers a RunLoopHandler for the specified handle. Only one handler can
33   // be registered for a specified handle.
34   void AddHandler(RunLoopHandler* handler,
35                   const Handle& handle,
36                   MojoHandleSignals handle_signals,
37                   MojoDeadline deadline);
38   void RemoveHandler(const Handle& handle);
39   bool HasHandler(const Handle& handle) const;
40 
41   // Runs the loop servicing handles as they are ready. This returns when Quit()
42   // is invoked, or there no more handles.
43   void Run();
44 
45   // Runs the loop servicing any handles that are ready. Does not wait for
46   // handles to become ready before returning. Returns early if Quit() is
47   // invoked.
48   void RunUntilIdle();
49 
50   void Quit();
51 
52  private:
53   struct RunState;
54   struct WaitState;
55 
56   // Contains the data needed to track a request to AddHandler().
57   struct HandlerData {
HandlerDataHandlerData58     HandlerData()
59         : handler(NULL),
60           handle_signals(MOJO_HANDLE_SIGNAL_NONE),
61           deadline(0),
62           id(0) {}
63 
64     RunLoopHandler* handler;
65     MojoHandleSignals handle_signals;
66     MojoTimeTicks deadline;
67     // See description of |RunLoop::next_handler_id_| for details.
68     int id;
69   };
70 
71   typedef std::map<Handle, HandlerData> HandleToHandlerData;
72 
73   // Waits for a handle to be ready. Returns after servicing at least one
74   // handle (or there are no more handles) unless |non_blocking| is true,
75   // in which case it will also return if servicing at least one handle
76   // would require blocking. Returns true if a RunLoopHandler was notified.
77   bool Wait(bool non_blocking);
78 
79   // Notifies any handlers whose deadline has expired. Returns true if a
80   // RunLoopHandler was notified.
81   bool NotifyDeadlineExceeded();
82 
83   // Removes the first invalid handle. This is called if MojoWaitMany() finds an
84   // invalid handle. Returns true if a RunLoopHandler was notified.
85   bool RemoveFirstInvalidHandle(const WaitState& wait_state);
86 
87   // Returns the state needed to pass to WaitMany().
88   WaitState GetWaitState(bool non_blocking) const;
89 
90   HandleToHandlerData handler_data_;
91 
92   // If non-NULL we're running (inside Run()). Member references a value on the
93   // stack.
94   RunState* run_state_;
95 
96   // An ever increasing value assigned to each HandlerData::id. Used to detect
97   // uniqueness while notifying. That is, while notifying expired timers we copy
98   // |handler_data_| and only notify handlers whose id match. If the id does not
99   // match it means the handler was removed then added so that we shouldn't
100   // notify it.
101   int next_handler_id_;
102 
103   MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoop);
104 };
105 
106 }  // namespace mojo
107 
108 #endif  // MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_
109