~suaweb/nginx/nginx-recipe

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/third_party/chromium/src/base/message_loop/message_pump_mac.h

  • Committer: Frans Elliott
  • Date: 2015-06-12 21:15:13 UTC
  • Revision ID: mastergeek.elliott@gmail.com-20150612211513-un4vguj32deibvb0
Added the actual pagespeed library to the ngx_pagespeed module dir.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2012 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
// The basis for all native run loops on the Mac is the CFRunLoop.  It can be
 
6
// used directly, it can be used as the driving force behind the similar
 
7
// Foundation NSRunLoop, and it can be used to implement higher-level event
 
8
// loops such as the NSApplication event loop.
 
9
//
 
10
// This file introduces a basic CFRunLoop-based implementation of the
 
11
// MessagePump interface called CFRunLoopBase.  CFRunLoopBase contains all
 
12
// of the machinery necessary to dispatch events to a delegate, but does not
 
13
// implement the specific run loop.  Concrete subclasses must provide their
 
14
// own DoRun and Quit implementations.
 
15
//
 
16
// A concrete subclass that just runs a CFRunLoop loop is provided in
 
17
// MessagePumpCFRunLoop.  For an NSRunLoop, the similar MessagePumpNSRunLoop
 
18
// is provided.
 
19
//
 
20
// For the application's event loop, an implementation based on AppKit's
 
21
// NSApplication event system is provided in MessagePumpNSApplication.
 
22
//
 
23
// Typically, MessagePumpNSApplication only makes sense on a Cocoa
 
24
// application's main thread.  If a CFRunLoop-based message pump is needed on
 
25
// any other thread, one of the other concrete subclasses is preferrable.
 
26
// MessagePumpMac::Create is defined, which returns a new NSApplication-based
 
27
// or NSRunLoop-based MessagePump subclass depending on which thread it is
 
28
// called on.
 
29
 
 
30
#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_MAC_H_
 
31
#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_MAC_H_
 
32
 
 
33
#include "base/message_loop/message_pump.h"
 
34
 
 
35
#include "base/basictypes.h"
 
36
 
 
37
#include <CoreFoundation/CoreFoundation.h>
 
38
 
 
39
#include "base/memory/weak_ptr.h"
 
40
 
 
41
#if !defined(__OBJC__)
 
42
class NSAutoreleasePool;
 
43
#else  // !defined(__OBJC__)
 
44
#if defined(OS_IOS)
 
45
#import <Foundation/Foundation.h>
 
46
#else
 
47
#import <AppKit/AppKit.h>
 
48
 
 
49
// Clients must subclass NSApplication and implement this protocol if they use
 
50
// MessagePumpMac.
 
51
@protocol CrAppProtocol
 
52
// Must return true if -[NSApplication sendEvent:] is currently on the stack.
 
53
// See the comment for |CreateAutoreleasePool()| in the cc file for why this is
 
54
// necessary.
 
55
- (BOOL)isHandlingSendEvent;
 
56
@end
 
57
#endif  // !defined(OS_IOS)
 
58
#endif  // !defined(__OBJC__)
 
