Chromium Code Reviews| Index: ipc/ipc_message_macros.h |
| =================================================================== |
| --- ipc/ipc_message_macros.h (revision 74010) |
| +++ ipc/ipc_message_macros.h (working copy) |
| @@ -1,18 +1,92 @@ |
| -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| +// 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
|
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| -// This header is meant to be included in multiple passes, hence no traditional |
| -// header guard. |
| +// Defining IPC Messages |
| // |
| -// In your XXX_messages_internal.h file, before defining any messages do: |
| -// #define IPC_MESSAGE_START XMsgStart |
| -// XMstStart value is from the IPCMessageStart enum in ipc_message_utils.h, and |
| -// needs to be unique for each different file. |
| -// In your XXX_messages.cc file, after all the includes for param types: |
| +// Your IPC messages will be defined by macros inside of an XXX_messages.h |
| +// header file. Most of the time, the system can automatically generate all |
| +// of messaging mechanism from these definitions, but sometimes some manual |
| +// coding is required. In these cases, you will also have an XXX_messages.cc |
| +// implemation file as well. |
| +// |
| +// The senders of your messages will include your XXX_messages.h file to |
| +// get the full set of definitions they need to send your messages. |
| +// |
| +// Each XXX_messages.h file must be registered with the IPC system. This |
| +// requires adding two things: |
| +// - An XXXMsgStart value to the IPCMessageStart enum in ipc_message_utils.h |
| +// - 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
|
| +// |
| +// The XXXMsgStart value is an enumeration that ensures uniqueness for |
| +// each different message file. Later, you will use this inside your |
| +// XXX_messages.h file to surrond your message declatation macros: |
| +// #define IPC_MESSAGE_START XXXMsgStart |
| +// ( ... your macro invocations go here ... ) |
| +// #undef IPC_MESSAGE_START |
| +// |
| +// The common_message_tree.h header pulls in all other message-declaring |
| +// headers through the mesage generation process. It is included by |
| +// common_message_generator.cc, which is where all the generated code |
| +// will wind up. In cases where manual generation is required, in your |
| +// XXX_messages.cc file, put the following after all the includes |
| +// for param types: |
| // #define IPC_MESSAGE_IMPL |
| -// #include "X_messages.h" |
| +// #include "XXXX_messages.h" |
| // |
| +// The XXX_messages file will be multiply-included by the |
| +// common_message_generator.cc file, so your XXX_messages file must be |
| +// specially guarded. There will be two sections of the file, one of |
| +// 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
|
| +// macros and is multiply-evaluated. The convention used is as follows: |
| +// #ifndef XXX_MESSAGES_H_ |
| +// #define XXX_MESSAGES_H_ |
| +// (... the type definition section goes here ...) |
| +// #endif // XXX_MESSAGES_H_ |
| +// #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
|
| +// #define XXX_MESSAGES_SECTION |
| +// #define IPC_MESSAGE_START XXXMsgStart |
| +// (... the message macro invocations go here ...) |
| +// #undef IPC_MESSAGE_START |
| +// #endif // IPC_MESSAGE_REINCLUDED || !defined(XXX_MESSAGES_SECTION) |
| +// Note that there is no #pragma once in either section; doing so |
| +// would mark the whole file as being singly-included. |
| +// |
| +// Inside the type definition section, you include all of the headers |
| +// required to define the types later used in your message macro invocations. |
| +// Sometimes is it convenient to provide an incomplete class type declaration |
| +// to avoid pulling in a long chain of headers. This is acceptable when |
| +// your XXX_messages.h header is being included by the message sending code, |
| +// but not when the common_message_generator.c is building the messages. In |
| +// these cases, follow a convention like: |
| +// class some_class; // One incomplete class declaration |
| +// class_some_other_class; // Another incomplete class declaration |
| +// #ifdef IPC_MESSAGE_IMPL |
| +// #inlcude "path/to/some_class.h" // Full class declaration |
| +// #inlcude "path/to/some_other_class.h" // Full class declaration |
| +// #endif // IPC_MESSAGE_IMPL |
| +// |
| +// Inside the message macro invocation secton, use macros for three things: |
| +// - New struct definitions for IPC |
| +// - Registering existing struct and enum definitions with IPC |
| +// - Defining the messages themselves |
| +// |
| +// New structs are defined with IPC_STRUCT_BEGIN(), IPC_STRUCT_MEMBER(), |
| +// IPC_STRUCT_END() family of macros. These cause the XXX_messages.h |
| +// to proclaim equivalent struct declarations for use by callers, as well |
| +// as later registering the type with the message generation. Note that |
| +// IPC_STRUCT_MEMBER() is only permitted inside matching calls to |
| +// IPC_STRUCT_BEGIN() / IPC_STRUCT_END(). |
| +// |
| +// Externally-defined structs are registered with IPC_STRUCT_TRAITS_BEGIN(), |
| +// IPC_STRUCT_TRAITS_MEMBER(), and IPC_STRUCT_TRAITS_END() macros. These |
| +// cause registration of the types with message generation only. Note that |
| +// IPC_STRUCT_TRAITS_MEMBER() is only permitted inside matching calls |
| +// to IPC_STRUCT_TRAITS_BEGIN() / IPC_STRUCT_TRAITS_END(). |
| +// |
| +// Enum types are registered with a single IPC_ENUM_TRAITS() macro. There |
| +// is no need to enumerate each value to the IPC mechanism. |
| +// |
| // "Sync" messages are just synchronous calls, the Send() call doesn't return |
| // until a reply comes back. Input parameters are first (const TYPE&), and |
| // To declare a sync message, use the IPC_SYNC_ macros. The numbers at the |
| @@ -21,7 +95,6 @@ |
| // The receiver's handler function will be |
| // void OnSyncMessageName(const type1& in1, type2* out1, type3* out2) |
| // |
| -// |
| // A caller can also send a synchronous message, while the receiver can respond |
| // at a later time. This is transparent from the sender's side. The receiver |
| // needs to use a different handler that takes in a IPC::Message* as the output |
| @@ -38,12 +111,13 @@ |
| // ViewHostMsg_SyncMessageName::WriteReplyParams(reply_msg, out1, out2); |
| // Send(reply_msg); |
| +#ifndef IPC_IPC_MESSAGE_MACROS_H_ |
| +#define IPC_IPC_MESSAGE_MACROS_H_ |
| +// Can use #pragma once all XXX_messages.h files clean up IPC_MESSAGE_START |
| + |
| #include "ipc/ipc_message_utils.h" |
| +#include "ipc/ipc_param_traits_macros.h" |
| -// In case a file includes several X_messages.h files, we don't want to get |
| -// errors because each X_messages_internal.h file will define this. |
| -#undef IPC_MESSAGE_START |
| - |
| #if defined(IPC_MESSAGE_IMPL) |
| #include "ipc/ipc_message_impl_macros.h" |
| #elif defined(IPC_MESSAGE_MACROS_LOG_ENABLED) |
| @@ -60,7 +134,7 @@ |
| typedef base::hash_map<uint32, LogFunction > LogFunctionMap; |
| LogFunctionMap g_log_function_mapping; |
| -#endif |
| +#endif // IPC_LOG_TABLE_CREATED |
| #define IPC_MESSAGE_LOG(msg_class) \ |
| @@ -280,7 +354,7 @@ |
| #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) \ |
| IPC_MESSAGE_LOG(msg_class) |
| -#else |
| +#else // defined(IPC_MESSAGE_MACROS_LOG_ENABLED) |
| #define IPC_MESSAGE_CONTROL0_EXTRA(msg_class) |
| #define IPC_MESSAGE_CONTROL1_EXTRA(msg_class, type1) |
| @@ -352,8 +426,22 @@ |
| #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) |
| #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) |
| -#endif |
| +#endif // defined(IPC_MESSAGE_MACROS_LOG_ENABLED) |
| +// Force IPC message guard convention single-include semantics. |
| +#define IPC_MESSAGE_REINCLUDE 0 |
| + |
| +// Macros for defining structs. May be subsequently redefined. |
| +#define IPC_STRUCT_BEGIN(struct_name) \ |
| + struct struct_name; \ |
| + IPC_STRUCT_TRAITS_BEGIN(struct_name) \ |
| + IPC_STRUCT_TRAITS_END() \ |
| + struct struct_name : IPC::NoParams { \ |
| + struct_name(); \ |
| + ~struct_name(); |
| +#define IPC_STRUCT_MEMBER(type, name) type name; |
| +#define IPC_STRUCT_END() }; |
| + |
| // Note: we currently use __LINE__ to give unique IDs to messages within a file. |
| // They're globally unique since each file defines its own IPC_MESSAGE_START. |
| // Ideally, we wouldn't use line numbers, but instead use the __COUNTER__ macro, |
| @@ -1243,3 +1331,9 @@ |
| // This corresponds to an enum value from IPCMessageStart. |
| #define IPC_MESSAGE_CLASS(message) \ |
| message.type() >> 16 |
| + |
| +#endif // IPC_IPC_MESSAGE_MACROS_H_ |
| + |
| + |
| +// Clean up IPC_MESSAGE_START in this unguarded section. |
|
jam
2011/02/07 23:34:55
I'm confused, why is this needed?
|
| +#undef IPC_MESSAGE_START |