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