OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2007 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2007 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 if (wake_up_) { | 205 if (wake_up_) { |
206 CFRunLoopSourceSignal(wake_up_); | 206 CFRunLoopSourceSignal(wake_up_); |
207 CFRunLoopWakeUp(run_loop_); | 207 CFRunLoopWakeUp(run_loop_); |
208 } | 208 } |
209 } | 209 } |
210 | 210 |
211 void MacCFSocketServer::OnWakeUpCallback() { | 211 void MacCFSocketServer::OnWakeUpCallback() { |
212 ASSERT(run_loop_ == CFRunLoopGetCurrent()); | 212 ASSERT(run_loop_ == CFRunLoopGetCurrent()); |
213 CFRunLoopStop(run_loop_); | 213 CFRunLoopStop(run_loop_); |
214 } | 214 } |
| 215 |
| 216 /////////////////////////////////////////////////////////////////////////////// |
| 217 // MacCarbonSocketServer |
| 218 /////////////////////////////////////////////////////////////////////////////// |
| 219 #ifndef CARBON_DEPRECATED |
| 220 |
| 221 const UInt32 kEventClassSocketServer = 'MCSS'; |
| 222 const UInt32 kEventWakeUp = 'WAKE'; |
| 223 const EventTypeSpec kEventWakeUpSpec[] = { |
| 224 { kEventClassSocketServer, kEventWakeUp } |
| 225 }; |
| 226 |
| 227 std::string DecodeEvent(EventRef event) { |
| 228 std::string str; |
| 229 DecodeFourChar(::GetEventClass(event), &str); |
| 230 str.push_back(':'); |
| 231 DecodeFourChar(::GetEventKind(event), &str); |
| 232 return str; |
| 233 } |
| 234 |
| 235 MacCarbonSocketServer::MacCarbonSocketServer() |
| 236 : event_queue_(GetCurrentEventQueue()), wake_up_(NULL) { |
| 237 VERIFY(noErr == CreateEvent(NULL, kEventClassSocketServer, kEventWakeUp, 0, |
| 238 kEventAttributeUserEvent, &wake_up_)); |
| 239 } |
| 240 |
| 241 MacCarbonSocketServer::~MacCarbonSocketServer() { |
| 242 if (wake_up_) { |
| 243 ReleaseEvent(wake_up_); |
| 244 } |
| 245 } |
| 246 |
| 247 bool MacCarbonSocketServer::Wait(int cms, bool process_io) { |
| 248 ASSERT(GetCurrentEventQueue() == event_queue_); |
| 249 |
| 250 // Listen to all events if we're processing I/O. |
| 251 // Only listen for our wakeup event if we're not. |
| 252 UInt32 num_types = 0; |
| 253 const EventTypeSpec* events = NULL; |
| 254 if (!process_io) { |
| 255 num_types = GetEventTypeCount(kEventWakeUpSpec); |
| 256 events = kEventWakeUpSpec; |
| 257 } |
| 258 |
| 259 EventTargetRef target = GetEventDispatcherTarget(); |
| 260 EventTimeout timeout = |
| 261 (kForever == cms) ? kEventDurationForever : cms / 1000.0; |
| 262 EventTimeout end_time = GetCurrentEventTime() + timeout; |
| 263 |
| 264 bool done = false; |
| 265 while (!done) { |
| 266 EventRef event; |
| 267 OSStatus result = ReceiveNextEvent(num_types, events, timeout, true, |
| 268 &event); |
| 269 if (noErr == result) { |
| 270 if (wake_up_ != event) { |
| 271 LOG_F(LS_VERBOSE) << "Dispatching event: " << DecodeEvent(event); |
| 272 result = SendEventToEventTarget(event, target); |
| 273 if ((noErr != result) && (eventNotHandledErr != result)) { |
| 274 LOG_E(LS_ERROR, OS, result) << "SendEventToEventTarget"; |
| 275 } |
| 276 } else { |
| 277 done = true; |
| 278 } |
| 279 ReleaseEvent(event); |
| 280 } else if (eventLoopTimedOutErr == result) { |
| 281 ASSERT(cms != kForever); |
| 282 done = true; |
| 283 } else if (eventLoopQuitErr == result) { |
| 284 // Ignore this... we get spurious quits for a variety of reasons. |
| 285 LOG_E(LS_VERBOSE, OS, result) << "ReceiveNextEvent"; |
| 286 } else { |
| 287 // Some strange error occurred. Log it. |
| 288 LOG_E(LS_WARNING, OS, result) << "ReceiveNextEvent"; |
| 289 return false; |
| 290 } |
| 291 if (kForever != cms) { |
| 292 timeout = end_time - GetCurrentEventTime(); |
| 293 } |
| 294 } |
| 295 return true; |
| 296 } |
| 297 |
| 298 void MacCarbonSocketServer::WakeUp() { |
| 299 if (!IsEventInQueue(event_queue_, wake_up_)) { |
| 300 RetainEvent(wake_up_); |
| 301 OSStatus result = PostEventToQueue(event_queue_, wake_up_, |
| 302 kEventPriorityStandard); |
| 303 if (noErr != result) { |
| 304 LOG_E(LS_ERROR, OS, result) << "PostEventToQueue"; |
| 305 } |
| 306 } |
| 307 } |
| 308 |
| 309 /////////////////////////////////////////////////////////////////////////////// |
| 310 // MacCarbonAppSocketServer |
| 311 /////////////////////////////////////////////////////////////////////////////// |
| 312 |
| 313 MacCarbonAppSocketServer::MacCarbonAppSocketServer() |
| 314 : event_queue_(GetCurrentEventQueue()) { |
| 315 // Install event handler |
| 316 VERIFY(noErr == InstallApplicationEventHandler( |
| 317 NewEventHandlerUPP(WakeUpEventHandler), 1, kEventWakeUpSpec, this, |
| 318 &event_handler_)); |
| 319 |
| 320 // Install a timer and set it idle to begin with. |
| 321 VERIFY(noErr == InstallEventLoopTimer(GetMainEventLoop(), |
| 322 kEventDurationForever, |
| 323 kEventDurationForever, |
| 324 NewEventLoopTimerUPP(TimerHandler), |
| 325 this, |
| 326 &timer_)); |
| 327 } |
| 328 |
| 329 MacCarbonAppSocketServer::~MacCarbonAppSocketServer() { |
| 330 RemoveEventLoopTimer(timer_); |
| 331 RemoveEventHandler(event_handler_); |
| 332 } |
| 333 |
| 334 OSStatus MacCarbonAppSocketServer::WakeUpEventHandler( |
| 335 EventHandlerCallRef next, EventRef event, void *data) { |
| 336 QuitApplicationEventLoop(); |
| 337 return noErr; |
| 338 } |
| 339 |
| 340 void MacCarbonAppSocketServer::TimerHandler( |
| 341 EventLoopTimerRef timer, void *data) { |
| 342 QuitApplicationEventLoop(); |
| 343 } |
| 344 |
| 345 bool MacCarbonAppSocketServer::Wait(int cms, bool process_io) { |
| 346 if (!process_io && cms == 0) { |
| 347 // No op. |
| 348 return true; |
| 349 } |
| 350 if (kForever != cms) { |
| 351 // Start a timer. |
| 352 OSStatus error = |
| 353 SetEventLoopTimerNextFireTime(timer_, cms / 1000.0); |
| 354 if (error != noErr) { |
| 355 LOG(LS_ERROR) << "Failed setting next fire time."; |
| 356 } |
| 357 } |
| 358 if (!process_io) { |
| 359 // No way to listen to common modes and not get socket events, unless |
| 360 // we disable each one's callbacks. |
| 361 EnableSocketCallbacks(false); |
| 362 } |
| 363 RunApplicationEventLoop(); |
| 364 if (!process_io) { |
| 365 // Reenable them. Hopefully this won't cause spurious callbacks or |
| 366 // missing ones while they were disabled. |
| 367 EnableSocketCallbacks(true); |
| 368 } |
| 369 return true; |
| 370 } |
| 371 |
| 372 void MacCarbonAppSocketServer::WakeUp() { |
| 373 // TODO: No-op if there's already a WakeUp in flight. |
| 374 EventRef wake_up; |
| 375 VERIFY(noErr == CreateEvent(NULL, kEventClassSocketServer, kEventWakeUp, 0, |
| 376 kEventAttributeUserEvent, &wake_up)); |
| 377 OSStatus result = PostEventToQueue(event_queue_, wake_up, |
| 378 kEventPriorityStandard); |
| 379 if (noErr != result) { |
| 380 LOG_E(LS_ERROR, OS, result) << "PostEventToQueue"; |
| 381 } |
| 382 ReleaseEvent(wake_up); |
| 383 } |
| 384 |
| 385 #endif |
215 } // namespace rtc | 386 } // namespace rtc |
OLD | NEW |