Home | History | Annotate | Download | only in utility
      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 {
     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