|
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 |
|
3 // found in the LICENSE file. |
|
4 |
|
5 #include "chrome/common/mach_message_source_mac.h" |
|
6 |
|
7 #include "base/logging.h" |
|
8 |
|
9 MachMessageSource::MachMessageSource(mach_port_t port, |
|
10 MachPortListener* msg_listener, |
|
11 bool* success) { |
|
12 DCHECK(msg_listener); |
|
13 DCHECK(success); |
|
14 DCHECK(port != MACH_PORT_NULL); |
|
15 |
|
16 CFMachPortContext port_context = {0}; |
|
17 port_context.info = msg_listener; |
|
18 |
|
19 scoped_cftyperef<CFMachPortRef> cf_mach_port_ref( |
|
20 CFMachPortCreateWithPort(kCFAllocatorDefault, |
|
21 port, |
|
22 MachMessageSource::OnReceiveMachMessage, |
|
23 &port_context, |
|
24 NULL)); |
|
25 |
|
26 if (cf_mach_port_ref.get() == NULL) { |
|
27 CHROMIUM_LOG(WARNING) << "CFMachPortCreate failed"; |
|
28 *success = false; |
|
29 return; |
|
30 } |
|
31 |
|
32 // Create a RL source. |
|
33 machport_runloop_ref_.reset( |
|
34 CFMachPortCreateRunLoopSource(kCFAllocatorDefault, |
|
35 cf_mach_port_ref.get(), |
|
36 0)); |
|
37 |
|
38 if (machport_runloop_ref_.get() == NULL) { |
|
39 CHROMIUM_LOG(WARNING) << "CFMachPortCreateRunLoopSource failed"; |
|
40 *success = false; |
|
41 return; |
|
42 } |
|
43 |
|
44 CFRunLoopAddSource(CFRunLoopGetCurrent(), |
|
45 machport_runloop_ref_.get(), |
|
46 kCFRunLoopCommonModes); |
|
47 *success = true; |
|
48 } |
|
49 |
|
50 MachMessageSource::~MachMessageSource() { |
|
51 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), |
|
52 machport_runloop_ref_.get(), |
|
53 kCFRunLoopCommonModes); |
|
54 } |
|
55 |
|
56 // static |
|
57 void MachMessageSource::OnReceiveMachMessage(CFMachPortRef port, void* msg, |
|
58 CFIndex size, void* closure) { |
|
59 MachPortListener *msg_listener = static_cast<MachPortListener*>(closure); |
|
60 size_t msg_size = (size < 0) ? 0 : static_cast<size_t>(size); |
|
61 DCHECK(msg && msg_size > 0); // this should never happen! |
|
62 |
|
63 if (msg_listener && msg && msg_size > 0) { |
|
64 msg_listener->OnMachMessageReceived(msg, msg_size); |
|
65 } |
|
66 } |