1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The basis for all native run loops on the Mac is the CFRunLoop.  It can be
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// used directly, it can be used as the driving force behind the similar
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Foundation NSRunLoop, and it can be used to implement higher-level event
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// loops such as the NSApplication event loop.
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This file introduces a basic CFRunLoop-based implementation of the
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessagePump interface called CFRunLoopBase.  CFRunLoopBase contains all
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// of the machinery necessary to dispatch events to a delegate, but does not
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// implement the specific run loop.  Concrete subclasses must provide their
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// own DoRun and Quit implementations.
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A concrete subclass that just runs a CFRunLoop loop is provided in
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessagePumpCFRunLoop.  For an NSRunLoop, the similar MessagePumpNSRunLoop
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// is provided.
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// For the application's event loop, an implementation based on AppKit's
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// NSApplication event system is provided in MessagePumpNSApplication.
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Typically, MessagePumpNSApplication only makes sense on a Cocoa
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// application's main thread.  If a CFRunLoop-based message pump is needed on
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// any other thread, one of the other concrete subclasses is preferrable.
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessagePumpMac::Create is defined, which returns a new NSApplication-based
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// or NSRunLoop-based MessagePump subclass depending on which thread it is
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// called on.
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef BASE_MESSAGE_PUMP_MAC_H_
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define BASE_MESSAGE_PUMP_MAC_H_
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_pump.h"
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <CoreFoundation/CoreFoundation.h>
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#if !defined(__OBJC__)
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass NSAutoreleasePool;
4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#else  // !defined(__OBJC__)
4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#import <AppKit/AppKit.h>
4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Clients must subclass NSApplication and implement this protocol if they use
4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// MessagePumpMac.
4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen@protocol CrAppProtocol
4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Must return true if -[NSApplication sendEvent:] is currently on the stack.
4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// See the comment for |CreateAutoreleasePool()| in the cc file for why this is
4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// necessary.
4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen- (BOOL)isHandlingSendEvent;
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen@end
5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif  // !defined(__OBJC__)
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base {
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
55513209b27ff55e2841eac0e4120199c23acce758Ben Murdochclass TimeTicks;
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MessagePumpCFRunLoopBase : public MessagePump {
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Needs access to CreateAutoreleasePool.
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  friend class MessagePumpScopedAutoreleasePool;
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessagePumpCFRunLoopBase();
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual ~MessagePumpCFRunLoopBase();
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Subclasses should implement the work they need to do in MessagePump::Run
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // in the DoRun method.  MessagePumpCFRunLoopBase::Run calls DoRun directly.
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This arrangement is used because MessagePumpCFRunLoopBase needs to set
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // up and tear down things before and after the "meat" of DoRun.
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Run(Delegate* delegate);
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void DoRun(Delegate* delegate) = 0;
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void ScheduleWork();
72513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time);
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected:
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Accessors for private data members to be used by subclasses.
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CFRunLoopRef run_loop() const { return run_loop_; }
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int nesting_level() const { return nesting_level_; }
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int run_nesting_level() const { return run_nesting_level_; }
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Return an autorelease pool to wrap around any work being performed.
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // In some cases, CreateAutoreleasePool may return nil intentionally to
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // preventing an autorelease pool from being created, allowing any
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // objects autoreleased by work to fall into the current autorelease pool.
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual NSAutoreleasePool* CreateAutoreleasePool();
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Timer callback scheduled by ScheduleDelayedWork.  This does not do any
88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // work, but it signals work_source_ so that delayed work can be performed
89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // within the appropriate priority constraints.
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void RunDelayedWorkTimer(CFRunLoopTimerRef timer, void* info);
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Perform highest-priority work.  This is associated with work_source_
93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // signalled by ScheduleWork or RunDelayedWorkTimer.  The static method calls
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // the instance method; the instance method returns true if it resignalled
95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // work_source_ to be called again from the loop.
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void RunWorkSource(void* info);
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool RunWork();
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Perform idle-priority work.  This is normally called by PreWaitObserver,
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // but is also associated with idle_work_source_.  When this function
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // actually does perform idle work, it will resignal that source.  The
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // static method calls the instance method; the instance method returns
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // true if idle work was done.
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void RunIdleWorkSource(void* info);
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool RunIdleWork();
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Perform work that may have been deferred because it was not runnable
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // within a nested run loop.  This is associated with
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // nesting_deferred_work_source_ and is signalled by
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // MaybeScheduleNestingDeferredWork when returning from a nested loop,
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // so that an outer loop will be able to perform the necessary tasks if it
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // permits nestable tasks.
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void RunNestingDeferredWorkSource(void* info);
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool RunNestingDeferredWork();
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Schedules possible nesting-deferred work to be processed before the run
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // loop goes to sleep, exits, or begins processing sources at the top of its
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // loop.  If this function detects that a nested loop had run since the
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // previous attempt to schedule nesting-deferred work, it will schedule a
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // call to RunNestingDeferredWorkSource.
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void MaybeScheduleNestingDeferredWork();
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Observer callback responsible for performing idle-priority work, before
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the run loop goes to sleep.  Associated with idle_work_observer_.
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void PreWaitObserver(CFRunLoopObserverRef observer,
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                              CFRunLoopActivity activity, void* info);
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Observer callback called before the run loop processes any sources.
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Associated with pre_source_observer_.
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void PreSourceObserver(CFRunLoopObserverRef observer,
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                CFRunLoopActivity activity, void* info);
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Observer callback called when the run loop starts and stops, at the
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // beginning and end of calls to CFRunLoopRun.  This is used to maintain
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // nesting_level_.  Associated with enter_exit_observer_.
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void EnterExitObserver(CFRunLoopObserverRef observer,
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                CFRunLoopActivity activity, void* info);
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Called by EnterExitObserver after performing maintenance on nesting_level_.
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This allows subclasses an opportunity to perform additional processing on
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the basis of run loops starting and stopping.
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void EnterExitRunLoop(CFRunLoopActivity activity);
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The thread's run loop.
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CFRunLoopRef run_loop_;
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The timer, sources, and observers are described above alongside their
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // callbacks.
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CFRunLoopTimerRef delayed_work_timer_;
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CFRunLoopSourceRef work_source_;
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CFRunLoopSourceRef idle_work_source_;
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CFRunLoopSourceRef nesting_deferred_work_source_;
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CFRunLoopObserverRef pre_wait_observer_;
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CFRunLoopObserverRef pre_source_observer_;
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CFRunLoopObserverRef enter_exit_observer_;
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // (weak) Delegate passed as an argument to the innermost Run call.
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Delegate* delegate_;
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The time that delayed_work_timer_ is scheduled to fire.  This is tracked
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // independently of CFRunLoopTimerGetNextFireDate(delayed_work_timer_)
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // to be able to reset the timer properly after waking from system sleep.
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // See PowerStateNotification.
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CFAbsoluteTime delayed_work_fire_time_;
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The recursion depth of the currently-executing CFRunLoopRun loop on the
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // run loop's thread.  0 if no run loops are running inside of whatever scope
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the object was created in.
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int nesting_level_;
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The recursion depth (calculated in the same way as nesting_level_) of the
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // innermost executing CFRunLoopRun loop started by a call to Run.
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int run_nesting_level_;
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The deepest (numerically highest) recursion depth encountered since the
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // most recent attempt to run nesting-deferred work.
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int deepest_nesting_level_;
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // "Delegateless" work flags are set when work is ready to be performed but
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // must wait until a delegate is available to process it.  This can happen
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // when a MessagePumpCFRunLoopBase is instantiated and work arrives without
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // any call to Run on the stack.  The Run method will check for delegateless
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // work on entry and redispatch it as needed once a delegate is available.
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool delegateless_work_;
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool delegateless_idle_work_;
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(MessagePumpCFRunLoopBase);
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MessagePumpCFRunLoop : public MessagePumpCFRunLoopBase {
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessagePumpCFRunLoop();
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void DoRun(Delegate* delegate);
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Quit();
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void EnterExitRunLoop(CFRunLoopActivity activity);
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // True if Quit is called to stop the innermost MessagePump
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // (innermost_quittable_) but some other CFRunLoopRun loop (nesting_level_)
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is running inside the MessagePump's innermost Run call.
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool quit_pending_;
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(MessagePumpCFRunLoop);
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MessagePumpNSRunLoop : public MessagePumpCFRunLoopBase {
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessagePumpNSRunLoop();
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual ~MessagePumpNSRunLoop();
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void DoRun(Delegate* delegate);
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Quit();
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A source that doesn't do anything but provide something signalable
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // attached to the run loop.  This source will be signalled when Quit
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is called, to cause the loop to wake up so that it can stop.
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CFRunLoopSourceRef quit_source_;
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // False after Quit is called.
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool keep_running_;
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(MessagePumpNSRunLoop);
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MessagePumpNSApplication : public MessagePumpCFRunLoopBase {
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessagePumpNSApplication();
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void DoRun(Delegate* delegate);
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Quit();
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected:
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns nil if NSApp is currently in the middle of calling -sendEvent.
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual NSAutoreleasePool* CreateAutoreleasePool();
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // False after Quit is called.
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool keep_running_;
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // True if DoRun is managing its own run loop as opposed to letting
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // -[NSApplication run] handle it.  The outermost run loop in the application
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is managed by -[NSApplication run], inner run loops are handled by a loop
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // in DoRun.
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool running_own_loop_;
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(MessagePumpNSApplication);
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MessagePumpMac {
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns a new instance of MessagePumpNSApplication if called on the main
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // thread.  Otherwise, returns a new instance of MessagePumpNSRunLoop.
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static MessagePump* Create();
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_IMPLICIT_CONSTRUCTORS(MessagePumpMac);
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace base
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // BASE_MESSAGE_PUMP_MAC_H_
265