run_loop.h revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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 12namespace mojo { 13 14class RunLoopHandler; 15 16class 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 { 58 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