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_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