Chromium Code Reviews| Index: ipc/ipc_message_macros.h |
| =================================================================== |
| --- ipc/ipc_message_macros.h (revision 74341) |
| +++ ipc/ipc_message_macros.h (working copy) |
| @@ -1,18 +1,126 @@ |
| -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // 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 XXX_messages.h file in a message generator .h file |
| +// |
| +// 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 before invoking message declatation macros: |
| +// #define IPC_MESSAGE_START XXXMsgStart |
| +// ( ... your macro invocations go here ... ) |
| +// |
| +// A message generator .h header file pulls in all other message-declaring |
| +// headers for a given component. It is included by a message generator |
| +// .cc file, which is where all the generated code will wind up. Typically, |
| +// you will use an existing generator (e.g. common_message_generator.cc and |
| +// common_message_generator.h in /chrome/common), but there are circumstances |
| +// where you may add a new one. |
| +// |
| +// In the rare cicrucmstances where you can't re-use an existing file, |
| +// your YYY_message_generator.cc file for a component YYY would contain |
| +// the following code: |
| +// // Get basic type definitions. |
| // #define IPC_MESSAGE_IMPL |
| -// #include "X_messages.h" |
| +// #include "path/to/YYY_message_generator.h" |
| +// // Generate constructors. |
| +// #include "ipc/struct_constructor_macros.h" |
| +// #include "path/to/YYY_message_generator.h" |
| +// // Generate destructors. |
| +// #include "ipc/struct_destructor_macros.h" |
| +// #include "path/to/YYY_message_generator.h" |
| +// namespace IPC { |
| +// // Generate param traits write methods. |
| +// #include "ipc/param_traits_write_macros.h" |
| +// #include "path/to/YYY_message_generator.h" |
| +// // Generate param traits read methods. |
| +// #include "ipc/param_traits_read_macros.h" |
| +// #include "path/to/YYY_message_generator.h" |
| +// // Generate param traits log methods. |
| +// #include "ipc/param_traits_log_macros.h" |
| +// #include "path/to/YYY_message_generator.h" |
| +// } // namespace IPC |
| // |
| +// 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 "XXX_messages.h" |
| +// (... implementation of traits not auto-generated ...) |
| +// |
| +// The XXX_messages.h file will be multiply-included by the |
| +// YYY_message_generator.cc file, so your XXX_messages file can't be |
| +// guarded in the usual manner. Ideally, there will be no need for any |
| +// inclusion guard, since the XXX_messages.h file should consist soley |
| +// of inclusions of other headers (which are self-guarding) and IPC |
| +// macros (which are multiply evaluating). |
| +// |
| +// Note that there is no #pragma once; doing so would mark the whole file |
| +// as being singly-included. Since your XXX_messages.h file is only |
| +// partially-guarded, care must be taken to ensure that it is only included |
| +// by other .cc files (and the YYY_message_generator.h file). Including an |
| +// XXX_messages.h file in some other .h file may result in duplicate |
| +// declarations and a compilation failure. |
| +// |
| +// One exception to the no-include guard rule occurs if you have type |
| +// definitions present in your XXX_messages.h file. Ideally, you'd move |
|
jam
2011/02/10 18:43:33
btw thinking more about this, I think typedefs in
|
| +// these to another (guarded) .h file and include this second .h in your |
| +// XXX_messages.h file. But if for some reason this can't be done, then |
| +// you will want to bracket the smallest possible section of your |
| +// XXX_messages.h file with an include guard macro. |
| +// |
| +// 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 YYY_message_generator.c is building the messages. In |
| +// addtion, due to the multiple inclusion restriction, these type will need |
| +// to be guarded. Follow a convention like: |
| +// #ifndef SOME_GUARD_MACRO |
|
jam
2011/02/10 18:43:33
nit: we don't really need an ifdef guard around fo
|
| +// #define SOME_GUARD_MACRO |
| +// class some_class; // One incomplete class declaration |
| +// class_some_other_class; // Another incomplete class declaration |
| +// #endif // SOME_GUARD_MACRO |
| +// #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 |
| +// (.. IPC macros using some_class and some_other_class ...) |
| +// |
| +// You will use IPC message macro invocations 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. |
| +// |
| +// Once the types have been declared / registered, message definitions follow. |
| // "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 +129,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 +145,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/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 +168,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 +388,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 +460,19 @@ |
| #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) |
| +// 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 +1362,11 @@ |
| // 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 so that the |
| +// XXX_messages.h files need not do so themselves. This makes the |
| +// XXX_messages.h files easier to write. |
| +#undef IPC_MESSAGE_START |
| + |