diff options
author | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-24 21:37:13 +0000 |
---|---|---|
committer | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-24 21:37:13 +0000 |
commit | 37eedd8a6922e9810fd35df3a609126edf1c7a05 (patch) | |
tree | 26ee21747afcf74a4e03d9f2865769e7f4b7dff1 /chrome | |
parent | 22bb1a47a2fa1510c525c7dfe8c8d14058a337ba (diff) | |
download | chromium_src-37eedd8a6922e9810fd35df3a609126edf1c7a05.zip chromium_src-37eedd8a6922e9810fd35df3a609126edf1c7a05.tar.gz chromium_src-37eedd8a6922e9810fd35df3a609126edf1c7a05.tar.bz2 |
Add class to encapsulate a CF Mach Message Source and handle it's liftime.
This class handles adding a listener on Mach port to the current CFRunloop and
calling a delegate when a message is received on that port.
Review URL: http://codereview.chromium.org/11331
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5936 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/chrome.xcodeproj/project.pbxproj | 6 | ||||
-rw-r--r-- | chrome/common/mach_message_source_mac.cc | 66 | ||||
-rw-r--r-- | chrome/common/mach_message_source_mac.h | 59 |
3 files changed, 131 insertions, 0 deletions
diff --git a/chrome/chrome.xcodeproj/project.pbxproj b/chrome/chrome.xcodeproj/project.pbxproj index e143d70..8e9798e 100644 --- a/chrome/chrome.xcodeproj/project.pbxproj +++ b/chrome/chrome.xcodeproj/project.pbxproj @@ -138,6 +138,7 @@ 4DDC63E70EAE344300FB5EBE /* metrics_response_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF8B60E9D4839009A6919 /* metrics_response_unittest.cc */; }; 4DDC644B0EAE390800FB5EBE /* libxml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D7BFB230E9D4BBF009A6919 /* libxml.a */; }; 4DDC64580EAE394200FB5EBE /* libzlib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DDC64550EAE392400FB5EBE /* libzlib.a */; }; + B54BD8FC0ED622C00093FD54 /* mach_message_source_mac.cc in Sources */ = {isa = PBXBuildFile; fileRef = B54BD8FA0ED622C00093FD54 /* mach_message_source_mac.cc */; }; B562C8430ED49C830077A23F /* mach_ipc_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = B562C8420ED49C830077A23F /* mach_ipc_mac.mm */; }; E48FB9590EC4E9C10052B72B /* safe_browsing_database_bloom.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFADF0E9D49DE009A6919 /* safe_browsing_database_bloom.cc */; }; E48FB95C0EC4E9DD0052B72B /* safe_browsing_database_impl.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFAE10E9D49DE009A6919 /* safe_browsing_database_impl.cc */; }; @@ -1231,6 +1232,8 @@ 4D7BFF7A0E9D5449009A6919 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = "<group>"; }; 4DC6498E0EA92BF90017C876 /* platform_test_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = platform_test_mac.mm; sourceTree = "<group>"; }; 4DDC64500EAE392400FB5EBE /* zlib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = zlib.xcodeproj; path = third_party/zlib/zlib.xcodeproj; sourceTree = "<group>"; }; + B54BD8FA0ED622C00093FD54 /* mach_message_source_mac.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mach_message_source_mac.cc; sourceTree = "<group>"; }; + B54BD8FB0ED622C00093FD54 /* mach_message_source_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mach_message_source_mac.h; sourceTree = "<group>"; }; B562C8410ED49C830077A23F /* mach_ipc_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mach_ipc_mac.h; sourceTree = "<group>"; }; B562C8420ED49C830077A23F /* mach_ipc_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = mach_ipc_mac.mm; sourceTree = "<group>"; }; E48FB9610EC4EA270052B72B /* automation_autocomplete_edit_tracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = automation_autocomplete_edit_tracker.h; sourceTree = "<group>"; }; @@ -2094,6 +2097,8 @@ 4D7BFBD00E9D4C9F009A6919 /* logging_chrome_uitest.cc */, B562C8410ED49C830077A23F /* mach_ipc_mac.h */, B562C8420ED49C830077A23F /* mach_ipc_mac.mm */, + B54BD8FA0ED622C00093FD54 /* mach_message_source_mac.cc */, + B54BD8FB0ED622C00093FD54 /* mach_message_source_mac.h */, 4D7BFBD10E9D4C9F009A6919 /* message_router.cc */, 4D7BFBD20E9D4C9F009A6919 /* message_router.h */, 4D7BFBD30E9D4C9F009A6919 /* mru_cache.h */, @@ -2837,6 +2842,7 @@ 4D7BFC4B0E9D4D06009A6919 /* json_value_serializer.cc in Sources */, 4D7BFC540E9D4D09009A6919 /* libxml_utils.cc in Sources */, B562C8430ED49C830077A23F /* mach_ipc_mac.mm in Sources */, + B54BD8FC0ED622C00093FD54 /* mach_message_source_mac.cc in Sources */, 4D7BFC5C0E9D4D24009A6919 /* notification_service.cc in Sources */, 4D7BFC710E9D4D28009A6919 /* pref_member.cc in Sources */, 4D7BFC7A0E9D4D2B009A6919 /* pref_names.cc in Sources */, diff --git a/chrome/common/mach_message_source_mac.cc b/chrome/common/mach_message_source_mac.cc new file mode 100644 index 0000000..1249d8a --- /dev/null +++ b/chrome/common/mach_message_source_mac.cc @@ -0,0 +1,66 @@ +// 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) { + 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) { + 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); + } +} diff --git a/chrome/common/mach_message_source_mac.h b/chrome/common/mach_message_source_mac.h new file mode 100644 index 0000000..f57539d --- /dev/null +++ b/chrome/common/mach_message_source_mac.h @@ -0,0 +1,59 @@ +// 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. + +#ifndef CHROME_COMMON_MACH_MESSAGE_SOURCE_MAC_H_ +#define CHROME_COMMON_MACH_MESSAGE_SOURCE_MAC_H_ + +#include <CoreServices/CoreServices.h> + +#include "base/scoped_cftyperef.h" + +// Handles registering and cleaning up after a CFRunloopSource for a Mach port. +// Messages received on the port are piped through to a delegate. +// +// Example: +// class MyListener : public MachMessageSource::MachPortListener { +// public: +// void OnMachMessageReceived(void* mach_msg, size_t size) { +// printf("received message on Mach port\n"); +// } +// }; +// +// mach_port_t a_port = ...; +// MyListener listener; +// bool success = false; +// MachMessageSource message_source(port, listener, &success); +// +// if (!success) { +// exit(1); // Couldn't register mach runloop source. +// } +// +// CFRunLoopRun(); // Process messages on runloop... +class MachMessageSource { + public: + // Classes that want to listen on a Mach port can implement + // OnMachMessageReceived, |mach_msg| is a pointer to the raw message data and + // |size| is the buffer size; + class MachPortListener { + public: + virtual void OnMachMessageReceived(void* mach_msg, size_t size) = 0; + }; + + // |listener| is a week reference passed to CF, it needs to remain in + // existence till this object is destroeyd. + MachMessageSource(mach_port_t port, + MachPortListener* listener, + bool* success); + ~MachMessageSource(); + + private: + // Called by CF when a new message arrives on the Mach port. + static void OnReceiveMachMessage(CFMachPortRef port, void* msg, CFIndex size, + void* closure); + + scoped_cftyperef<CFRunLoopSourceRef> machport_runloop_ref_; + DISALLOW_COPY_AND_ASSIGN(MachMessageSource); +}; + +#endif // CHROME_COMMON_MACH_MESSAGE_SOURCE_MAC_H_ |