1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef BASE_MACH_IPC_MAC_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define BASE_MACH_IPC_MAC_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <mach/mach.h> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <mach/message.h> 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <servers/bootstrap.h> 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/types.h> 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <CoreServices/CoreServices.h> 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//============================================================================== 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// DISCUSSION: 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The three main classes of interest are 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// MachMessage: a wrapper for a Mach message of the following form 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// mach_msg_header_t 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// mach_msg_body_t 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// optional descriptors 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// optional extra message data 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MachReceiveMessage and MachSendMessage subclass MachMessage 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and are used instead of MachMessage which is an abstract base class 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ReceivePort: 333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Represents a Mach port for which we have receive rights 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MachPortSender: 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Represents a Mach port for which we have send rights 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Here's an example to receive a message on a server port: 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// // This creates our named server port 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ReceivePort receivePort("com.Google.MyService"); 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MachReceiveMessage message; 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// kern_return_t result = receivePort.WaitForMessage(&message, 0); 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// if (result == KERN_SUCCESS && message.GetMessageID() == 57) { 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// mach_port_t task = message.GetTranslatedPort(0); 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// mach_port_t thread = message.GetTranslatedPort(1); 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// char *messageString = message.GetData(); 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// printf("message string = %s\n", messageString); 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// } 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Here is an example of using these classes to send a message to this port: 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// // send to already named port 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MachPortSender sender("com.Google.MyService"); 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MachSendMessage message(57); // our message ID is 57 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// // add some ports to be translated for us 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// message.AddDescriptor(mach_task_self()); // our task 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// message.AddDescriptor(mach_thread_self()); // this thread 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// char messageString[] = "Hello server!\n"; 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// message.SetData(messageString, strlen(messageString)+1); 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// // timeout 1000ms 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// kern_return_t result = sender.SendMessage(message, 1000); 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define PRINT_MACH_RESULT(result_, message_) \ 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf(message_" %s (%d)\n", mach_error_string(result_), result_ ); 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base { 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//============================================================================== 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A wrapper class for mach_msg_port_descriptor_t (with same memory layout) 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// with convenient constructors and accessors 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MachMsgPortDescriptor : public mach_msg_port_descriptor_t { 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // General-purpose constructor 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MachMsgPortDescriptor(mach_port_t in_name, 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mach_msg_type_name_t in_disposition) { 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name = in_name; 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pad1 = 0; 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pad2 = 0; 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott disposition = in_disposition; 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott type = MACH_MSG_PORT_DESCRIPTOR; 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // For passing send rights to a port 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MachMsgPortDescriptor(mach_port_t in_name) { 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name = in_name; 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pad1 = 0; 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pad2 = 0; 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott disposition = MACH_MSG_TYPE_PORT_SEND; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott type = MACH_MSG_PORT_DESCRIPTOR; 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Copy constructor 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MachMsgPortDescriptor(const MachMsgPortDescriptor& desc) { 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name = desc.name; 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pad1 = desc.pad1; 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pad2 = desc.pad2; 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott disposition = desc.disposition; 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott type = desc.type; 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mach_port_t GetMachPort() const { 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return name; 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mach_msg_type_name_t GetDisposition() const { 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return disposition; 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // For convenience 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott operator mach_port_t() const { 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return GetMachPort(); 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//============================================================================== 1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// MachMessage: a wrapper for a Mach message 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (mach_msg_header_t, mach_msg_body_t, extra data) 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This considerably simplifies the construction of a message for sending 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and the getting at relevant data and descriptors for the receiver. 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class can be initialized using external storage of an arbitrary size 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// or it can manage storage internally. 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 1. If storage is allocated internally, the combined size of the descriptors 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// plus data must be less than 1024. But as a benefit no memory allocation is 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// necessary. 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 2. For external storage, a buffer of at least EmptyMessageSize() must be 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// provided. 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A MachMessage object is used by ReceivePort::WaitForMessage 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and MachPortSender::SendMessage 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MachMessage { 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static const size_t kEmptyMessageSize; 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~MachMessage(); 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The receiver of the message can retrieve the raw data this way 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u_int8_t *GetData() { 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return GetDataLength() > 0 ? GetDataPacket()->data : NULL; 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u_int32_t GetDataLength() { 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return EndianU32_LtoN(GetDataPacket()->data_length); 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The message ID may be used as a code identifying the type of message 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void SetMessageID(int32_t message_id) { 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GetDataPacket()->id = EndianU32_NtoL(message_id); 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32_t GetMessageID() { return EndianU32_LtoN(GetDataPacket()->id); } 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Adds a descriptor (typically a Mach port) to be translated 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // returns true if successful, otherwise not enough space 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool AddDescriptor(const MachMsgPortDescriptor &desc); 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int GetDescriptorCount() const { 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return storage_->body.msgh_descriptor_count; 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MachMsgPortDescriptor *GetDescriptor(int n); 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Convenience method which gets the Mach port described by the descriptor 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mach_port_t GetTranslatedPort(int n); 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A simple message is one with no descriptors 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool IsSimpleMessage() const { return GetDescriptorCount() == 0; } 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Sets raw data for the message (returns false if not enough space) 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool SetData(const void* data, int32_t data_length); 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Consider this an abstract base class - must create an actual instance 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // of MachReceiveMessage or MachSendMessage 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MachMessage(); 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Constructor for use with preallocate storage. 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // storage_length must be >= EmptyMessageSize() 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MachMessage(void *storage, size_t storage_length); 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend class ReceivePort; 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend class MachPortSender; 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Represents raw data in our message 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct MessageDataPacket { 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32_t id; // little-endian 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32_t data_length; // little-endian 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u_int8_t data[1]; // actual size limited by storage_length_bytes_ 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageDataPacket* GetDataPacket(); 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void SetDescriptorCount(int n); 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void SetDescriptor(int n, const MachMsgPortDescriptor &desc); 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns total message size setting msgh_size in the header to this value 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int CalculateSize(); 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns total storage size that this object can grow to, this is inclusive 2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // of the Mach header. 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t MaxSize() const { return storage_length_bytes_; } 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mach_msg_header_t *Head() { return &(storage_->head); } 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct MachMessageData { 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mach_msg_header_t head; 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mach_msg_body_t body; 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // descriptors and data may be embedded here. 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u_int8_t padding[1024]; 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MachMessageData *storage_; 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t storage_length_bytes_; 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool own_storage_; // Is storage owned by this object? 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//============================================================================== 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MachReceiveMessage and MachSendMessage are useful to separate the idea 2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// of a Mach message being sent and being received, and adds increased type 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// safety: 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ReceivePort::WaitForMessage() only accepts a MachReceiveMessage 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MachPortSender::SendMessage() only accepts a MachSendMessage 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//============================================================================== 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MachReceiveMessage : public MachMessage { 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MachReceiveMessage() : MachMessage() {} 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MachReceiveMessage(void *storage, size_t storage_length) 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : MachMessage(storage, storage_length) {} 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(MachReceiveMessage); 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//============================================================================== 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MachSendMessage : public MachMessage { 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit MachSendMessage(int32_t message_id); 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MachSendMessage(void *storage, size_t storage_length, int32_t message_id); 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Initialize(int32_t message_id); 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(MachSendMessage); 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//============================================================================== 2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Represents a Mach port for which we have receive rights 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ReceivePort { 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Creates a new Mach port for receiving messages and registers a name for it 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit ReceivePort(const char *receive_port_name); 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Given an already existing Mach port, use it. We take ownership of the 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // port and deallocate it in our destructor. 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit ReceivePort(mach_port_t receive_port); 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Create a new Mach port for receiving messages 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ReceivePort(); 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~ReceivePort(); 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Waits on the Mach port until message received or timeout. If |timeout| is 2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // MACH_MSG_TIMEOUT_NONE, this method waits forever. 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kern_return_t WaitForMessage(MachReceiveMessage *out_message, 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mach_msg_timeout_t timeout); 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The underlying Mach port that we wrap 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mach_port_t GetPort() const { return port_; } 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mach_port_t port_; 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kern_return_t init_result_; 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(ReceivePort); 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//============================================================================== 2903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Represents a Mach port for which we have send rights 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MachPortSender { 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // get a port with send rights corresponding to a named registered service 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit MachPortSender(const char *receive_port_name); 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Given an already existing Mach port, use it. Does not take ownership of 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |send_port|. 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit MachPortSender(mach_port_t send_port); 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kern_return_t SendMessage(MachSendMessage &message, 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mach_msg_timeout_t timeout); 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mach_port_t send_port_; 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kern_return_t init_result_; 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(MachPortSender); 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace base 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // BASE_MACH_IPC_MAC_H_ 314