Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / mojo / public / cpp / utility / run_loop.h
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 #include <queue>
10
11 #include "mojo/public/cpp/bindings/callback.h"
12 #include "mojo/public/cpp/system/core.h"
13
14 namespace mojo {
15
16 class RunLoopHandler;
17
18 class RunLoop {
19  public:
20   RunLoop();
21   ~RunLoop();
22
23   // Sets up state needed for RunLoop. This must be invoked before creating a
24   // RunLoop.
25   static void SetUp();
26
27   // Cleans state created by Setup().
28   static void TearDown();
29
30   // Returns the RunLoop for the current thread. Returns NULL if not yet
31   // created.
32   static RunLoop* current();
33
34   // Registers a RunLoopHandler for the specified handle. Only one handler can
35   // be registered for a specified handle.
36   void AddHandler(RunLoopHandler* handler,
37                   const Handle& handle,
38                   MojoHandleSignals handle_signals,
39                   MojoDeadline deadline);
40   void RemoveHandler(const Handle& handle);
41   bool HasHandler(const Handle& handle) const;
42
43   // Runs the loop servicing handles and tasks as they are ready. This returns
44   // when Quit() is invoked, or there are no more handles nor tasks.
45   void Run();
46
47   // Runs the loop servicing any handles and tasks that are ready. Does not wait
48   // for handles or tasks to become ready before returning. Returns early if
49   // Quit() is invoked.
50   void RunUntilIdle();
51
52   void Quit();
53
54   // Adds a task to be performed after delay has elapsed. Must be posted to the
55   // current thread's RunLoop.
56   void PostDelayedTask(const Closure& task, MojoTimeTicks delay);
57
58  private:
59   struct RunState;
60   struct WaitState;
61
62   // Contains the data needed to track a request to AddHandler().
63   struct HandlerData {
64     HandlerData()
65         : handler(NULL),
66           handle_signals(MOJO_HANDLE_SIGNAL_NONE),
67           deadline(0),
68           id(0) {}
69
70     RunLoopHandler* handler;
71     MojoHandleSignals handle_signals;
72     MojoTimeTicks deadline;
73     // See description of |RunLoop::next_handler_id_| for details.
74     int id;
75   };
76
77   typedef std::map<Handle, HandlerData> HandleToHandlerData;
78
79   // Used for NotifyHandlers to specify whether HandlerData's |deadline|
80   // should be checked prior to notifying.
81   enum CheckDeadline {
82     CHECK_DEADLINE,
83     IGNORE_DEADLINE
84   };
85
86   // Mode of operation of the run loop.
87   enum RunMode {
88     UNTIL_EMPTY,
89     UNTIL_IDLE
90   };
91
92   // Runs the loop servicing any handles and tasks that are ready. If
93   // |run_mode| is |UNTIL_IDLE|, does not wait for handles or tasks to become
94   // ready before returning. Returns early if Quit() is invoked.
95   void RunInternal(RunMode run_mode);
96
97   // Do one unit of delayed work, if eligible. Returns true is a task was run.
98   bool DoDelayedWork();
99
100   // Waits for a handle to be ready or until the next task must be run. Returns
101   // after servicing at least one handle (or there are no more handles) unless
102   // a task must be run or |non_blocking| is true, in which case it will also
103   // return if no task is registered and servicing at least one handle would
104   // require blocking. Returns true if a RunLoopHandler was notified.
105   bool Wait(bool non_blocking);
106
107   // Notifies handlers of |error|.  If |check| == CHECK_DEADLINE, this will
108   // only notify handlers whose deadline has expired and skips the rest.
109   // Returns true if a RunLoopHandler was notified.
110   bool NotifyHandlers(MojoResult error, CheckDeadline check);
111
112   // Removes the first invalid handle. This is called if MojoWaitMany() finds an
113   // invalid handle. Returns true if a RunLoopHandler was notified.
114   bool RemoveFirstInvalidHandle(const WaitState& wait_state);
115
116   // Returns the state needed to pass to WaitMany().
117   WaitState GetWaitState(bool non_blocking) const;
118
119   HandleToHandlerData handler_data_;
120
121   // If non-NULL we're running (inside Run()). Member references a value on the
122   // stack.
123   RunState* run_state_;
124
125   // An ever increasing value assigned to each HandlerData::id. Used to detect
126   // uniqueness while notifying. That is, while notifying expired timers we copy
127   // |handler_data_| and only notify handlers whose id match. If the id does not
128   // match it means the handler was removed then added so that we shouldn't
129   // notify it.
130   int next_handler_id_;
131
132   struct PendingTask {
133     PendingTask(const Closure& task,
134                 MojoTimeTicks runtime,
135                 uint64_t sequence_number);
136     ~PendingTask();
137
138     bool operator<(const PendingTask& other) const;
139
140     Closure task;
141     MojoTimeTicks run_time;
142     uint64_t sequence_number;
143   };
144   // An ever increasing sequence number attached to each pending task in order
145   // to preserve relative order of tasks posted at the 'same' time.
146   uint64_t next_sequence_number_;
147   typedef std::priority_queue<PendingTask> DelayedTaskQueue;
148   DelayedTaskQueue delayed_tasks_;
149
150   MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoop);
151 };
152
153 }  // namespace mojo
154
155 #endif  // MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_