Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 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 // Defining IPC Messages | 5 // Defining IPC Messages |
| 6 // | 6 // |
| 7 // Your IPC messages will be defined by macros inside of an XXX_messages.h | 7 // Your IPC messages will be defined by macros inside of an XXX_messages.h |
| 8 // header file. Most of the time, the system can automatically generate all | 8 // header file. Most of the time, the system can automatically generate all |
| 9 // of messaging mechanism from these definitions, but sometimes some manual | 9 // of messaging mechanism from these definitions, but sometimes some manual |
| 10 // coding is required. In these cases, you will also have an XXX_messages.cc | 10 // coding is required. In these cases, you will also have an XXX_messages.cc |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 // each different message file. Later, you will use this inside your | 22 // each different message file. Later, you will use this inside your |
| 23 // XXX_messages.h file before invoking message declatation macros: | 23 // XXX_messages.h file before invoking message declatation macros: |
| 24 // #define IPC_MESSAGE_START XXXMsgStart | 24 // #define IPC_MESSAGE_START XXXMsgStart |
| 25 // ( ... your macro invocations go here ... ) | 25 // ( ... your macro invocations go here ... ) |
| 26 // | 26 // |
| 27 // Message Generator Files | 27 // Message Generator Files |
| 28 // | 28 // |
| 29 // A message generator .h header file pulls in all other message-declaring | 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 | 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, | 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 | 32 // you will use an existing generator (e.g. common_message_generator.cc |
| 33 // common_message_generator.h in /chrome/common), but there are circumstances | 33 // in /chrome/common), but there are circumstances where you may add a |
| 34 // where you may add a new one. | 34 // new one. |
| 35 // | 35 // |
| 36 // In the rare cicrucmstances where you can't re-use an existing file, | 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 | 37 // your YYY_message_generator.cc file for a component YYY would contain |
| 38 // the following code: | 38 // the following code: |
|
jam
2011/03/11 23:19:53
nit: it might be easier for people to copy it if C
| |
| 39 // // Get basic type definitions. | 39 // // Get basic type definitions. |
| 40 // #define IPC_MESSAGE_IMPL | 40 // #define IPC_MESSAGE_IMPL |
| 41 // #include "path/to/YYY_message_generator.h" | 41 // #include "path/to/YYY_message_generator.h" |
| 42 // // Generate constructors. | 42 // // Generate constructors. |
| 43 // #include "ipc/struct_constructor_macros.h" | 43 // #include "ipc/struct_constructor_macros.h" |
| 44 // #include "path/to/YYY_message_generator.h" | 44 // #include "path/to/YYY_message_generator.h" |
| 45 // // Generate destructors. | 45 // // Generate destructors. |
| 46 // #include "ipc/struct_destructor_macros.h" | 46 // #include "ipc/struct_destructor_macros.h" |
| 47 // #include "path/to/YYY_message_generator.h" | 47 // #include "path/to/YYY_message_generator.h" |
| 48 // namespace IPC { | |
| 49 // // Generate param traits write methods. | 48 // // Generate param traits write methods. |
| 50 // #include "ipc/param_traits_write_macros.h" | 49 // #include "ipc/param_traits_write_macros.h" |
| 50 // namespace IPC { | |
| 51 // #include "path/to/YYY_message_generator.h" | 51 // #include "path/to/YYY_message_generator.h" |
| 52 // } // namespace IPC | |
| 52 // // Generate param traits read methods. | 53 // // Generate param traits read methods. |
| 53 // #include "ipc/param_traits_read_macros.h" | 54 // #include "ipc/param_traits_read_macros.h" |
| 55 // namespace IPC { | |
| 54 // #include "path/to/YYY_message_generator.h" | 56 // #include "path/to/YYY_message_generator.h" |
| 57 // } // namespace IPC | |
| 55 // // Generate param traits log methods. | 58 // // Generate param traits log methods. |
| 56 // #include "ipc/param_traits_log_macros.h" | 59 // #include "ipc/param_traits_log_macros.h" |
| 60 // namespace IPC { | |
| 57 // #include "path/to/YYY_message_generator.h" | 61 // #include "path/to/YYY_message_generator.h" |
| 58 // } // namespace IPC | 62 // } // namespace IPC |
| 59 // | 63 // |
| 60 // In cases where manual generation is required, in your XXX_messages.cc | 64 // In cases where manual generation is required, in your XXX_messages.cc |
| 61 // file, put the following after all the includes for param types: | 65 // file, put the following after all the includes for param types: |
| 62 // #define IPC_MESSAGE_IMPL | 66 // #define IPC_MESSAGE_IMPL |
| 63 // #include "XXX_messages.h" | 67 // #include "XXX_messages.h" |
| 64 // (... implementation of traits not auto-generated ...) | 68 // (... implementation of traits not auto-generated ...) |
| 65 // | 69 // |
| 66 // Multiple Inclusion | 70 // Multiple Inclusion |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 struct struct_name; \ | 183 struct struct_name; \ |
| 180 IPC_STRUCT_TRAITS_BEGIN(struct_name) \ | 184 IPC_STRUCT_TRAITS_BEGIN(struct_name) \ |
| 181 IPC_STRUCT_TRAITS_END() \ | 185 IPC_STRUCT_TRAITS_END() \ |
| 182 struct struct_name : IPC::NoParams { \ | 186 struct struct_name : IPC::NoParams { \ |
| 183 struct_name(); \ | 187 struct_name(); \ |
| 184 ~struct_name(); | 188 ~struct_name(); |
| 185 #define IPC_STRUCT_MEMBER(type, name) type name; | 189 #define IPC_STRUCT_MEMBER(type, name) type name; |
| 186 #define IPC_STRUCT_END() }; | 190 #define IPC_STRUCT_END() }; |
| 187 | 191 |
| 188 // Message macros collect specific numbers of arguments and funnel them into | 192 // Message macros collect specific numbers of arguments and funnel them into |
| 189 // the common message generation macro. | 193 // the common message generation macro. These should never be redefined. |
| 190 #define IPC_MESSAGE_CONTROL0(msg_class) \ | 194 #define IPC_MESSAGE_CONTROL0(msg_class) \ |
| 191 IPC_MESSAGE_DECL(EMPTY, CONTROL, msg_class, 0, 0, (), ()) | 195 IPC_MESSAGE_DECL(EMPTY, CONTROL, msg_class, 0, 0, (), ()) |
| 192 | 196 |
| 193 #define IPC_MESSAGE_CONTROL1(msg_class, type1) \ | 197 #define IPC_MESSAGE_CONTROL1(msg_class, type1) \ |
| 194 IPC_MESSAGE_DECL(ASYNC, CONTROL, msg_class, 1, 0, (type1), ()) | 198 IPC_MESSAGE_DECL(ASYNC, CONTROL, msg_class, 1, 0, (type1), ()) |
| 195 | 199 |
| 196 #define IPC_MESSAGE_CONTROL2(msg_class, type1, type2) \ | 200 #define IPC_MESSAGE_CONTROL2(msg_class, type1, type2) \ |
| 197 IPC_MESSAGE_DECL(ASYNC, CONTROL, msg_class, 2, 0, (type1, type2), ()) | 201 IPC_MESSAGE_DECL(ASYNC, CONTROL, msg_class, 2, 0, (type1, type2), ()) |
| 198 | 202 |
| 199 #define IPC_MESSAGE_CONTROL3(msg_class, type1, type2, type3) \ | 203 #define IPC_MESSAGE_CONTROL3(msg_class, type1, type2, type3) \ |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 | 403 |
| 400 #define IPC_SYNC_MESSAGE_ROUTED5_3(msg_class, type1_in, type2_in, type3_in, type 4_in, type5_in, type1_out, type2_out, type3_out) \ | 404 #define IPC_SYNC_MESSAGE_ROUTED5_3(msg_class, type1_in, type2_in, type3_in, type 4_in, type5_in, type1_out, type2_out, type3_out) \ |
| 401 IPC_MESSAGE_DECL(SYNC, ROUTED, msg_class, 5, 3, (type1_in, type2_in, type3_in, type4_in, type5_in), (type1_out, type2_out, type3_out)) | 405 IPC_MESSAGE_DECL(SYNC, ROUTED, msg_class, 5, 3, (type1_in, type2_in, type3_in, type4_in, type5_in), (type1_out, type2_out, type3_out)) |
| 402 | 406 |
| 403 #define IPC_SYNC_MESSAGE_ROUTED5_4(msg_class, type1_in, type2_in, type3_in, type 4_in, type5_in, type1_out, type2_out, type3_out, type4_out) \ | 407 #define IPC_SYNC_MESSAGE_ROUTED5_4(msg_class, type1_in, type2_in, type3_in, type 4_in, type5_in, type1_out, type2_out, type3_out, type4_out) \ |
| 404 IPC_MESSAGE_DECL(SYNC, ROUTED, msg_class, 5, 4, (type1_in, type2_in, type3_in, type4_in, type5_in), (type1_out, type2_out, type3_out, type4_out)) | 408 IPC_MESSAGE_DECL(SYNC, ROUTED, msg_class, 5, 4, (type1_in, type2_in, type3_in, type4_in, type5_in), (type1_out, type2_out, type3_out, type4_out)) |
| 405 | 409 |
| 406 // Common message macro which dispatches into one of the 6 (sync x kind) | 410 // Common message macro which dispatches into one of the 6 (sync x kind) |
| 407 // routines. There is a way that these 6 cases can be lumped together, | 411 // routines. There is a way that these 6 cases can be lumped together, |
| 408 // but the macros get very complicated in that case. | 412 // but the macros get very complicated in that case. |
| 409 // Note: we currently use __LINE__ to give unique IDs to messages within | 413 // Note: intended be redefined to generate other information. |
| 410 // a file. They're globally unique since each file defines its own | |
| 411 // IPC_MESSAGE_START. Ideally, we wouldn't use line numbers (a possibility | |
| 412 // is to instead use the __COUNTER__ macro, but it needs gcc 4.3 and xcode | |
| 413 // doesn't use it yet). | |
| 414 #define IPC_MESSAGE_DECL(sync, kind, msg_class, \ | 414 #define IPC_MESSAGE_DECL(sync, kind, msg_class, \ |
| 415 in_cnt, out_cnt, in_list, out_list) \ | 415 in_cnt, out_cnt, in_list, out_list) \ |
| 416 IPC_##sync##_##kind##_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ | 416 IPC_##sync##_##kind##_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ |
| 417 IPC_MESSAGE_EXTRA(sync, kind, msg_class, in_cnt, out_cnt, in_list, out_list) | 417 IPC_MESSAGE_EXTRA(sync, kind, msg_class, in_cnt, out_cnt, in_list, out_list) |
| 418 | 418 |
| 419 #define IPC_EMPTY_CONTROL_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ | 419 #define IPC_EMPTY_CONTROL_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ |
| 420 class msg_class : public IPC::Message { \ | 420 class msg_class : public IPC::Message { \ |
| 421 public: \ | 421 public: \ |
| 422 enum { ID = (IPC_MESSAGE_START << 16) + __LINE__ }; \ | 422 enum { ID = IPC_MESSAGE_ID() }; \ |
| 423 msg_class() : IPC::Message(MSG_ROUTING_CONTROL, ID, PRIORITY_NORMAL) {} \ | 423 msg_class() : IPC::Message(MSG_ROUTING_CONTROL, ID, PRIORITY_NORMAL) {} \ |
| 424 }; | 424 }; |
| 425 | 425 |
| 426 #define IPC_EMPTY_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ | 426 #define IPC_EMPTY_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ |
| 427 class msg_class : public IPC::Message { \ | 427 class msg_class : public IPC::Message { \ |
| 428 public: \ | 428 public: \ |
| 429 enum { ID = (IPC_MESSAGE_START << 16) + __LINE__ }; \ | 429 enum { ID = IPC_MESSAGE_ID() }; \ |
| 430 msg_class(int32 routing_id) \ | 430 msg_class(int32 routing_id) \ |
| 431 : IPC::Message(routing_id, ID, PRIORITY_NORMAL) {} \ | 431 : IPC::Message(routing_id, ID, PRIORITY_NORMAL) {} \ |
| 432 }; | 432 }; |
| 433 | 433 |
| 434 #define IPC_ASYNC_CONTROL_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ | 434 #define IPC_ASYNC_CONTROL_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ |
| 435 class msg_class : \ | 435 class msg_class : \ |
| 436 public IPC::MessageWithTuple<IPC_TUPLE_IN_##in_cnt in_list> { \ | 436 public IPC::MessageWithTuple<IPC_TUPLE_IN_##in_cnt in_list> { \ |
| 437 public: \ | 437 public: \ |
| 438 enum { ID = (IPC_MESSAGE_START << 16) + __LINE__ }; \ | 438 enum { ID = IPC_MESSAGE_ID() }; \ |
| 439 msg_class(IPC_TYPE_IN_##in_cnt in_list); \ | 439 msg_class(IPC_TYPE_IN_##in_cnt in_list); \ |
| 440 ~msg_class(); \ | 440 ~msg_class(); \ |
| 441 static void Log(std::string* name, const Message* msg, std::string* l); \ | 441 static void Log(std::string* name, const Message* msg, std::string* l); \ |
| 442 }; | 442 }; |
| 443 | 443 |
| 444 #define IPC_ASYNC_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ | 444 #define IPC_ASYNC_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ |
| 445 class msg_class : \ | 445 class msg_class : \ |
| 446 public IPC::MessageWithTuple<IPC_TUPLE_IN_##in_cnt in_list> { \ | 446 public IPC::MessageWithTuple<IPC_TUPLE_IN_##in_cnt in_list> { \ |
| 447 public: \ | 447 public: \ |
| 448 enum { ID = (IPC_MESSAGE_START << 16) + __LINE__ }; \ | 448 enum { ID = IPC_MESSAGE_ID() }; \ |
| 449 msg_class(int32 routing_id IPC_COMMA_##in_cnt \ | 449 msg_class(int32 routing_id IPC_COMMA_##in_cnt \ |
| 450 IPC_TYPE_IN_##in_cnt in_list); \ | 450 IPC_TYPE_IN_##in_cnt in_list); \ |
| 451 ~msg_class(); \ | 451 ~msg_class(); \ |
| 452 static void Log(std::string* name, const Message* msg, std::string* l); \ | 452 static void Log(std::string* name, const Message* msg, std::string* l); \ |
| 453 }; | 453 }; |
| 454 | 454 |
| 455 #define IPC_SYNC_CONTROL_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ | 455 #define IPC_SYNC_CONTROL_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ |
| 456 class msg_class : \ | 456 class msg_class : \ |
| 457 public IPC::MessageWithReply<IPC_TUPLE_IN_##in_cnt in_list, \ | 457 public IPC::MessageWithReply<IPC_TUPLE_IN_##in_cnt in_list, \ |
| 458 IPC_TUPLE_OUT_##out_cnt out_list> { \ | 458 IPC_TUPLE_OUT_##out_cnt out_list> { \ |
| 459 public: \ | 459 public: \ |
| 460 enum { ID = (IPC_MESSAGE_START << 16) + __LINE__ }; \ | 460 enum { ID = IPC_MESSAGE_ID() }; \ |
| 461 msg_class(IPC_TYPE_IN_##in_cnt in_list \ | 461 msg_class(IPC_TYPE_IN_##in_cnt in_list \ |
| 462 IPC_COMMA_AND_##in_cnt(IPC_COMMA_##out_cnt) \ | 462 IPC_COMMA_AND_##in_cnt(IPC_COMMA_##out_cnt) \ |
| 463 IPC_TYPE_OUT_##out_cnt out_list); \ | 463 IPC_TYPE_OUT_##out_cnt out_list); \ |
| 464 ~msg_class(); \ | 464 ~msg_class(); \ |
| 465 static void Log(std::string* name, const Message* msg, std::string* l); \ | 465 static void Log(std::string* name, const Message* msg, std::string* l); \ |
| 466 }; | 466 }; |
| 467 | 467 |
| 468 #define IPC_SYNC_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ | 468 #define IPC_SYNC_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \ |
| 469 class msg_class : \ | 469 class msg_class : \ |
| 470 public IPC::MessageWithReply<IPC_TUPLE_IN_##in_cnt in_list, \ | 470 public IPC::MessageWithReply<IPC_TUPLE_IN_##in_cnt in_list, \ |
| 471 IPC_TUPLE_OUT_##out_cnt out_list> { \ | 471 IPC_TUPLE_OUT_##out_cnt out_list> { \ |
| 472 public: \ | 472 public: \ |
| 473 enum { ID = (IPC_MESSAGE_START << 16) + __LINE__ }; \ | 473 enum { ID = IPC_MESSAGE_ID() }; \ |
| 474 msg_class(int32 routing_id \ | 474 msg_class(int32 routing_id \ |
| 475 IPC_COMMA_OR_##in_cnt(IPC_COMMA_##out_cnt) \ | 475 IPC_COMMA_OR_##in_cnt(IPC_COMMA_##out_cnt) \ |
| 476 IPC_TYPE_IN_##in_cnt in_list \ | 476 IPC_TYPE_IN_##in_cnt in_list \ |
| 477 IPC_COMMA_AND_##in_cnt(IPC_COMMA_##out_cnt) \ | 477 IPC_COMMA_AND_##in_cnt(IPC_COMMA_##out_cnt) \ |
| 478 IPC_TYPE_OUT_##out_cnt out_list); \ | 478 IPC_TYPE_OUT_##out_cnt out_list); \ |
| 479 ~msg_class(); \ | 479 ~msg_class(); \ |
| 480 static void Log(std::string* name, const Message* msg, std::string* l); \ | 480 static void Log(std::string* name, const Message* msg, std::string* l); \ |
| 481 }; | 481 }; |
| 482 | 482 |
| 483 #if defined(IPC_MESSAGE_IMPL) | 483 #if defined(IPC_MESSAGE_IMPL) |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 664 #define IPC_COMMA_AND_4(x) x | 664 #define IPC_COMMA_AND_4(x) x |
| 665 #define IPC_COMMA_AND_5(x) x | 665 #define IPC_COMMA_AND_5(x) x |
| 666 | 666 |
| 667 #define IPC_COMMA_OR_0(x) x | 667 #define IPC_COMMA_OR_0(x) x |
| 668 #define IPC_COMMA_OR_1(x) , | 668 #define IPC_COMMA_OR_1(x) , |
| 669 #define IPC_COMMA_OR_2(x) , | 669 #define IPC_COMMA_OR_2(x) , |
| 670 #define IPC_COMMA_OR_3(x) , | 670 #define IPC_COMMA_OR_3(x) , |
| 671 #define IPC_COMMA_OR_4(x) , | 671 #define IPC_COMMA_OR_4(x) , |
| 672 #define IPC_COMMA_OR_5(x) , | 672 #define IPC_COMMA_OR_5(x) , |
| 673 | 673 |
| 674 // Message IDs | |
| 675 // Note: we currently use __LINE__ to give unique IDs to messages within | |
| 676 // a file. They're globally unique since each file defines its own | |
| 677 // IPC_MESSAGE_START. Ideally, we wouldn't use line numbers (a possibility | |
| 678 // is to instead use the __COUNTER__ macro, but it needs gcc 4.3 and xcode | |
| 679 // doesn't use it yet). | |
| 680 #define IPC_MESSAGE_ID() ((IPC_MESSAGE_START << 16) + __LINE__) | |
| 681 #define IPC_MESSAGE_ID_CLASS(id) ((id) >> 16) | |
| 682 #define IPC_MESSAGE_ID_LINE(id) ((id) & 0xffff) | |
| 683 | |
| 674 // Message crackers and handlers. | 684 // Message crackers and handlers. |
| 675 // Prefer to use the IPC_BEGIN_MESSAGE_MAP_EX to the older macros since they | 685 // Prefer to use the IPC_BEGIN_MESSAGE_MAP_EX to the older macros since they |
| 676 // allow you to detect when a message could not be de-serialized. Usage: | 686 // allow you to detect when a message could not be de-serialized. Usage: |
| 677 // | 687 // |
| 678 // bool MyClass::OnMessageReceived(const IPC::Message& msg) { | 688 // bool MyClass::OnMessageReceived(const IPC::Message& msg) { |
| 679 // bool handled = true; | 689 // bool handled = true; |
| 680 // bool msg_is_good = false; | 690 // bool msg_is_good = false; |
| 681 // IPC_BEGIN_MESSAGE_MAP_EX(MyClass, msg, msg_is_good) | 691 // IPC_BEGIN_MESSAGE_MAP_EX(MyClass, msg, msg_is_good) |
| 682 // IPC_MESSAGE_HANDLER(MsgClassOne, OnMsgClassOne) | 692 // IPC_MESSAGE_HANDLER(MsgClassOne, OnMsgClassOne) |
| 683 // ...more handlers here ... | 693 // ...more handlers here ... |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 747 DCHECK(msg_is_ok__); \ | 757 DCHECK(msg_is_ok__); \ |
| 748 } \ | 758 } \ |
| 749 } | 759 } |
| 750 | 760 |
| 751 #define IPC_END_MESSAGE_MAP_EX() \ | 761 #define IPC_END_MESSAGE_MAP_EX() \ |
| 752 } \ | 762 } \ |
| 753 } | 763 } |
| 754 | 764 |
| 755 // This corresponds to an enum value from IPCMessageStart. | 765 // This corresponds to an enum value from IPCMessageStart. |
| 756 #define IPC_MESSAGE_CLASS(message) \ | 766 #define IPC_MESSAGE_CLASS(message) \ |
| 757 message.type() >> 16 | 767 IPC_MESSAGE_ID_CLASS(message.type()) |
| 758 | 768 |
| 759 #endif // IPC_IPC_MESSAGE_MACROS_H_ | 769 #endif // IPC_IPC_MESSAGE_MACROS_H_ |
| 760 | 770 |
| 761 // Clean up IPC_MESSAGE_START in this unguarded section so that the | 771 // Clean up IPC_MESSAGE_START in this unguarded section so that the |
| 762 // XXX_messages.h files need not do so themselves. This makes the | 772 // XXX_messages.h files need not do so themselves. This makes the |
| 763 // XXX_messages.h files easier to write. | 773 // XXX_messages.h files easier to write. |
| 764 #undef IPC_MESSAGE_START | 774 #undef IPC_MESSAGE_START |
| 765 | 775 |
| OLD | NEW |