69 lines
2.3 KiB
C++
69 lines
2.3 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
// Copyright (c) 2008 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "chrome/common/mach_message_source_mac.h"
|
|
|
|
#include "base/logging.h"
|
|
|
|
MachMessageSource::MachMessageSource(mach_port_t port,
|
|
MachPortListener* msg_listener,
|
|
bool* success) {
|
|
DCHECK(msg_listener);
|
|
DCHECK(success);
|
|
DCHECK(port != MACH_PORT_NULL);
|
|
|
|
CFMachPortContext port_context = {0};
|
|
port_context.info = msg_listener;
|
|
|
|
scoped_cftyperef<CFMachPortRef> cf_mach_port_ref(
|
|
CFMachPortCreateWithPort(kCFAllocatorDefault,
|
|
port,
|
|
MachMessageSource::OnReceiveMachMessage,
|
|
&port_context,
|
|
NULL));
|
|
|
|
if (cf_mach_port_ref.get() == NULL) {
|
|
CHROMIUM_LOG(WARNING) << "CFMachPortCreate failed";
|
|
*success = false;
|
|
return;
|
|
}
|
|
|
|
// Create a RL source.
|
|
machport_runloop_ref_.reset(
|
|
CFMachPortCreateRunLoopSource(kCFAllocatorDefault,
|
|
cf_mach_port_ref.get(),
|
|
0));
|
|
|
|
if (machport_runloop_ref_.get() == NULL) {
|
|
CHROMIUM_LOG(WARNING) << "CFMachPortCreateRunLoopSource failed";
|
|
*success = false;
|
|
return;
|
|
}
|
|
|
|
CFRunLoopAddSource(CFRunLoopGetCurrent(),
|
|
machport_runloop_ref_.get(),
|
|
kCFRunLoopCommonModes);
|
|
*success = true;
|
|
}
|
|
|
|
MachMessageSource::~MachMessageSource() {
|
|
CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
|
|
machport_runloop_ref_.get(),
|
|
kCFRunLoopCommonModes);
|
|
}
|
|
|
|
// static
|
|
void MachMessageSource::OnReceiveMachMessage(CFMachPortRef port, void* msg,
|
|
CFIndex size, void* closure) {
|
|
MachPortListener *msg_listener = static_cast<MachPortListener*>(closure);
|
|
size_t msg_size = (size < 0) ? 0 : static_cast<size_t>(size);
|
|
DCHECK(msg && msg_size > 0); // this should never happen!
|
|
|
|
if (msg_listener && msg && msg_size > 0) {
|
|
msg_listener->OnMachMessageReceived(msg, msg_size);
|
|
}
|
|
}
|