Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // This header is meant to be included in multiple passes, hence no traditional | 5 // Defining IPC Messages |
| 6 // header guard. | |
| 7 // | 6 // |
| 8 // In your XXX_messages_internal.h file, before defining any messages do: | 7 // Your IPC messages will be defined by macros inside of an XXX_messages.h |
| 9 // #define IPC_MESSAGE_START XMsgStart | 8 // header file. Most of the time, the system can automatically generate all |
| 10 // XMstStart value is from the IPCMessageStart enum in ipc_message_utils.h, and | 9 // of messaging mechanism from these definitions, but sometimes some manual |
| 11 // needs to be unique for each different file. | 10 // coding is required. In these cases, you will also have an XXX_messages.cc |
| 12 // In your XXX_messages.cc file, after all the includes for param types: | 11 // implemation file as well. |
| 12 // | |
| 13 // The senders of your messages will include your XXX_messages.h file to | |
| 14 // get the full set of definitions they need to send your messages. | |
| 15 // | |
| 16 // Each XXX_messages.h file must be registered with the IPC system. This | |
| 17 // requires adding two things: | |
| 18 // - An XXXMsgStart value to the IPCMessageStart enum in ipc_message_utils.h | |
| 19 // - An inclusion of XXX_messages.h file in a message generator .h file | |
| 20 // | |
| 21 // The XXXMsgStart value is an enumeration that ensures uniqueness for | |
| 22 // each different message file. Later, you will use this inside your | |
| 23 // XXX_messages.h file to surrond your message declatation macros: | |
| 24 // #define IPC_MESSAGE_START XXXMsgStart | |
| 25 // ( ... your macro invocations go here ... ) | |
| 26 // #undef IPC_MESSAGE_START | |
| 27 // | |
| 28 // A message generator .h header file pulls in all other message-declaring | |
| 29 // headers for a given component. It is included by a message generator | |
| 30 // .cc file, which is where all the generated code will wind up. Typically, | |
| 31 // you will use an existing generator (e.g. common_message_generator.cc and | |
| 32 // common_message_generator.h in /chrome/common), but there are circumstances | |
| 33 // where you may add a new one. | |
| 34 | |
| 35 // In the rare cicrucmstances where you can't re-use an existing file, | |
| 36 // your YYY_message_generator.cc file for a component YYY would contain | |
| 37 // the following code: | |
| 38 // // Get basic type definitions. | |
| 13 // #define IPC_MESSAGE_IMPL | 39 // #define IPC_MESSAGE_IMPL |
| 14 // #include "X_messages.h" | 40 // #include "path/to/YYY_message_generator.h" |
| 41 // // Generate constructors. | |
| 42 // #include "ipc/struct_constructor_macros.h" | |
| 43 // #include "path/to/YYY_message_generator.h" | |
| 44 // // Generate destructors. | |
| 45 // #include "ipc/struct_destructor_macros.h" | |
| 46 // #include "path/to/YYY_message_generator.h" | |
| 47 // namespace IPC { | |
| 48 // // Generate param traits write methods. | |
| 49 // #include "ipc/ipc_param_traits_write_macros.h" | |
| 50 // #include "path/to/YYY_message_generator.h" | |
| 51 // // Generate param traits read methods. | |
| 52 // #include "ipc/ipc_param_traits_read_macros.h" | |
| 53 // #include "path/to/YYY_message_generator.h" | |
| 54 // // Generate param traits log methods. | |
| 55 // #include "ipc/ipc_param_traits_log_macros.h" | |
| 56 // #include "path/to/YYY_message_generator.h" | |
| 57 // } // namespace IPC | |
| 15 // | 58 // |
| 59 // In cases where manual generation is required, in your XXX_messages.cc | |
| 60 // file, put the following after all the includes for param types: | |
| 61 // #define IPC_MESSAGE_IMPL | |
| 62 // #include "XXXX_messages.h" | |
| 63 // | |
| 64 // The XXX_messages.h file will be multiply-included by the | |
| 65 // YYY_message_generator.cc file, so your XXX_messages file must be | |
| 66 // specially guarded. There will be two sections of the file, one of | |
| 67 // which declares types and is singly-evaluated, and another which invokes | |
| 68 // macros and is multiply-evaluated. The convention used is as follows: | |
| 69 // #ifndef XXX_MESSAGES_H_ | |
| 70 // #define XXX_MESSAGES_H_ | |
| 71 // (... the type definition section goes here ...) | |
| 72 // #endif // XXX_MESSAGES_H_ | |
| 73 // #define IPC_MESSAGE_START XXXMsgStart | |
| 74 // (... the message macro invocations go here ...) | |
| 75 // #undef IPC_MESSAGE_START | |
| 76 // | |
| 77 // Note that there is no #pragma once; doing so would mark the whole file | |
| 78 // as being singly-included. Since your XXX_messages.h file is only | |
| 79 // partially-guarded, care must be taken to ensure that it is only included | |
| 80 // by other .cc files (and the YYY_message_generator.h file). Including an | |
| 81 // XXX_messages.h file in some other .h file may result in duplicate | |
| 82 // declarations and a compilation failure. | |
| 83 // | |
| 84 // Inside the type definition section, you include all of the headers | |
| 85 // required to define the types later used in your message macro invocations. | |
| 86 // Sometimes is it convenient to provide an incomplete class type declaration | |
| 87 // to avoid pulling in a long chain of headers. This is acceptable when | |
| 88 // your XXX_messages.h header is being included by the message sending code, | |
| 89 // but not when the YYY_message_generator.c is building the messages. In | |
| 90 // these cases, follow a convention like: | |
| 91 // class some_class; // One incomplete class declaration | |
| 92 // class_some_other_class; // Another incomplete class declaration | |
| 93 // #ifdef IPC_MESSAGE_IMPL | |
| 94 // #inlcude "path/to/some_class.h" // Full class declaration | |
| 95 // #inlcude "path/to/some_other_class.h" // Full class declaration | |
| 96 // #endif // IPC_MESSAGE_IMPL | |
| 97 // | |
| 98 // Inside the message macro invocation secton, use macros for three things: | |
| 99 // - New struct definitions for IPC | |
| 100 // - Registering existing struct and enum definitions with IPC | |
| 101 // - Defining the messages themselves | |
| 102 // | |
| 103 // New structs are defined with IPC_STRUCT_BEGIN(), IPC_STRUCT_MEMBER(), | |
| 104 // IPC_STRUCT_END() family of macros. These cause the XXX_messages.h | |
| 105 // to proclaim equivalent struct declarations for use by callers, as well | |
| 106 // as later registering the type with the message generation. Note that | |
| 107 // IPC_STRUCT_MEMBER() is only permitted inside matching calls to | |
| 108 // IPC_STRUCT_BEGIN() / IPC_STRUCT_END(). | |
| 109 // | |
| 110 // Externally-defined structs are registered with IPC_STRUCT_TRAITS_BEGIN(), | |
| 111 // IPC_STRUCT_TRAITS_MEMBER(), and IPC_STRUCT_TRAITS_END() macros. These | |
| 112 // cause registration of the types with message generation only. Note that | |
| 113 // IPC_STRUCT_TRAITS_MEMBER() is only permitted inside matching calls | |
| 114 // to IPC_STRUCT_TRAITS_BEGIN() / IPC_STRUCT_TRAITS_END(). | |
| 115 // | |
| 116 // Enum types are registered with a single IPC_ENUM_TRAITS() macro. There | |
| 117 // is no need to enumerate each value to the IPC mechanism. | |
| 118 // | |
| 119 // Once the types have been declared / registered, message definitions follow. | |
| 16 // "Sync" messages are just synchronous calls, the Send() call doesn't return | 120 // "Sync" messages are just synchronous calls, the Send() call doesn't return |
| 17 // until a reply comes back. Input parameters are first (const TYPE&), and | 121 // until a reply comes back. Input parameters are first (const TYPE&), and |
| 18 // To declare a sync message, use the IPC_SYNC_ macros. The numbers at the | 122 // To declare a sync message, use the IPC_SYNC_ macros. The numbers at the |
| 19 // end show how many input/output parameters there are (i.e. 1_2 is 1 in, 2 | 123 // end show how many input/output parameters there are (i.e. 1_2 is 1 in, 2 |
| 20 // out). The caller does a Send([route id, ], in1, &out1, &out2). | 124 // out). The caller does a Send([route id, ], in1, &out1, &out2). |
| 21 // The receiver's handler function will be | 125 // The receiver's handler function will be |
| 22 // void OnSyncMessageName(const type1& in1, type2* out1, type3* out2) | 126 // void OnSyncMessageName(const type1& in1, type2* out1, type3* out2) |
| 23 // | 127 // |
| 24 // | |
| 25 // A caller can also send a synchronous message, while the receiver can respond | 128 // A caller can also send a synchronous message, while the receiver can respond |
| 26 // at a later time. This is transparent from the sender's side. The receiver | 129 // at a later time. This is transparent from the sender's side. The receiver |
| 27 // needs to use a different handler that takes in a IPC::Message* as the output | 130 // needs to use a different handler that takes in a IPC::Message* as the output |
| 28 // type, stash the message, and when it has the data it can Send the message. | 131 // type, stash the message, and when it has the data it can Send the message. |
| 29 // | 132 // |
| 30 // Use the IPC_MESSAGE_HANDLER_DELAY_REPLY macro instead of IPC_MESSAGE_HANDLER | 133 // Use the IPC_MESSAGE_HANDLER_DELAY_REPLY macro instead of IPC_MESSAGE_HANDLER |
| 31 // IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncMessageName, | 134 // IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncMessageName, |
| 32 // OnSyncMessageName) | 135 // OnSyncMessageName) |
| 33 // | 136 // |
| 34 // The handler function will look like: | 137 // The handler function will look like: |
| 35 // void OnSyncMessageName(const type1& in1, IPC::Message* reply_msg); | 138 // void OnSyncMessageName(const type1& in1, IPC::Message* reply_msg); |
| 36 // | 139 // |
| 37 // Receiver stashes the IPC::Message* pointer, and when it's ready, it does: | 140 // Receiver stashes the IPC::Message* pointer, and when it's ready, it does: |
| 38 // ViewHostMsg_SyncMessageName::WriteReplyParams(reply_msg, out1, out2); | 141 // ViewHostMsg_SyncMessageName::WriteReplyParams(reply_msg, out1, out2); |
| 39 // Send(reply_msg); | 142 // Send(reply_msg); |
| 40 | 143 |
| 144 #ifndef IPC_IPC_MESSAGE_MACROS_H_ | |
| 145 #define IPC_IPC_MESSAGE_MACROS_H_ | |
| 146 // Can use #pragma once all XXX_messages.h files clean up IPC_MESSAGE_START | |
| 147 | |
| 41 #include "ipc/ipc_message_utils.h" | 148 #include "ipc/ipc_message_utils.h" |
| 42 | 149 #include "ipc/ipc_param_traits_macros.h" |
| 43 // In case a file includes several X_messages.h files, we don't want to get | |
| 44 // errors because each X_messages_internal.h file will define this. | |
| 45 #undef IPC_MESSAGE_START | |
| 46 | 150 |
| 47 #if defined(IPC_MESSAGE_IMPL) | 151 #if defined(IPC_MESSAGE_IMPL) |
| 48 #include "ipc/ipc_message_impl_macros.h" | 152 #include "ipc/ipc_message_impl_macros.h" |
| 49 #elif defined(IPC_MESSAGE_MACROS_LOG_ENABLED) | 153 #elif defined(IPC_MESSAGE_MACROS_LOG_ENABLED) |
| 50 | 154 |
| 51 #ifndef IPC_LOG_TABLE_CREATED | 155 #ifndef IPC_LOG_TABLE_CREATED |
| 52 #define IPC_LOG_TABLE_CREATED | 156 #define IPC_LOG_TABLE_CREATED |
| 53 | 157 |
| 54 #include "base/hash_tables.h" | 158 #include "base/hash_tables.h" |
| 55 | 159 |
| 56 typedef void (*LogFunction)(std::string* name, | 160 typedef void (*LogFunction)(std::string* name, |
| 57 const IPC::Message* msg, | 161 const IPC::Message* msg, |
| 58 std::string* params); | 162 std::string* params); |
| 59 | 163 |
| 60 typedef base::hash_map<uint32, LogFunction > LogFunctionMap; | 164 typedef base::hash_map<uint32, LogFunction > LogFunctionMap; |
| 61 LogFunctionMap g_log_function_mapping; | 165 LogFunctionMap g_log_function_mapping; |
| 62 | 166 |
| 63 #endif | 167 #endif // IPC_LOG_TABLE_CREATED |
| 64 | 168 |
| 65 | 169 |
| 66 #define IPC_MESSAGE_LOG(msg_class) \ | 170 #define IPC_MESSAGE_LOG(msg_class) \ |
| 67 class LoggerRegisterHelper##msg_class { \ | 171 class LoggerRegisterHelper##msg_class { \ |
| 68 public: \ | 172 public: \ |
| 69 LoggerRegisterHelper##msg_class() { \ | 173 LoggerRegisterHelper##msg_class() { \ |
| 70 g_log_function_mapping[msg_class::ID] = msg_class::Log; \ | 174 g_log_function_mapping[msg_class::ID] = msg_class::Log; \ |
| 71 } \ | 175 } \ |
| 72 }; \ | 176 }; \ |
| 73 LoggerRegisterHelper##msg_class g_LoggerRegisterHelper##msg_class; | 177 LoggerRegisterHelper##msg_class g_LoggerRegisterHelper##msg_class; |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 273 | 377 |
| 274 #define IPC_SYNC_MESSAGE_ROUTED5_2_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out) \ | 378 #define IPC_SYNC_MESSAGE_ROUTED5_2_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out) \ |
| 275 IPC_MESSAGE_LOG(msg_class) | 379 IPC_MESSAGE_LOG(msg_class) |
| 276 | 380 |
| 277 #define IPC_SYNC_MESSAGE_ROUTED5_3_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out, type3_out) \ | 381 #define IPC_SYNC_MESSAGE_ROUTED5_3_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out, type3_out) \ |
| 278 IPC_MESSAGE_LOG(msg_class) | 382 IPC_MESSAGE_LOG(msg_class) |
| 279 | 383 |
| 280 #define IPC_SYNC_MESSAGE_ROUTED5_4_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out, type3_out, type4_out) \ | 384 #define IPC_SYNC_MESSAGE_ROUTED5_4_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out, type3_out, type4_out) \ |
| 281 IPC_MESSAGE_LOG(msg_class) | 385 IPC_MESSAGE_LOG(msg_class) |
| 282 | 386 |
| 283 #else | 387 #else // defined(IPC_MESSAGE_MACROS_LOG_ENABLED) |
| 284 | 388 |
| 285 #define IPC_MESSAGE_CONTROL0_EXTRA(msg_class) | 389 #define IPC_MESSAGE_CONTROL0_EXTRA(msg_class) |
| 286 #define IPC_MESSAGE_CONTROL1_EXTRA(msg_class, type1) | 390 #define IPC_MESSAGE_CONTROL1_EXTRA(msg_class, type1) |
| 287 #define IPC_MESSAGE_CONTROL2_EXTRA(msg_class, type1, type2) | 391 #define IPC_MESSAGE_CONTROL2_EXTRA(msg_class, type1, type2) |
| 288 #define IPC_MESSAGE_CONTROL3_EXTRA(msg_class, type1, type2, type3) | 392 #define IPC_MESSAGE_CONTROL3_EXTRA(msg_class, type1, type2, type3) |
| 289 #define IPC_MESSAGE_CONTROL4_EXTRA(msg_class, type1, type2, type3, type4) | 393 #define IPC_MESSAGE_CONTROL4_EXTRA(msg_class, type1, type2, type3, type4) |
| 290 #define IPC_MESSAGE_CONTROL5_EXTRA(msg_class, type1, type2, type3, type4, type5) | 394 #define IPC_MESSAGE_CONTROL5_EXTRA(msg_class, type1, type2, type3, type4, type5) |
| 291 #define IPC_MESSAGE_ROUTED0_EXTRA(msg_class) | 395 #define IPC_MESSAGE_ROUTED0_EXTRA(msg_class) |
| 292 #define IPC_MESSAGE_ROUTED1_EXTRA(msg_class, type1) | 396 #define IPC_MESSAGE_ROUTED1_EXTRA(msg_class, type1) |
| 293 #define IPC_MESSAGE_ROUTED2_EXTRA(msg_class, type1, type2) | 397 #define IPC_MESSAGE_ROUTED2_EXTRA(msg_class, type1, type2) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 345 #define IPC_SYNC_MESSAGE_ROUTED4_1_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type1_out) | 449 #define IPC_SYNC_MESSAGE_ROUTED4_1_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type1_out) |
| 346 #define IPC_SYNC_MESSAGE_ROUTED4_2_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type1_out, type2_out) | 450 #define IPC_SYNC_MESSAGE_ROUTED4_2_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type1_out, type2_out) |
| 347 #define IPC_SYNC_MESSAGE_ROUTED4_3_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type1_out, type2_out, type3_out) | 451 #define IPC_SYNC_MESSAGE_ROUTED4_3_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type1_out, type2_out, type3_out) |
| 348 #define IPC_SYNC_MESSAGE_ROUTED4_4_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type1_out, type2_out, type3_out, type4_out) | 452 #define IPC_SYNC_MESSAGE_ROUTED4_4_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type1_out, type2_out, type3_out, type4_out) |
| 349 #define IPC_SYNC_MESSAGE_ROUTED5_0_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in) | 453 #define IPC_SYNC_MESSAGE_ROUTED5_0_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in) |
| 350 #define IPC_SYNC_MESSAGE_ROUTED5_1_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out) | 454 #define IPC_SYNC_MESSAGE_ROUTED5_1_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out) |
| 351 #define IPC_SYNC_MESSAGE_ROUTED5_2_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out) | 455 #define IPC_SYNC_MESSAGE_ROUTED5_2_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out) |
| 352 #define IPC_SYNC_MESSAGE_ROUTED5_3_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out, type3_out) | 456 #define IPC_SYNC_MESSAGE_ROUTED5_3_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out, type3_out) |
| 353 #define IPC_SYNC_MESSAGE_ROUTED5_4_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out, type4_out) | 457 #define IPC_SYNC_MESSAGE_ROUTED5_4_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out, type4_out) |
| 354 | 458 |
| 355 #endif | 459 #endif // defined(IPC_MESSAGE_MACROS_LOG_ENABLED) |
| 460 | |
| 461 // Macros for defining structs. May be subsequently redefined. | |
| 462 #define IPC_STRUCT_BEGIN(struct_name) \ | |
| 463 struct struct_name; \ | |
| 464 IPC_STRUCT_TRAITS_BEGIN(struct_name) \ | |
| 465 IPC_STRUCT_TRAITS_END() \ | |
| 466 struct struct_name : IPC::NoParams { \ | |
| 467 struct_name(); \ | |
| 468 ~struct_name(); | |
| 469 #define IPC_STRUCT_MEMBER(type, name) type name; | |
| 470 #define IPC_STRUCT_END() }; | |
| 356 | 471 |
| 357 // Note: we currently use __LINE__ to give unique IDs to messages within a file. | 472 // Note: we currently use __LINE__ to give unique IDs to messages within a file. |
| 358 // They're globally unique since each file defines its own IPC_MESSAGE_START. | 473 // They're globally unique since each file defines its own IPC_MESSAGE_START. |
| 359 // Ideally, we wouldn't use line numbers, but instead use the __COUNTER__ macro, | 474 // Ideally, we wouldn't use line numbers, but instead use the __COUNTER__ macro, |
| 360 // but it needs gcc 4.3 and xcode doesn't use it yet. When that happens, switch | 475 // but it needs gcc 4.3 and xcode doesn't use it yet. When that happens, switch |
| 361 // to it. | 476 // to it. |
| 362 | 477 |
| 363 #define IPC_MESSAGE_CONTROL0(msg_class) \ | 478 #define IPC_MESSAGE_CONTROL0(msg_class) \ |
| 364 class msg_class : public IPC::Message { \ | 479 class msg_class : public IPC::Message { \ |
| 365 public: \ | 480 public: \ |
| (...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1236 } \ | 1351 } \ |
| 1237 } | 1352 } |
| 1238 | 1353 |
| 1239 #define IPC_END_MESSAGE_MAP_EX() \ | 1354 #define IPC_END_MESSAGE_MAP_EX() \ |
| 1240 } \ | 1355 } \ |
| 1241 } | 1356 } |
| 1242 | 1357 |
| 1243 // This corresponds to an enum value from IPCMessageStart. | 1358 // This corresponds to an enum value from IPCMessageStart. |
| 1244 #define IPC_MESSAGE_CLASS(message) \ | 1359 #define IPC_MESSAGE_CLASS(message) \ |
| 1245 message.type() >> 16 | 1360 message.type() >> 16 |
| 1361 | |
| 1362 #endif // IPC_IPC_MESSAGE_MACROS_H_ | |
| 1363 | |
| 1364 // Clean up IPC_MESSAGE_START in this unguarded section in case some | |
| 1365 // XXX_message.h files fail do so themselves. | |
|
jam
2011/02/10 00:22:19
nit: since we'll only want to undef in this file,
| |
| 1366 #undef IPC_MESSAGE_START | |
| 1367 | |
| OLD | NEW |