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 | |
386 } // namespace rtc | 215 } // namespace rtc |
OLD | NEW |