59
 
 
60
namespace base {
 
61
 
 
62
class MessagePumpInstrumentation;
 
63
class RunLoop;
 
64
class TimeTicks;
 
65
 
 
66
class MessagePumpCFRunLoopBase : public MessagePump {
 
67
  // Needs access to CreateAutoreleasePool.
 
68
  friend class MessagePumpScopedAutoreleasePool;
 
69
 public:
 
70
  MessagePumpCFRunLoopBase();
 
71
  virtual ~MessagePumpCFRunLoopBase();
 
72
 
 
73
  // Subclasses should implement the work they need to do in MessagePump::Run
 
74
  // in the DoRun method.  MessagePumpCFRunLoopBase::Run calls DoRun directly.
 
75
  // This arrangement is used because MessagePumpCFRunLoopBase needs to set
 
76
  // up and tear down things before and after the "meat" of DoRun.
 
77
  virtual void Run(Delegate* delegate) OVERRIDE;
 
78
  virtual void DoRun(Delegate* delegate) = 0;
 
79
 
 
80
  virtual void ScheduleWork() OVERRIDE;
 
81
  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
 
82
 
 
83
 protected:
 
84
  // Accessors for private data members to be used by subclasses.
 
85
  CFRunLoopRef run_loop() const { return run_loop_; }
 
86
  int nesting_level() const { return nesting_level_; }
 
87
  int run_nesting_level() const { return run_nesting_level_; }
 
88
 
 
89
  // Sets this pump's delegate.  Signals the appropriate sources if
 
90
  // |delegateless_work_| is true.  |delegate| can be NULL.
 
91
  void SetDelegate(Delegate* delegate);
 
92
 
 
93
  // Return an autorelease pool to wrap around any work being performed.
 
94
  // In some cases, CreateAutoreleasePool may return nil intentionally to
 
95
  // preventing an autorelease pool from being created, allowing any
 
96
  // objects autoreleased by work to fall into the current autorelease pool.
 
97
  virtual NSAutoreleasePool* CreateAutoreleasePool();
 
98
 
 
99
  // Enables instrumentation of the MessagePump. See MessagePumpInstrumentation
 
100
  // in the implementation for details.
 
101
  void EnableInstrumentation();
 
102
  WeakPtr<MessagePumpInstrumentation> instrumentation_;
 
103
 
 
104
 private:
 
105
  // Timer callback scheduled by ScheduleDelayedWork.  This does not do any
 
106
  // work, but it signals work_source_ so that delayed work can be performed
 
107
  // within the appropriate priority constraints.
 
108
  static void RunDelayedWorkTimer(CFRunLoopTimerRef timer, void* info);
 
109
 
 
110
  // Perform highest-priority work.  This is associated with work_source_
 
111
  // signalled by ScheduleWork or RunDelayedWorkTimer.  The static method calls
 
112
  // the instance method; the instance method returns true if it resignalled
 
113
  // work_source_ to be called again from the loop.
 
114
  static void RunWorkSource(void* info);
 
115
  bool RunWork();
 
116
 
 
117
  // Perform idle-priority work.  This is normally called by
 
118
  // StartOrEndWaitObserver, but is also associated with idle_work_source_. When
 
119
  // this function actually does perform idle work, it will resignal that
 
120
  // source.  The static method calls the instance method; the instance method
 
121
  // returns true if idle work was done.
 
122
  static void RunIdleWorkSource(void* info);
 
123
  bool RunIdleWork();
 
124
 
 
125
  // Perform work that may have been deferred because it was not runnable
 
126
  // within a nested run loop.  This is associated with
 
127
  // nesting_deferred_work_source_ and is signalled by
 
128
  // MaybeScheduleNestingDeferredWork when returning from a nested loop,
 
129
  // so that an outer loop will be able to perform the necessary tasks if it
 
130
  // permits nestable tasks.
 
131
  static void RunNestingDeferredWorkSource(void* info);
 
132
  bool RunNestingDeferredWork();
 
133
 
 
134
  // Schedules possible nesting-deferred work to be processed before the run
 
135
  // loop goes to sleep, exits, or begins processing sources at the top of its
 
136
  // loop.  If this function detects that a nested loop had run since the
 
137
  // previous attempt to schedule nesting-deferred work, it will schedule a
 
138
  // call to RunNestingDeferredWorkSource.
 
139
  void MaybeScheduleNestingDeferredWork();
 
140
 
 
141
  // Observer callback responsible for performing idle-priority work, before
 
142
  // the run loop goes to sleep.  Associated with idle_work_observer_.
 
143
  static void StartOrEndWaitObserver(CFRunLoopObserverRef observer,
 
144
                                     CFRunLoopActivity activity, void* info);
 
145
 
 
146
  // Observer callback called before the run loop processes any sources.
 
147
  // Associated with pre_source_observer_.
 
148
  static void PreSourceObserver(CFRunLoopObserverRef observer,
 
149
                                CFRunLoopActivity activity, void* info);
 
150
 
 
151
  // Observer callback called when the run loop starts and stops, at the
 
152
  // beginning and end of calls to CFRunLoopRun.  This is used to maintain
 
153
  // nesting_level_.  Associated with enter_exit_observer_.
 
154
  static void EnterExitObserver(CFRunLoopObserverRef observer,
 
155
                                CFRunLoopActivity activity, void* info);
 
156
 
 
157
  // Called by EnterExitObserver after performing maintenance on nesting_level_.
 
158
  // This allows subclasses an opportunity to perform additional processing on
 
159
  // the basis of run loops starting and stopping.
 
160
  virtual void EnterExitRunLoop(CFRunLoopActivity activity);
 
161
 
 
162
  // The thread's run loop.
 
163
  CFRunLoopRef run_loop_;
 
164
 
 
165
  // The timer, sources, and observers are described above alongside their
 
166
  // callbacks.
 
167
  CFRunLoopTimerRef delayed_work_timer_;
 
168
  CFRunLoopSourceRef work_source_;
 
169
  CFRunLoopSourceRef idle_work_source_;
 
170
  CFRunLoopSourceRef nesting_deferred_work_source_;
 
171
  CFRunLoopObserverRef pre_wait_observer_;
 
172
  CFRunLoopObserverRef pre_source_observer_;
 
173
  CFRunLoopObserverRef enter_exit_observer_;
 
174
 
 
175
  // (weak) Delegate passed as an argument to the innermost Run call.
 
176
  Delegate* delegate_;
 
177
 
 
178
  // The time that delayed_work_timer_ is scheduled to fire.  This is tracked
 
179
  // independently of CFRunLoopTimerGetNextFireDate(delayed_work_timer_)
 
180
  // to be able to reset the timer properly after waking from system sleep.
 
181
  // See PowerStateNotification.
 
182
  CFAbsoluteTime delayed_work_fire_time_;
 
183
 
 
184
  // The recursion depth of the currently-executing CFRunLoopRun loop on the
 
185
  // run loop's thread.  0 if no run loops are running inside of whatever scope
 
186
  // the object was created in.
 
187
  int nesting_level_;
 
188
 
 
189
  // The recursion depth (calculated in the same way as nesting_level_) of the
 
190
  // innermost executing CFRunLoopRun loop started by a call to Run.
 
191
  int run_nesting_level_;
 
192
 
 
193
  // The deepest (numerically highest) recursion depth encountered since the
 
194
  // most recent attempt to run nesting-deferred work.
 
195
  int deepest_nesting_level_;
 
196
 
 
197
  // "Delegateless" work flags are set when work is ready to be performed but
 
198
  // must wait until a delegate is available to process it.  This can happen
 
199
  // when a MessagePumpCFRunLoopBase is instantiated and work arrives without
 
200
  // any call to Run on the stack.  The Run method will check for delegateless
 
201
  // work on entry and redispatch it as needed once a delegate is available.
 
202
  bool delegateless_work_;
 
203
  bool delegateless_idle_work_;
 
204
 
 
205
  DISALLOW_COPY_AND_ASSIGN(MessagePumpCFRunLoopBase);
 
206
};
 
207
 
 
208
class MessagePumpCFRunLoop : public MessagePumpCFRunLoopBase {
 
209
 public:
 
210
  MessagePumpCFRunLoop();
 
211
  virtual ~MessagePumpCFRunLoop();
 
212
 
 
213
  virtual void DoRun(Delegate* delegate) OVERRIDE;
 
214
  virtual void Quit() OVERRIDE;
 
215
 
 
216
 private:
 
217
  virtual void EnterExitRunLoop(CFRunLoopActivity activity) OVERRIDE;
 
218
 
 
219
  // True if Quit is called to stop the innermost MessagePump
 
220
  // (innermost_quittable_) but some other CFRunLoopRun loop (nesting_level_)
 
221
  // is running inside the MessagePump's innermost Run call.
 
222
  bool quit_pending_;
 
223
 
 
224
  DISALLOW_COPY_AND_ASSIGN(MessagePumpCFRunLoop);
 
225
};
 
226
 
 
227
class MessagePumpNSRunLoop : public MessagePumpCFRunLoopBase {
 
228
 public:
 
229
  BASE_EXPORT MessagePumpNSRunLoop();
 
230
  virtual ~MessagePumpNSRunLoop();
 
231
 
 
232
  virtual void DoRun(Delegate* delegate) OVERRIDE;
 
233
  virtual void Quit() OVERRIDE;
 
234
 
 
235
 private:
 
236
  // A source that doesn't do anything but provide something signalable
 
237
  // attached to the run loop.  This source will be signalled when Quit
 
238
  // is called, to cause the loop to wake up so that it can stop.
 
239
  CFRunLoopSourceRef quit_source_;
 
240
 
 
241
  // False after Quit is called.
 
242
  bool keep_running_;
 
243
 
 
244
  DISALLOW_COPY_AND_ASSIGN(MessagePumpNSRunLoop);
 
245
};
 
246
 
 
247
#if defined(OS_IOS)
 
248
// This is a fake message pump.  It attaches sources to the main thread's
 
249
// CFRunLoop, so PostTask() will work, but it is unable to drive the loop
 
250
// directly, so calling Run() or Quit() are errors.
 
251
class MessagePumpUIApplication : public MessagePumpCFRunLoopBase {
 
252
 public:
 
253
  MessagePumpUIApplication();
 
254
  virtual ~MessagePumpUIApplication();
 
255
  virtual void DoRun(Delegate* delegate) OVERRIDE;
 
256
  virtual void Quit() OVERRIDE;
 
257
 
 
258
  // This message pump can not spin the main message loop directly.  Instead,
 
259
  // call |Attach()| to set up a delegate.  It is an error to call |Run()|.
 
260
  virtual void Attach(Delegate* delegate);
 
261
 
 
262
 private:
 
263
  RunLoop* run_loop_;
 
264
 
 
265
  DISALLOW_COPY_AND_ASSIGN(MessagePumpUIApplication);
 
266
};
 
267
 
 
268
#else
 
269
 
 
270
class MessagePumpNSApplication : public MessagePumpCFRunLoopBase {
 
271
 public:
 
272
  MessagePumpNSApplication();
 
273
  virtual ~MessagePumpNSApplication();
 
274
 
 
275
  virtual void DoRun(Delegate* delegate) OVERRIDE;
 
276
  virtual void Quit() OVERRIDE;
 
277
 
 
278
 private:
 
279
  // False after Quit is called.
 
280
  bool keep_running_;
 
281
 
 
282
  // True if DoRun is managing its own run loop as opposed to letting
 
283
  // -[NSApplication run] handle it.  The outermost run loop in the application
 
284
  // is managed by -[NSApplication run], inner run loops are handled by a loop
 
285
  // in DoRun.
 
286
  bool running_own_loop_;
 
287
 
 
288
  DISALLOW_COPY_AND_ASSIGN(MessagePumpNSApplication);
 
289
};
 
290
 
 
291
class MessagePumpCrApplication : public MessagePumpNSApplication {
 
292
 public:
 
293
  MessagePumpCrApplication();
 
294
  virtual ~MessagePumpCrApplication();
 
295
 
 
296
 protected:
 
297
  // Returns nil if NSApp is currently in the middle of calling
 
298
  // -sendEvent.  Requires NSApp implementing CrAppProtocol.
 
299
  virtual NSAutoreleasePool* CreateAutoreleasePool() OVERRIDE;
 
300
 
 
301
 private:
 
302
  DISALLOW_COPY_AND_ASSIGN(MessagePumpCrApplication);
 
303
};
 
304
#endif  // !defined(OS_IOS)
 
305
 
 
306
class MessagePumpMac {
 
307
 public:
 
308
  // If not on the main thread, returns a new instance of
 
309
  // MessagePumpNSRunLoop.
 
310
  //
 
311
  // On the main thread, if NSApp exists and conforms to
 
312
  // CrAppProtocol, creates an instances of MessagePumpCrApplication.
 
313
  //
 
314
  // Otherwise creates an instance of MessagePumpNSApplication using a
 
315
  // default NSApplication.
 
316
  static MessagePump* Create();
 
317
 
 
318
#if !defined(OS_IOS)
 
319
  // If a pump is created before the required CrAppProtocol is
 
320
  // created, the wrong MessagePump subclass could be used.
 
321
  // UsingCrApp() returns false if the message pump was created before
 
322
  // NSApp was initialized, or if NSApp does not implement
 
323
  // CrAppProtocol.  NSApp must be initialized before calling.
 
324
  BASE_EXPORT static bool UsingCrApp();
 
325
 
 
326
  // Wrapper to query -[NSApp isHandlingSendEvent] from C++ code.
 
327
  // Requires NSApp to implement CrAppProtocol.
 
328
  BASE_EXPORT static bool IsHandlingSendEvent();
 
329
#endif  // !defined(OS_IOS)
 
330
 
 
331
 private:
 
332
  DISALLOW_IMPLICIT_CONSTRUCTORS(MessagePumpMac);
 
333
};
 
334
 
 
335
}  // namespace base
 
336
 
 
337
#endif  // BASE_MESSAGE_LOOP_MESSAGE_PUMP_MAC_H_