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