Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: base/message_pump_mac.mm

Issue 149687: delegateless pump (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/message_pump_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/message_pump_mac.h" 5 #include "base/message_pump_mac.h"
6 6
7 #import <AppKit/AppKit.h> 7 #import <AppKit/AppKit.h>
8 #import <Foundation/Foundation.h> 8 #import <Foundation/Foundation.h>
9 #include <float.h> 9 #include <float.h>
10 10
11 #include "base/scoped_nsautorelease_pool.h" 11 #include "base/scoped_nsautorelease_pool.h"
12 #include "base/time.h" 12 #include "base/time.h"
13 13
14 namespace { 14 namespace {
15 15
16 void NoOp(void* info) { 16 void NoOp(void* info) {
17 } 17 }
18 18
19 } // namespace 19 } // namespace
20 20
21 namespace base { 21 namespace base {
22 22
23 // Must be called on the run loop thread. 23 // Must be called on the run loop thread.
24 MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase() 24 MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
25 : nesting_level_(0), 25 : nesting_level_(0),
26 delegate_(NULL) 26 delegate_(NULL),
27 delegateless_work_(false),
28 delegateless_delayed_work_(false),
29 delegateless_idle_work_(false)
27 { 30 {
28 run_loop_ = CFRunLoopGetCurrent(); 31 run_loop_ = CFRunLoopGetCurrent();
29 CFRetain(run_loop_); 32 CFRetain(run_loop_);
30 33
31 // Set a repeating timer with a preposterous firing time and interval. The 34 // Set a repeating timer with a preposterous firing time and interval. The
32 // timer will effectively never fire as-is. The firing time will be adjusted 35 // timer will effectively never fire as-is. The firing time will be adjusted
33 // as needed when ScheduleDelayedWork is called. 36 // as needed when ScheduleDelayedWork is called.
34 CFRunLoopTimerContext timer_context = CFRunLoopTimerContext(); 37 CFRunLoopTimerContext timer_context = CFRunLoopTimerContext();
35 timer_context.info = this; 38 timer_context.info = this;
36 delayed_work_timer_ = CFRunLoopTimerCreate(NULL, // allocator 39 delayed_work_timer_ = CFRunLoopTimerCreate(NULL, // allocator
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 CFRelease(delayed_work_timer_); 121 CFRelease(delayed_work_timer_);
119 122
120 CFRelease(run_loop_); 123 CFRelease(run_loop_);
121 } 124 }
122 125
123 // Must be called on the run loop thread. 126 // Must be called on the run loop thread.
124 void MessagePumpCFRunLoopBase::Run(Delegate* delegate) { 127 void MessagePumpCFRunLoopBase::Run(Delegate* delegate) {
125 Delegate* last_delegate = delegate_; 128 Delegate* last_delegate = delegate_;
126 delegate_ = delegate; 129 delegate_ = delegate;
127 130
131 // If any work showed up but could not be dispatched for want of a delegate,
132 // set it up for dispatch again now that a delegate is available.
133 if (delegateless_work_) {
134 CFRunLoopSourceSignal(work_source_);
135 delegateless_work_ = false;
136 }
137 if (delegateless_delayed_work_) {
138 CFRunLoopSourceSignal(delayed_work_source_);
139 delegateless_delayed_work_ = false;
140 }
141 if (delegateless_idle_work_) {
142 CFRunLoopSourceSignal(idle_work_source_);
143 delegateless_idle_work_ = false;
144 }
145
128 DoRun(delegate); 146 DoRun(delegate);
129 147
130 delegate_ = last_delegate; 148 delegate_ = last_delegate;
131 } 149 }
132 150
133 // May be called on any thread. 151 // May be called on any thread.
134 void MessagePumpCFRunLoopBase::ScheduleWork() { 152 void MessagePumpCFRunLoopBase::ScheduleWork() {
135 CFRunLoopSourceSignal(work_source_); 153 CFRunLoopSourceSignal(work_source_);
136 CFRunLoopWakeUp(run_loop_); 154 CFRunLoopWakeUp(run_loop_);
137 } 155 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 // static 194 // static
177 void MessagePumpCFRunLoopBase::RunWorkSource(void* info) { 195 void MessagePumpCFRunLoopBase::RunWorkSource(void* info) {
178 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 196 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
179 self->RunWork(); 197 self->RunWork();
180 } 198 }
181 199
182 // Called by MessagePumpCFRunLoopBase::RunWorkSource. 200 // Called by MessagePumpCFRunLoopBase::RunWorkSource.
183 bool MessagePumpCFRunLoopBase::RunWork() { 201 bool MessagePumpCFRunLoopBase::RunWork() {
184 if (!delegate_) { 202 if (!delegate_) {
185 // This point can be reached with a NULL delegate_ if Run is not on the 203 // This point can be reached with a NULL delegate_ if Run is not on the
186 // stack but foreign code is spinning the CFRunLoop. 204 // stack but foreign code is spinning the CFRunLoop. Arrange to come back
187 205 // here when a delegate is available.
188 // TODO(???): we get here while looping in our temporary 1st run 206 delegateless_work_ = true;
189 // dialog. If we simply return false, we choke rather brutally
190 // (we no longer do work ever again). For now, we simply
191 // re-signal ourself so we come around again. The problem only
192 // happens in a branded build if
193 // ~/Library/Preferences/com.google.Chrome.plist does not exist.
194 CFRunLoopSourceSignal(work_source_);
195
196 return false; 207 return false;
197 } 208 }
198 209
199 // If we're on the main event loop, the NSApp runloop won't clean up the 210 // If we're on the main event loop, the NSApp runloop won't clean up the
200 // autorelease pool until there is a UI event, so use a local one for any 211 // autorelease pool until there is a UI event, so use a local one for any
201 // autoreleased objects to ensure they go away sooner. 212 // autoreleased objects to ensure they go away sooner.
202 ScopedNSAutoreleasePool autorelease_pool; 213 ScopedNSAutoreleasePool autorelease_pool;
203 214
204 // Call DoWork once, and if something was done, arrange to come back here 215 // Call DoWork once, and if something was done, arrange to come back here
205 // again as long as the loop is still running. 216 // again as long as the loop is still running.
206 bool did_work = delegate_->DoWork(); 217 bool did_work = delegate_->DoWork();
207 if (did_work) { 218 if (did_work) {
208 CFRunLoopSourceSignal(work_source_); 219 CFRunLoopSourceSignal(work_source_);
209 } 220 }
210 221
211 return did_work; 222 return did_work;
212 } 223 }
213 224
214 // Called from the run loop. 225 // Called from the run loop.
215 // static 226 // static
216 void MessagePumpCFRunLoopBase::RunDelayedWorkSource(void* info) { 227 void MessagePumpCFRunLoopBase::RunDelayedWorkSource(void* info) {
217 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 228 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
218 self->RunDelayedWork(); 229 self->RunDelayedWork();
219 } 230 }
220 231
221 // Called by MessagePumpCFRunLoopBase::RunDelayedWorkSource. 232 // Called by MessagePumpCFRunLoopBase::RunDelayedWorkSource.
222 bool MessagePumpCFRunLoopBase::RunDelayedWork() { 233 bool MessagePumpCFRunLoopBase::RunDelayedWork() {
223 if (!delegate_) { 234 if (!delegate_) {
224 // This point can be reached with a NULL delegate_ if Run is not on the 235 // This point can be reached with a NULL delegate_ if Run is not on the
225 // stack but foreign code is spinning the CFRunLoop. 236 // stack but foreign code is spinning the CFRunLoop. Arrange to come back
237 // here when a delegate is available.
238 delegateless_delayed_work_ = true;
226 return false; 239 return false;
227 } 240 }
228 241
229 // If we're on the main event loop, the NSApp runloop won't clean up the 242 // If we're on the main event loop, the NSApp runloop won't clean up the
230 // autorelease pool until there is a UI event, so use a local one for any 243 // autorelease pool until there is a UI event, so use a local one for any
231 // autoreleased objects to ensure they go away sooner. 244 // autoreleased objects to ensure they go away sooner.
232 ScopedNSAutoreleasePool autorelease_pool; 245 ScopedNSAutoreleasePool autorelease_pool;
233 246
234 Time next_time; 247 Time next_time;
235 delegate_->DoDelayedWork(&next_time); 248 delegate_->DoDelayedWork(&next_time);
(...skipping 19 matching lines...) Expand all
255 // static 268 // static
256 void MessagePumpCFRunLoopBase::RunIdleWorkSource(void* info) { 269 void MessagePumpCFRunLoopBase::RunIdleWorkSource(void* info) {
257 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 270 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
258 self->RunIdleWork(); 271 self->RunIdleWork();
259 } 272 }
260 273
261 // Called by MessagePumpCFRunLoopBase::RunIdleWorkSource. 274 // Called by MessagePumpCFRunLoopBase::RunIdleWorkSource.
262 bool MessagePumpCFRunLoopBase::RunIdleWork() { 275 bool MessagePumpCFRunLoopBase::RunIdleWork() {
263 if (!delegate_) { 276 if (!delegate_) {
264 // This point can be reached with a NULL delegate_ if Run is not on the 277 // This point can be reached with a NULL delegate_ if Run is not on the
265 // stack but foreign code is spinning the CFRunLoop. 278 // stack but foreign code is spinning the CFRunLoop. Arrange to come back
279 // here when a delegate is available.
280 delegateless_idle_work_ = true;
266 return false; 281 return false;
267 } 282 }
268 283
269 // If we're on the main event loop, the NSApp runloop won't clean up the 284 // If we're on the main event loop, the NSApp runloop won't clean up the
270 // autorelease pool until there is a UI event, so use a local one for any 285 // autorelease pool until there is a UI event, so use a local one for any
271 // autoreleased objects to ensure they go away sooner. 286 // autoreleased objects to ensure they go away sooner.
272 ScopedNSAutoreleasePool autorelease_pool; 287 ScopedNSAutoreleasePool autorelease_pool;
273 288
274 // Call DoIdleWork once, and if something was done, arrange to come back here 289 // Call DoIdleWork once, and if something was done, arrange to come back here
275 // again as long as the loop is still running. 290 // again as long as the loop is still running.
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 // static 521 // static
507 MessagePump* MessagePumpMac::Create() { 522 MessagePump* MessagePumpMac::Create() {
508 if ([NSThread isMainThread]) { 523 if ([NSThread isMainThread]) {
509 return new MessagePumpNSApplication; 524 return new MessagePumpNSApplication;
510 } 525 }
511 526
512 return new MessagePumpNSRunLoop; 527 return new MessagePumpNSRunLoop;
513 } 528 }
514 529
515 } // namespace base 530 } // namespace base
OLDNEW
« no previous file with comments | « base/message_pump_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698