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 { 52 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