michael@0: // Copyright (c) 2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include "chrome/common/mach_message_source_mac.h" michael@0: michael@0: #include "base/logging.h" michael@0: michael@0: MachMessageSource::MachMessageSource(mach_port_t port, michael@0: MachPortListener* msg_listener, michael@0: bool* success) { michael@0: DCHECK(msg_listener); michael@0: DCHECK(success); michael@0: DCHECK(port != MACH_PORT_NULL); michael@0: michael@0: CFMachPortContext port_context = {0}; michael@0: port_context.info = msg_listener; michael@0: michael@0: scoped_cftyperef cf_mach_port_ref( michael@0: CFMachPortCreateWithPort(kCFAllocatorDefault, michael@0: port, michael@0: MachMessageSource::OnReceiveMachMessage, michael@0: &port_context, michael@0: NULL)); michael@0: michael@0: if (cf_mach_port_ref.get() == NULL) { michael@0: CHROMIUM_LOG(WARNING) << "CFMachPortCreate failed"; michael@0: *success = false; michael@0: return; michael@0: } michael@0: michael@0: // Create a RL source. michael@0: machport_runloop_ref_.reset( michael@0: CFMachPortCreateRunLoopSource(kCFAllocatorDefault, michael@0: cf_mach_port_ref.get(), michael@0: 0)); michael@0: michael@0: if (machport_runloop_ref_.get() == NULL) { michael@0: CHROMIUM_LOG(WARNING) << "CFMachPortCreateRunLoopSource failed"; michael@0: *success = false; michael@0: return; michael@0: } michael@0: michael@0: CFRunLoopAddSource(CFRunLoopGetCurrent(), michael@0: machport_runloop_ref_.get(), michael@0: kCFRunLoopCommonModes); michael@0: *success = true; michael@0: } michael@0: michael@0: MachMessageSource::~MachMessageSource() { michael@0: CFRunLoopRemoveSource(CFRunLoopGetCurrent(), michael@0: machport_runloop_ref_.get(), michael@0: kCFRunLoopCommonModes); michael@0: } michael@0: michael@0: // static michael@0: void MachMessageSource::OnReceiveMachMessage(CFMachPortRef port, void* msg, michael@0: CFIndex size, void* closure) { michael@0: MachPortListener *msg_listener = static_cast(closure); michael@0: size_t msg_size = (size < 0) ? 0 : static_cast(size); michael@0: DCHECK(msg && msg_size > 0); // this should never happen! michael@0: michael@0: if (msg_listener && msg && msg_size > 0) { michael@0: msg_listener->OnMachMessageReceived(msg, msg_size); michael@0: } michael@0: }