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 before invoking message declatation macros: |
| 24 // #define IPC_MESSAGE_START XXXMsgStart |
| 25 // ( ... your macro invocations go here ... ) |
| 26 // |
| 27 // Message Generator Files |
| 28 // |
| 29 // A message generator .h header file pulls in all other message-declaring |
| 30 // headers for a given component. It is included by a message generator |
| 31 // .cc file, which is where all the generated code will wind up. Typically, |
| 32 // you will use an existing generator (e.g. common_message_generator.cc and |
| 33 // common_message_generator.h in /chrome/common), but there are circumstances |
| 34 // where you may add a new one. |
| 35 // |
| 36 // In the rare cicrucmstances where you can't re-use an existing file, |
| 37 // your YYY_message_generator.cc file for a component YYY would contain |
| 38 // the following code: |
| 39 // // Get basic type definitions. |
13 // #define IPC_MESSAGE_IMPL | 40 // #define IPC_MESSAGE_IMPL |
14 // #include "X_messages.h" | 41 // #include "path/to/YYY_message_generator.h" |
| 42 // // Generate constructors. |
| 43 // #include "ipc/struct_constructor_macros.h" |
| 44 // #include "path/to/YYY_message_generator.h" |
| 45 // // Generate destructors. |
| 46 // #include "ipc/struct_destructor_macros.h" |
| 47 // #include "path/to/YYY_message_generator.h" |
| 48 // namespace IPC { |
| 49 // // Generate param traits write methods. |
| 50 // #include "ipc/param_traits_write_macros.h" |
| 51 // #include "path/to/YYY_message_generator.h" |
| 52 // // Generate param traits read methods. |
| 53 // #include "ipc/param_traits_read_macros.h" |
| 54 // #include "path/to/YYY_message_generator.h" |
| 55 // // Generate param traits log methods. |
| 56 // #include "ipc/param_traits_log_macros.h" |
| 57 // #include "path/to/YYY_message_generator.h" |
| 58 // } // namespace IPC |
15 // | 59 // |
| 60 // In cases where manual generation is required, in your XXX_messages.cc |
| 61 // file, put the following after all the includes for param types: |
| 62 // #define IPC_MESSAGE_IMPL |
| 63 // #include "XXX_messages.h" |
| 64 // (... implementation of traits not auto-generated ...) |
| 65 // |
| 66 // Multiple Inclusion |
| 67 // |
| 68 // The XXX_messages.h file will be multiply-included by the |
| 69 // YYY_message_generator.cc file, so your XXX_messages file can't be |
| 70 // guarded in the usual manner. Ideally, there will be no need for any |
| 71 // inclusion guard, since the XXX_messages.h file should consist soley |
| 72 // of inclusions of other headers (which are self-guarding) and IPC |
| 73 // macros (which are multiply evaluating). |
| 74 // |
| 75 // Note that there is no #pragma once either; doing so would mark the whole |
| 76 // file as being singly-included. Since your XXX_messages.h file is only |
| 77 // partially-guarded, care must be taken to ensure that it is only included |
| 78 // by other .cc files (and the YYY_message_generator.h file). Including an |
| 79 // XXX_messages.h file in some other .h file may result in duplicate |
| 80 // declarations and a compilation failure. |
| 81 // |
| 82 // Type Declarations |
| 83 // |
| 84 // It is generally a bad idea to have type definitions in a XXX_messages.h |
| 85 // file; most likely the typedef will then be used in the message, as opposed |
| 86 // to the struct iself. Later, an IPC message dispatcher wil need to call |
| 87 // a function taking that type, and that function is declared in some other |
| 88 // header. Thus, in order to get the type definition, the other header |
| 89 // would have to include the XXX_messages.h file, violating the rule above |
| 90 // about not including XXX_messages.h file in other .h files. |
| 91 // |
| 92 // One approach here is to move these type definitions to another (guarded) |
| 93 // .h file and include this second .h in your XXX_messages.h file. This |
| 94 // is still less than ideal, because the dispatched function would have to |
| 95 // redeclare the typedef or include this second header. This may be |
| 96 // reasonable in a few cases. |
| 97 // |
| 98 // Failing all of the above, then you will want to bracket the smallest |
| 99 // possible section of your XXX_messages.h file containing these types |
| 100 // with an include guard macro. Be aware that providing an incomplete |
| 101 // class type declaration to avoid pulling in a long chain of headers is |
| 102 // acceptable when your XXX_messages.h header is being included by the |
| 103 // message sending caller's code, but not when the YYY_message_generator.c |
| 104 // is building the messages. In addtion, due to the multiple inclusion |
| 105 // restriction, these type ought to be guarded. Follow a convention like: |
| 106 // #ifndef SOME_GUARD_MACRO |
| 107 // #define SOME_GUARD_MACRO |
| 108 // class some_class; // One incomplete class declaration |
| 109 // class_some_other_class; // Another incomplete class declaration |
| 110 // #endif // SOME_GUARD_MACRO |
| 111 // #ifdef IPC_MESSAGE_IMPL |
| 112 // #inlcude "path/to/some_class.h" // Full class declaration |
| 113 // #inlcude "path/to/some_other_class.h" // Full class declaration |
| 114 // #endif // IPC_MESSAGE_IMPL |
| 115 // (.. IPC macros using some_class and some_other_class ...) |
| 116 // |
| 117 // Macro Invocations |
| 118 // |
| 119 // You will use IPC message macro invocations for three things: |
| 120 // - New struct definitions for IPC |
| 121 // - Registering existing struct and enum definitions with IPC |
| 122 // - Defining the messages themselves |
| 123 // |
| 124 // New structs are defined with IPC_STRUCT_BEGIN(), IPC_STRUCT_MEMBER(), |
| 125 // IPC_STRUCT_END() family of macros. These cause the XXX_messages.h |
| 126 // to proclaim equivalent struct declarations for use by callers, as well |
| 127 // as later registering the type with the message generation. Note that |
| 128 // IPC_STRUCT_MEMBER() is only permitted inside matching calls to |
| 129 // IPC_STRUCT_BEGIN() / IPC_STRUCT_END(). |
| 130 // |
| 131 // Externally-defined structs are registered with IPC_STRUCT_TRAITS_BEGIN(), |
| 132 // IPC_STRUCT_TRAITS_MEMBER(), and IPC_STRUCT_TRAITS_END() macros. These |
| 133 // cause registration of the types with message generation only. Note that |
| 134 // IPC_STRUCT_TRAITS_MEMBER() is only permitted inside matching calls |
| 135 // to IPC_STRUCT_TRAITS_BEGIN() / IPC_STRUCT_TRAITS_END(). |
| 136 // |
| 137 // Enum types are registered with a single IPC_ENUM_TRAITS() macro. There |
| 138 // is no need to enumerate each value to the IPC mechanism. |
| 139 // |
| 140 // Once the types have been declared / registered, message definitions follow. |
16 // "Sync" messages are just synchronous calls, the Send() call doesn't return | 141 // "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 | 142 // 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 | 143 // 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 | 144 // 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). | 145 // out). The caller does a Send([route id, ], in1, &out1, &out2). |
21 // The receiver's handler function will be | 146 // The receiver's handler function will be |
22 // void OnSyncMessageName(const type1& in1, type2* out1, type3* out2) | 147 // void OnSyncMessageName(const type1& in1, type2* out1, type3* out2) |
23 // | 148 // |
24 // | |
25 // A caller can also send a synchronous message, while the receiver can respond | 149 // 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 | 150 // 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 | 151 // 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. | 152 // type, stash the message, and when it has the data it can Send the message. |
29 // | 153 // |
30 // Use the IPC_MESSAGE_HANDLER_DELAY_REPLY macro instead of IPC_MESSAGE_HANDLER | 154 // Use the IPC_MESSAGE_HANDLER_DELAY_REPLY macro instead of IPC_MESSAGE_HANDLER |
31 // IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncMessageName, | 155 // IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncMessageName, |
32 // OnSyncMessageName) | 156 // OnSyncMessageName) |
33 // | 157 // |
34 // The handler function will look like: | 158 // The handler function will look like: |
35 // void OnSyncMessageName(const type1& in1, IPC::Message* reply_msg); | 159 // void OnSyncMessageName(const type1& in1, IPC::Message* reply_msg); |
36 // | 160 // |
37 // Receiver stashes the IPC::Message* pointer, and when it's ready, it does: | 161 // Receiver stashes the IPC::Message* pointer, and when it's ready, it does: |
38 // ViewHostMsg_SyncMessageName::WriteReplyParams(reply_msg, out1, out2); | 162 // ViewHostMsg_SyncMessageName::WriteReplyParams(reply_msg, out1, out2); |
39 // Send(reply_msg); | 163 // Send(reply_msg); |
40 | 164 |
| 165 #ifndef IPC_IPC_MESSAGE_MACROS_H_ |
| 166 #define IPC_IPC_MESSAGE_MACROS_H_ |
| 167 // Can use #pragma once all XXX_messages.h files clean up IPC_MESSAGE_START |
| 168 |
41 #include "ipc/ipc_message_utils.h" | 169 #include "ipc/ipc_message_utils.h" |
42 | 170 #include "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 | 171 |
47 #if defined(IPC_MESSAGE_IMPL) | 172 #if defined(IPC_MESSAGE_IMPL) |
48 #include "ipc/ipc_message_impl_macros.h" | 173 #include "ipc/ipc_message_impl_macros.h" |
49 #elif defined(IPC_MESSAGE_MACROS_LOG_ENABLED) | 174 #elif defined(IPC_MESSAGE_MACROS_LOG_ENABLED) |
50 | 175 |
51 #ifndef IPC_LOG_TABLE_CREATED | 176 #ifndef IPC_LOG_TABLE_CREATED |
52 #define IPC_LOG_TABLE_CREATED | 177 #define IPC_LOG_TABLE_CREATED |
53 | 178 |
54 #include "base/hash_tables.h" | 179 #include "base/hash_tables.h" |
55 | 180 |
56 typedef void (*LogFunction)(std::string* name, | 181 typedef void (*LogFunction)(std::string* name, |
57 const IPC::Message* msg, | 182 const IPC::Message* msg, |
58 std::string* params); | 183 std::string* params); |
59 | 184 |
60 typedef base::hash_map<uint32, LogFunction > LogFunctionMap; | 185 typedef base::hash_map<uint32, LogFunction > LogFunctionMap; |
61 LogFunctionMap g_log_function_mapping; | 186 LogFunctionMap g_log_function_mapping; |
62 | 187 |
63 #endif | 188 #endif // IPC_LOG_TABLE_CREATED |
64 | 189 |
65 | 190 |
66 #define IPC_MESSAGE_LOG(msg_class) \ | 191 #define IPC_MESSAGE_LOG(msg_class) \ |
67 class LoggerRegisterHelper##msg_class { \ | 192 class LoggerRegisterHelper##msg_class { \ |
68 public: \ | 193 public: \ |
69 LoggerRegisterHelper##msg_class() { \ | 194 LoggerRegisterHelper##msg_class() { \ |
70 g_log_function_mapping[msg_class::ID] = msg_class::Log; \ | 195 g_log_function_mapping[msg_class::ID] = msg_class::Log; \ |
71 } \ | 196 } \ |
72 }; \ | 197 }; \ |
73 LoggerRegisterHelper##msg_class g_LoggerRegisterHelper##msg_class; | 198 LoggerRegisterHelper##msg_class g_LoggerRegisterHelper##msg_class; |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 | 398 |
274 #define IPC_SYNC_MESSAGE_ROUTED5_2_EXTRA(msg_class, type1_in, type2_in, type3_in
, type4_in, type5_in, type1_out, type2_out) \ | 399 #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) | 400 IPC_MESSAGE_LOG(msg_class) |
276 | 401 |
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) \ | 402 #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) | 403 IPC_MESSAGE_LOG(msg_class) |
279 | 404 |
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) \ | 405 #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) | 406 IPC_MESSAGE_LOG(msg_class) |
282 | 407 |
283 #else | 408 #else // defined(IPC_MESSAGE_MACROS_LOG_ENABLED) |
284 | 409 |
285 #define IPC_MESSAGE_CONTROL0_EXTRA(msg_class) | 410 #define IPC_MESSAGE_CONTROL0_EXTRA(msg_class) |
286 #define IPC_MESSAGE_CONTROL1_EXTRA(msg_class, type1) | 411 #define IPC_MESSAGE_CONTROL1_EXTRA(msg_class, type1) |
287 #define IPC_MESSAGE_CONTROL2_EXTRA(msg_class, type1, type2) | 412 #define IPC_MESSAGE_CONTROL2_EXTRA(msg_class, type1, type2) |
288 #define IPC_MESSAGE_CONTROL3_EXTRA(msg_class, type1, type2, type3) | 413 #define IPC_MESSAGE_CONTROL3_EXTRA(msg_class, type1, type2, type3) |
289 #define IPC_MESSAGE_CONTROL4_EXTRA(msg_class, type1, type2, type3, type4) | 414 #define IPC_MESSAGE_CONTROL4_EXTRA(msg_class, type1, type2, type3, type4) |
290 #define IPC_MESSAGE_CONTROL5_EXTRA(msg_class, type1, type2, type3, type4, type5) | 415 #define IPC_MESSAGE_CONTROL5_EXTRA(msg_class, type1, type2, type3, type4, type5) |
291 #define IPC_MESSAGE_ROUTED0_EXTRA(msg_class) | 416 #define IPC_MESSAGE_ROUTED0_EXTRA(msg_class) |
292 #define IPC_MESSAGE_ROUTED1_EXTRA(msg_class, type1) | 417 #define IPC_MESSAGE_ROUTED1_EXTRA(msg_class, type1) |
293 #define IPC_MESSAGE_ROUTED2_EXTRA(msg_class, type1, type2) | 418 #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) | 470 #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) | 471 #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) | 472 #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) | 473 #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) | 474 #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) | 475 #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) | 476 #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) | 477 #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) | 478 #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 | 479 |
355 #endif | 480 #endif // defined(IPC_MESSAGE_MACROS_LOG_ENABLED) |
| 481 |
| 482 // Macros for defining structs. May be subsequently redefined. |
| 483 #define IPC_STRUCT_BEGIN(struct_name) \ |
| 484 struct struct_name; \ |
| 485 IPC_STRUCT_TRAITS_BEGIN(struct_name) \ |
| 486 IPC_STRUCT_TRAITS_END() \ |
| 487 struct struct_name : IPC::NoParams { \ |
| 488 struct_name(); \ |
| 489 ~struct_name(); |
| 490 #define IPC_STRUCT_MEMBER(type, name) type name; |
| 491 #define IPC_STRUCT_END() }; |
356 | 492 |
357 // Note: we currently use __LINE__ to give unique IDs to messages within a file. | 493 // 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. | 494 // 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, | 495 // 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 | 496 // but it needs gcc 4.3 and xcode doesn't use it yet. When that happens, switch |
361 // to it. | 497 // to it. |
362 | 498 |
363 #define IPC_MESSAGE_CONTROL0(msg_class) \ | 499 #define IPC_MESSAGE_CONTROL0(msg_class) \ |
364 class msg_class : public IPC::Message { \ | 500 class msg_class : public IPC::Message { \ |
365 public: \ | 501 public: \ |
(...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 } \ | 1372 } \ |
1237 } | 1373 } |
1238 | 1374 |
1239 #define IPC_END_MESSAGE_MAP_EX() \ | 1375 #define IPC_END_MESSAGE_MAP_EX() \ |
1240 } \ | 1376 } \ |
1241 } | 1377 } |
1242 | 1378 |
1243 // This corresponds to an enum value from IPCMessageStart. | 1379 // This corresponds to an enum value from IPCMessageStart. |
1244 #define IPC_MESSAGE_CLASS(message) \ | 1380 #define IPC_MESSAGE_CLASS(message) \ |
1245 message.type() >> 16 | 1381 message.type() >> 16 |
| 1382 |
| 1383 #endif // IPC_IPC_MESSAGE_MACROS_H_ |
| 1384 |
| 1385 // Clean up IPC_MESSAGE_START in this unguarded section so that the |
| 1386 // XXX_messages.h files need not do so themselves. This makes the |
| 1387 // XXX_messages.h files easier to write. |
| 1388 #undef IPC_MESSAGE_START |
| 1389 |
OLD | NEW |