| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_MACH_IPC_MAC_H_ | 5 #ifndef BASE_MACH_IPC_MAC_H_ |
| 6 #define BASE_MACH_IPC_MAC_H_ | 6 #define BASE_MACH_IPC_MAC_H_ |
| 7 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include <mach/mach.h> | 9 #include <mach/mach.h> |
| 10 #include <mach/message.h> | 10 #include <mach/message.h> |
| 11 #include <servers/bootstrap.h> | 11 #include <servers/bootstrap.h> |
| 12 #include <sys/types.h> | 12 #include <sys/types.h> |
| 13 | 13 |
| 14 #include <CoreServices/CoreServices.h> | 14 #include <CoreServices/CoreServices.h> |
| 15 | 15 |
| 16 #include "base/basictypes.h" | 16 #include "base/basictypes.h" |
| 17 | 17 |
| 18 //============================================================================== | 18 //============================================================================== |
| 19 // DISCUSSION: | 19 // DISCUSSION: |
| 20 // | 20 // |
| 21 // The three main classes of interest are | 21 // The three main classes of interest are |
| 22 // | 22 // |
| 23 // MachMessage: a wrapper for a mach message of the following form | 23 // MachMessage: a wrapper for a Mach message of the following form |
| 24 // mach_msg_header_t | 24 // mach_msg_header_t |
| 25 // mach_msg_body_t | 25 // mach_msg_body_t |
| 26 // optional descriptors | 26 // optional descriptors |
| 27 // optional extra message data | 27 // optional extra message data |
| 28 // | 28 // |
| 29 // MachReceiveMessage and MachSendMessage subclass MachMessage | 29 // MachReceiveMessage and MachSendMessage subclass MachMessage |
| 30 // and are used instead of MachMessage which is an abstract base class | 30 // and are used instead of MachMessage which is an abstract base class |
| 31 // | 31 // |
| 32 // ReceivePort: | 32 // ReceivePort: |
| 33 // Represents a mach port for which we have receive rights | 33 // Represents a Mach port for which we have receive rights |
| 34 // | 34 // |
| 35 // MachPortSender: | 35 // MachPortSender: |
| 36 // Represents a mach port for which we have send rights | 36 // Represents a Mach port for which we have send rights |
| 37 // | 37 // |
| 38 // Here's an example to receive a message on a server port: | 38 // Here's an example to receive a message on a server port: |
| 39 // | 39 // |
| 40 // // This creates our named server port | 40 // // This creates our named server port |
| 41 // ReceivePort receivePort("com.Google.MyService"); | 41 // ReceivePort receivePort("com.Google.MyService"); |
| 42 // | 42 // |
| 43 // MachReceiveMessage message; | 43 // MachReceiveMessage message; |
| 44 // kern_return_t result = receivePort.WaitForMessage(&message, 0); | 44 // kern_return_t result = receivePort.WaitForMessage(&message, 0); |
| 45 // | 45 // |
| 46 // if (result == KERN_SUCCESS && message.GetMessageID() == 57) { | 46 // if (result == KERN_SUCCESS && message.GetMessageID() == 57) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 return *this; | 120 return *this; |
| 121 } | 121 } |
| 122 | 122 |
| 123 // For convenience | 123 // For convenience |
| 124 operator mach_port_t() const { | 124 operator mach_port_t() const { |
| 125 return GetMachPort(); | 125 return GetMachPort(); |
| 126 } | 126 } |
| 127 }; | 127 }; |
| 128 | 128 |
| 129 //============================================================================== | 129 //============================================================================== |
| 130 // MachMessage: a wrapper for a mach message | 130 // MachMessage: a wrapper for a Mach message |
| 131 // (mach_msg_header_t, mach_msg_body_t, extra data) | 131 // (mach_msg_header_t, mach_msg_body_t, extra data) |
| 132 // | 132 // |
| 133 // This considerably simplifies the construction of a message for sending | 133 // This considerably simplifies the construction of a message for sending |
| 134 // and the getting at relevant data and descriptors for the receiver. | 134 // and the getting at relevant data and descriptors for the receiver. |
| 135 // | 135 // |
| 136 // This class can be initialized using external storage of an arbitrary size | 136 // This class can be initialized using external storage of an arbitrary size |
| 137 // or it can manage storage internally. | 137 // or it can manage storage internally. |
| 138 // 1. If storage is allocated internally, the combined size of the descriptors | 138 // 1. If storage is allocated internally, the combined size of the descriptors |
| 139 // plus data must be less than 1024. But as a benefit no memory allocation is | 139 // plus data must be less than 1024. But as a benefit no memory allocation is |
| 140 // necessary. | 140 // necessary. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 158 return EndianU32_LtoN(GetDataPacket()->data_length); | 158 return EndianU32_LtoN(GetDataPacket()->data_length); |
| 159 } | 159 } |
| 160 | 160 |
| 161 // The message ID may be used as a code identifying the type of message | 161 // The message ID may be used as a code identifying the type of message |
| 162 void SetMessageID(int32_t message_id) { | 162 void SetMessageID(int32_t message_id) { |
| 163 GetDataPacket()->id = EndianU32_NtoL(message_id); | 163 GetDataPacket()->id = EndianU32_NtoL(message_id); |
| 164 } | 164 } |
| 165 | 165 |
| 166 int32_t GetMessageID() { return EndianU32_LtoN(GetDataPacket()->id); } | 166 int32_t GetMessageID() { return EndianU32_LtoN(GetDataPacket()->id); } |
| 167 | 167 |
| 168 // Adds a descriptor (typically a mach port) to be translated | 168 // Adds a descriptor (typically a Mach port) to be translated |
| 169 // returns true if successful, otherwise not enough space | 169 // returns true if successful, otherwise not enough space |
| 170 bool AddDescriptor(const MachMsgPortDescriptor &desc); | 170 bool AddDescriptor(const MachMsgPortDescriptor &desc); |
| 171 | 171 |
| 172 int GetDescriptorCount() const { | 172 int GetDescriptorCount() const { |
| 173 return storage_->body.msgh_descriptor_count; | 173 return storage_->body.msgh_descriptor_count; |
| 174 } | 174 } |
| 175 | 175 |
| 176 MachMsgPortDescriptor *GetDescriptor(int n); | 176 MachMsgPortDescriptor *GetDescriptor(int n); |
| 177 | 177 |
| 178 // Convenience method which gets the mach port described by the descriptor | 178 // Convenience method which gets the Mach port described by the descriptor |
| 179 mach_port_t GetTranslatedPort(int n); | 179 mach_port_t GetTranslatedPort(int n); |
| 180 | 180 |
| 181 // A simple message is one with no descriptors | 181 // A simple message is one with no descriptors |
| 182 bool IsSimpleMessage() const { return GetDescriptorCount() == 0; } | 182 bool IsSimpleMessage() const { return GetDescriptorCount() == 0; } |
| 183 | 183 |
| 184 // Sets raw data for the message (returns false if not enough space) | 184 // Sets raw data for the message (returns false if not enough space) |
| 185 bool SetData(const void* data, int32_t data_length); | 185 bool SetData(const void* data, int32_t data_length); |
| 186 | 186 |
| 187 protected: | 187 protected: |
| 188 // Consider this an abstract base class - must create an actual instance | 188 // Consider this an abstract base class - must create an actual instance |
| (...skipping 16 matching lines...) Expand all Loading... |
| 205 | 205 |
| 206 MessageDataPacket* GetDataPacket(); | 206 MessageDataPacket* GetDataPacket(); |
| 207 | 207 |
| 208 void SetDescriptorCount(int n); | 208 void SetDescriptorCount(int n); |
| 209 void SetDescriptor(int n, const MachMsgPortDescriptor &desc); | 209 void SetDescriptor(int n, const MachMsgPortDescriptor &desc); |
| 210 | 210 |
| 211 // Returns total message size setting msgh_size in the header to this value | 211 // Returns total message size setting msgh_size in the header to this value |
| 212 int CalculateSize(); | 212 int CalculateSize(); |
| 213 | 213 |
| 214 // Returns total storage size that this object can grow to, this is inclusive | 214 // Returns total storage size that this object can grow to, this is inclusive |
| 215 // of the mach header. | 215 // of the Mach header. |
| 216 size_t MaxSize() const { return storage_length_bytes_; } | 216 size_t MaxSize() const { return storage_length_bytes_; } |
| 217 | 217 |
| 218 protected: | 218 protected: |
| 219 mach_msg_header_t *Head() { return &(storage_->head); } | 219 mach_msg_header_t *Head() { return &(storage_->head); } |
| 220 | 220 |
| 221 private: | 221 private: |
| 222 struct MachMessageData { | 222 struct MachMessageData { |
| 223 mach_msg_header_t head; | 223 mach_msg_header_t head; |
| 224 mach_msg_body_t body; | 224 mach_msg_body_t body; |
| 225 // descriptors and data may be embedded here. | 225 // descriptors and data may be embedded here. |
| 226 u_int8_t padding[1024]; | 226 u_int8_t padding[1024]; |
| 227 }; | 227 }; |
| 228 | 228 |
| 229 // kEmptyMessageSize needs to have the definition of MachMessageData before | 229 // kEmptyMessageSize needs to have the definition of MachMessageData before |
| 230 // it. | 230 // it. |
| 231 public: | 231 public: |
| 232 // The size of an empty message with no data. | 232 // The size of an empty message with no data. |
| 233 static const size_t kEmptyMessageSize = sizeof(mach_msg_header_t) + | 233 static const size_t kEmptyMessageSize = sizeof(mach_msg_header_t) + |
| 234 sizeof(mach_msg_body_t) + | 234 sizeof(mach_msg_body_t) + |
| 235 sizeof(MessageDataPacket); | 235 sizeof(MessageDataPacket); |
| 236 | 236 |
| 237 private: | 237 private: |
| 238 MachMessageData *storage_; | 238 MachMessageData *storage_; |
| 239 size_t storage_length_bytes_; | 239 size_t storage_length_bytes_; |
| 240 bool own_storage_; // Is storage owned by this object? | 240 bool own_storage_; // Is storage owned by this object? |
| 241 }; | 241 }; |
| 242 | 242 |
| 243 //============================================================================== | 243 //============================================================================== |
| 244 // MachReceiveMessage and MachSendMessage are useful to separate the idea | 244 // MachReceiveMessage and MachSendMessage are useful to separate the idea |
| 245 // of a mach message being sent and being received, and adds increased type | 245 // of a Mach message being sent and being received, and adds increased type |
| 246 // safety: | 246 // safety: |
| 247 // ReceivePort::WaitForMessage() only accepts a MachReceiveMessage | 247 // ReceivePort::WaitForMessage() only accepts a MachReceiveMessage |
| 248 // MachPortSender::SendMessage() only accepts a MachSendMessage | 248 // MachPortSender::SendMessage() only accepts a MachSendMessage |
| 249 | 249 |
| 250 //============================================================================== | 250 //============================================================================== |
| 251 class MachReceiveMessage : public MachMessage { | 251 class MachReceiveMessage : public MachMessage { |
| 252 public: | 252 public: |
| 253 MachReceiveMessage() : MachMessage() {} | 253 MachReceiveMessage() : MachMessage() {} |
| 254 MachReceiveMessage(void *storage, size_t storage_length) | 254 MachReceiveMessage(void *storage, size_t storage_length) |
| 255 : MachMessage(storage, storage_length) {} | 255 : MachMessage(storage, storage_length) {} |
| 256 | 256 |
| 257 private: | 257 private: |
| 258 DISALLOW_COPY_AND_ASSIGN(MachReceiveMessage); | 258 DISALLOW_COPY_AND_ASSIGN(MachReceiveMessage); |
| 259 }; | 259 }; |
| 260 | 260 |
| 261 //============================================================================== | 261 //============================================================================== |
| 262 class MachSendMessage : public MachMessage { | 262 class MachSendMessage : public MachMessage { |
| 263 public: | 263 public: |
| 264 explicit MachSendMessage(int32_t message_id); | 264 explicit MachSendMessage(int32_t message_id); |
| 265 MachSendMessage(void *storage, size_t storage_length, int32_t message_id); | 265 MachSendMessage(void *storage, size_t storage_length, int32_t message_id); |
| 266 | 266 |
| 267 private: | 267 private: |
| 268 void Initialize(int32_t message_id); | 268 void Initialize(int32_t message_id); |
| 269 | 269 |
| 270 DISALLOW_COPY_AND_ASSIGN(MachSendMessage); | 270 DISALLOW_COPY_AND_ASSIGN(MachSendMessage); |
| 271 }; | 271 }; |
| 272 | 272 |
| 273 //============================================================================== | 273 //============================================================================== |
| 274 // Represents a mach port for which we have receive rights | 274 // Represents a Mach port for which we have receive rights |
| 275 class ReceivePort { | 275 class ReceivePort { |
| 276 public: | 276 public: |
| 277 // Creates a new mach port for receiving messages and registers a name for it | 277 // Creates a new Mach port for receiving messages and registers a name for it |
| 278 explicit ReceivePort(const char *receive_port_name); | 278 explicit ReceivePort(const char *receive_port_name); |
| 279 | 279 |
| 280 // Given an already existing mach port, use it. We take ownership of the | 280 // Given an already existing Mach port, use it. We take ownership of the |
| 281 // port and deallocate it in our destructor. | 281 // port and deallocate it in our destructor. |
| 282 explicit ReceivePort(mach_port_t receive_port); | 282 explicit ReceivePort(mach_port_t receive_port); |
| 283 | 283 |
| 284 // Create a new mach port for receiving messages | 284 // Create a new Mach port for receiving messages |
| 285 ReceivePort(); | 285 ReceivePort(); |
| 286 | 286 |
| 287 ~ReceivePort(); | 287 ~ReceivePort(); |
| 288 | 288 |
| 289 // Waits on the mach port until message received or timeout | 289 // Waits on the Mach port until message received or timeout. If |timeout| is |
| 290 // MACH_MSG_TIMEOUT_NONE, this method waits forever. |
| 290 kern_return_t WaitForMessage(MachReceiveMessage *out_message, | 291 kern_return_t WaitForMessage(MachReceiveMessage *out_message, |
| 291 mach_msg_timeout_t timeout); | 292 mach_msg_timeout_t timeout); |
| 292 | 293 |
| 293 // The underlying mach port that we wrap | 294 // The underlying Mach port that we wrap |
| 294 mach_port_t GetPort() const { return port_; } | 295 mach_port_t GetPort() const { return port_; } |
| 295 | 296 |
| 296 private: | 297 private: |
| 297 mach_port_t port_; | 298 mach_port_t port_; |
| 298 kern_return_t init_result_; | 299 kern_return_t init_result_; |
| 299 | 300 |
| 300 DISALLOW_COPY_AND_ASSIGN(ReceivePort); | 301 DISALLOW_COPY_AND_ASSIGN(ReceivePort); |
| 301 }; | 302 }; |
| 302 | 303 |
| 303 //============================================================================== | 304 //============================================================================== |
| 304 // Represents a mach port for which we have send rights | 305 // Represents a Mach port for which we have send rights |
| 305 class MachPortSender { | 306 class MachPortSender { |
| 306 public: | 307 public: |
| 307 // get a port with send rights corresponding to a named registered service | 308 // get a port with send rights corresponding to a named registered service |
| 308 explicit MachPortSender(const char *receive_port_name); | 309 explicit MachPortSender(const char *receive_port_name); |
| 309 | 310 |
| 310 | 311 |
| 311 // Given an already existing mach port, use it. Does not take ownership of | 312 // Given an already existing Mach port, use it. Does not take ownership of |
| 312 // |send_port|. | 313 // |send_port|. |
| 313 explicit MachPortSender(mach_port_t send_port); | 314 explicit MachPortSender(mach_port_t send_port); |
| 314 | 315 |
| 315 kern_return_t SendMessage(MachSendMessage &message, | 316 kern_return_t SendMessage(MachSendMessage &message, |
| 316 mach_msg_timeout_t timeout); | 317 mach_msg_timeout_t timeout); |
| 317 | 318 |
| 318 private: | 319 private: |
| 319 mach_port_t send_port_; | 320 mach_port_t send_port_; |
| 320 kern_return_t init_result_; | 321 kern_return_t init_result_; |
| 321 | 322 |
| 322 DISALLOW_COPY_AND_ASSIGN(MachPortSender); | 323 DISALLOW_COPY_AND_ASSIGN(MachPortSender); |
| 323 }; | 324 }; |
| 324 | 325 |
| 325 } // namespace base | 326 } // namespace base |
| 326 | 327 |
| 327 #endif // BASE_MACH_IPC_MAC_H_ | 328 #endif // BASE_MACH_IPC_MAC_H_ |
| OLD | NEW |