OLD | NEW |
---|---|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2011 The Chromium Authors. All rights reserved. |
jam
2011/02/07 23:34:55
nit: while you're changing this, you can just make
| |
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 your XXX_messages.h file inside common_message_tree.h | |
jam
2011/02/07 23:34:55
nit: the ipc module shouldn't refer (even in comme
| |
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 // The common_message_tree.h header pulls in all other message-declaring | |
29 // headers through the mesage generation process. It is included by | |
30 // common_message_generator.cc, which is where all the generated code | |
31 // will wind up. In cases where manual generation is required, in your | |
32 // XXX_messages.cc file, put the following after all the includes | |
33 // for param types: | |
13 // #define IPC_MESSAGE_IMPL | 34 // #define IPC_MESSAGE_IMPL |
14 // #include "X_messages.h" | 35 // #include "XXXX_messages.h" |
36 // | |
37 // The XXX_messages file will be multiply-included by the | |
38 // common_message_generator.cc file, so your XXX_messages file must be | |
39 // specially guarded. There will be two sections of the file, one of | |
40 // which declares types and is singly-evalutead, and another which invokes | |
jam
2011/02/07 23:34:55
nit: evalutead
jam
2011/02/09 23:06:14
ping
| |
41 // macros and is multiply-evaluated. The convention used is as follows: | |
42 // #ifndef XXX_MESSAGES_H_ | |
43 // #define XXX_MESSAGES_H_ | |
44 // (... the type definition section goes here ...) | |
45 // #endif // XXX_MESSAGES_H_ | |
46 // #if IPC_MESSAGE_REINCLUDED || !defined(XXX_MESSAGES_SECTION) | |
jam
2011/02/07 23:34:55
out of curiosity: what would happen if we didn't h
| |
47 // #define XXX_MESSAGES_SECTION | |
48 // #define IPC_MESSAGE_START XXXMsgStart | |
49 // (... the message macro invocations go here ...) | |
50 // #undef IPC_MESSAGE_START | |
51 // #endif // IPC_MESSAGE_REINCLUDED || !defined(XXX_MESSAGES_SECTION) | |
52 // Note that there is no #pragma once in either section; doing so | |
53 // would mark the whole file as being singly-included. | |
54 // | |
55 // Inside the type definition section, you include all of the headers | |
56 // required to define the types later used in your message macro invocations. | |
57 // Sometimes is it convenient to provide an incomplete class type declaration | |
58 // to avoid pulling in a long chain of headers. This is acceptable when | |
59 // your XXX_messages.h header is being included by the message sending code, | |
60 // but not when the common_message_generator.c is building the messages. In | |
61 // these cases, follow a convention like: | |
62 // class some_class; // One incomplete class declaration | |
63 // class_some_other_class; // Another incomplete class declaration | |
64 // #ifdef IPC_MESSAGE_IMPL | |
65 // #inlcude "path/to/some_class.h" // Full class declaration | |
66 // #inlcude "path/to/some_other_class.h" // Full class declaration | |
67 // #endif // IPC_MESSAGE_IMPL | |
68 // | |
69 // Inside the message macro invocation secton, use macros for three things: | |
70 // - New struct definitions for IPC | |
71 // - Registering existing struct and enum definitions with IPC | |
72 // - Defining the messages themselves | |
73 // | |
74 // New structs are defined with IPC_STRUCT_BEGIN(), IPC_STRUCT_MEMBER(), | |
75 // IPC_STRUCT_END() family of macros. These cause the XXX_messages.h | |
76 // to proclaim equivalent struct declarations for use by callers, as well | |
77 // as later registering the type with the message generation. Note that | |
78 // IPC_STRUCT_MEMBER() is only permitted inside matching calls to | |
79 // IPC_STRUCT_BEGIN() / IPC_STRUCT_END(). | |
80 // | |
81 // Externally-defined structs are registered with IPC_STRUCT_TRAITS_BEGIN(), | |
82 // IPC_STRUCT_TRAITS_MEMBER(), and IPC_STRUCT_TRAITS_END() macros. These | |
83 // cause registration of the types with message generation only. Note that | |
84 // IPC_STRUCT_TRAITS_MEMBER() is only permitted inside matching calls | |
85 // to IPC_STRUCT_TRAITS_BEGIN() / IPC_STRUCT_TRAITS_END(). | |
86 // | |
87 // Enum types are registered with a single IPC_ENUM_TRAITS() macro. There | |
88 // is no need to enumerate each value to the IPC mechanism. | |
15 // | 89 // |
16 // "Sync" messages are just synchronous calls, the Send() call doesn't return | 90 // "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 | 91 // 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 | 92 // 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 | 93 // 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). | 94 // out). The caller does a Send([route id, ], in1, &out1, &out2). |
21 // The receiver's handler function will be | 95 // The receiver's handler function will be |
22 // void OnSyncMessageName(const type1& in1, type2* out1, type3* out2) | 96 // void OnSyncMessageName(const type1& in1, type2* out1, type3* out2) |
23 // | 97 // |
24 // | |
25 // A caller can also send a synchronous message, while the receiver can respond | 98 // 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 | 99 // 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 | 100 // 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. | 101 // type, stash the message, and when it has the data it can Send the message. |
29 // | 102 // |
30 // Use the IPC_MESSAGE_HANDLER_DELAY_REPLY macro instead of IPC_MESSAGE_HANDLER | 103 // Use the IPC_MESSAGE_HANDLER_DELAY_REPLY macro instead of IPC_MESSAGE_HANDLER |
31 // IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncMessageName, | 104 // IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncMessageName, |
32 // OnSyncMessageName) | 105 // OnSyncMessageName) |
33 // | 106 // |
34 // The handler function will look like: | 107 // The handler function will look like: |
35 // void OnSyncMessageName(const type1& in1, IPC::Message* reply_msg); | 108 // void OnSyncMessageName(const type1& in1, IPC::Message* reply_msg); |
36 // | 109 // |
37 // Receiver stashes the IPC::Message* pointer, and when it's ready, it does: | 110 // Receiver stashes the IPC::Message* pointer, and when it's ready, it does: |
38 // ViewHostMsg_SyncMessageName::WriteReplyParams(reply_msg, out1, out2); | 111 // ViewHostMsg_SyncMessageName::WriteReplyParams(reply_msg, out1, out2); |
39 // Send(reply_msg); | 112 // Send(reply_msg); |
40 | 113 |
114 #ifndef IPC_IPC_MESSAGE_MACROS_H_ | |
115 #define IPC_IPC_MESSAGE_MACROS_H_ | |
116 // Can use #pragma once all XXX_messages.h files clean up IPC_MESSAGE_START | |
117 | |
41 #include "ipc/ipc_message_utils.h" | 118 #include "ipc/ipc_message_utils.h" |
42 | 119 #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 | 120 |
47 #if defined(IPC_MESSAGE_IMPL) | 121 #if defined(IPC_MESSAGE_IMPL) |
48 #include "ipc/ipc_message_impl_macros.h" | 122 #include "ipc/ipc_message_impl_macros.h" |
49 #elif defined(IPC_MESSAGE_MACROS_LOG_ENABLED) | 123 #elif defined(IPC_MESSAGE_MACROS_LOG_ENABLED) |
50 | 124 |
51 #ifndef IPC_LOG_TABLE_CREATED | 125 #ifndef IPC_LOG_TABLE_CREATED |
52 #define IPC_LOG_TABLE_CREATED | 126 #define IPC_LOG_TABLE_CREATED |
53 | 127 |
54 #include "base/hash_tables.h" | 128 #include "base/hash_tables.h" |
55 | 129 |
56 typedef void (*LogFunction)(std::string* name, | 130 typedef void (*LogFunction)(std::string* name, |
57 const IPC::Message* msg, | 131 const IPC::Message* msg, |
58 std::string* params); | 132 std::string* params); |
59 | 133 |
60 typedef base::hash_map<uint32, LogFunction > LogFunctionMap; | 134 typedef base::hash_map<uint32, LogFunction > LogFunctionMap; |
61 LogFunctionMap g_log_function_mapping; | 135 LogFunctionMap g_log_function_mapping; |
62 | 136 |
63 #endif | 137 #endif // IPC_LOG_TABLE_CREATED |
64 | 138 |
65 | 139 |
66 #define IPC_MESSAGE_LOG(msg_class) \ | 140 #define IPC_MESSAGE_LOG(msg_class) \ |
67 class LoggerRegisterHelper##msg_class { \ | 141 class LoggerRegisterHelper##msg_class { \ |
68 public: \ | 142 public: \ |
69 LoggerRegisterHelper##msg_class() { \ | 143 LoggerRegisterHelper##msg_class() { \ |
70 g_log_function_mapping[msg_class::ID] = msg_class::Log; \ | 144 g_log_function_mapping[msg_class::ID] = msg_class::Log; \ |
71 } \ | 145 } \ |
72 }; \ | 146 }; \ |
73 LoggerRegisterHelper##msg_class g_LoggerRegisterHelper##msg_class; | 147 LoggerRegisterHelper##msg_class g_LoggerRegisterHelper##msg_class; |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
273 | 347 |
274 #define IPC_SYNC_MESSAGE_ROUTED5_2_EXTRA(msg_class, type1_in, type2_in, type3_in , type4_in, type5_in, type1_out, type2_out) \ | 348 #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) | 349 IPC_MESSAGE_LOG(msg_class) |
276 | 350 |
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) \ | 351 #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) | 352 IPC_MESSAGE_LOG(msg_class) |
279 | 353 |
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) \ | 354 #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) | 355 IPC_MESSAGE_LOG(msg_class) |
282 | 356 |
283 #else | 357 #else // defined(IPC_MESSAGE_MACROS_LOG_ENABLED) |
284 | 358 |
285 #define IPC_MESSAGE_CONTROL0_EXTRA(msg_class) | 359 #define IPC_MESSAGE_CONTROL0_EXTRA(msg_class) |
286 #define IPC_MESSAGE_CONTROL1_EXTRA(msg_class, type1) | 360 #define IPC_MESSAGE_CONTROL1_EXTRA(msg_class, type1) |
287 #define IPC_MESSAGE_CONTROL2_EXTRA(msg_class, type1, type2) | 361 #define IPC_MESSAGE_CONTROL2_EXTRA(msg_class, type1, type2) |
288 #define IPC_MESSAGE_CONTROL3_EXTRA(msg_class, type1, type2, type3) | 362 #define IPC_MESSAGE_CONTROL3_EXTRA(msg_class, type1, type2, type3) |
289 #define IPC_MESSAGE_CONTROL4_EXTRA(msg_class, type1, type2, type3, type4) | 363 #define IPC_MESSAGE_CONTROL4_EXTRA(msg_class, type1, type2, type3, type4) |
290 #define IPC_MESSAGE_CONTROL5_EXTRA(msg_class, type1, type2, type3, type4, type5) | 364 #define IPC_MESSAGE_CONTROL5_EXTRA(msg_class, type1, type2, type3, type4, type5) |
291 #define IPC_MESSAGE_ROUTED0_EXTRA(msg_class) | 365 #define IPC_MESSAGE_ROUTED0_EXTRA(msg_class) |
292 #define IPC_MESSAGE_ROUTED1_EXTRA(msg_class, type1) | 366 #define IPC_MESSAGE_ROUTED1_EXTRA(msg_class, type1) |
293 #define IPC_MESSAGE_ROUTED2_EXTRA(msg_class, type1, type2) | 367 #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) | 419 #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) | 420 #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) | 421 #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) | 422 #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) | 423 #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) | 424 #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) | 425 #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) | 426 #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) | 427 #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 | 428 |
355 #endif | 429 #endif // defined(IPC_MESSAGE_MACROS_LOG_ENABLED) |
430 | |
431 // Force IPC message guard convention single-include semantics. | |
432 #define IPC_MESSAGE_REINCLUDE 0 | |
433 | |
434 // Macros for defining structs. May be subsequently redefined. | |
435 #define IPC_STRUCT_BEGIN(struct_name) \ | |
436 struct struct_name; \ | |
437 IPC_STRUCT_TRAITS_BEGIN(struct_name) \ | |
438 IPC_STRUCT_TRAITS_END() \ | |
439 struct struct_name : IPC::NoParams { \ | |
440 struct_name(); \ | |
441 ~struct_name(); | |
442 #define IPC_STRUCT_MEMBER(type, name) type name; | |
443 #define IPC_STRUCT_END() }; | |
356 | 444 |
357 // Note: we currently use __LINE__ to give unique IDs to messages within a file. | 445 // 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. | 446 // 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, | 447 // 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 | 448 // but it needs gcc 4.3 and xcode doesn't use it yet. When that happens, switch |
361 // to it. | 449 // to it. |
362 | 450 |
363 #define IPC_MESSAGE_CONTROL0(msg_class) \ | 451 #define IPC_MESSAGE_CONTROL0(msg_class) \ |
364 class msg_class : public IPC::Message { \ | 452 class msg_class : public IPC::Message { \ |
365 public: \ | 453 public: \ |
(...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1236 } \ | 1324 } \ |
1237 } | 1325 } |
1238 | 1326 |
1239 #define IPC_END_MESSAGE_MAP_EX() \ | 1327 #define IPC_END_MESSAGE_MAP_EX() \ |
1240 } \ | 1328 } \ |
1241 } | 1329 } |
1242 | 1330 |
1243 // This corresponds to an enum value from IPCMessageStart. | 1331 // This corresponds to an enum value from IPCMessageStart. |
1244 #define IPC_MESSAGE_CLASS(message) \ | 1332 #define IPC_MESSAGE_CLASS(message) \ |
1245 message.type() >> 16 | 1333 message.type() >> 16 |
1334 | |
1335 #endif // IPC_IPC_MESSAGE_MACROS_H_ | |
1336 | |
1337 | |
1338 // Clean up IPC_MESSAGE_START in this unguarded section. | |
jam
2011/02/07 23:34:55
I'm confused, why is this needed?
| |
1339 #undef IPC_MESSAGE_START | |
OLD | NEW |