Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: ipc/ipc_message_utils.h

Issue 3106018: Reapplies all the IPC system work (reverts the revert r56272). (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ipc/ipc_message_macros.h ('k') | ipc/ipc_message_utils.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #ifndef IPC_IPC_MESSAGE_UTILS_H_ 5 #ifndef IPC_IPC_MESSAGE_UTILS_H_
6 #define IPC_IPC_MESSAGE_UTILS_H_ 6 #define IPC_IPC_MESSAGE_UTILS_H_
7 #pragma once 7 #pragma once
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 #include <map> 12 #include <map>
13 #include <set> 13 #include <set>
14 14
15 #include "base/file_path.h"
16 #include "base/format_macros.h" 15 #include "base/format_macros.h"
17 #include "base/nullable_string16.h"
18 #include "base/string16.h" 16 #include "base/string16.h"
19 #include "base/string_number_conversions.h" 17 #include "base/string_number_conversions.h"
20 #include "base/string_util.h" 18 #include "base/string_util.h"
21 #include "base/time.h"
22 #include "base/tuple.h" 19 #include "base/tuple.h"
23 #include "base/utf_string_conversions.h" 20 #include "base/utf_string_conversions.h"
24 #include "base/values.h" 21 #include "ipc/ipc_sync_message.h"
25 #if defined(OS_POSIX) 22
26 #include "ipc/file_descriptor_set_posix.h" 23 #if defined(COMPILER_GCC)
24 // GCC "helpfully" tries to inline template methods in release mode. Except we
25 // want the majority of the template junk being expanded once in the
26 // implementation file (and only provide the definitions in
27 // ipc_message_utils_impl.h in those files) and exported, instead of expanded
28 // at every call site. Special note: GCC happily accepts the attribute before
29 // the method declaration, but only acts on it if it is after.
30 #define IPC_MSG_NOINLINE __attribute__((noinline));
31 #elif defined(COMPILER_MSVC)
32 // MSVC++ doesn't do this.
33 #define IPC_MSG_NOINLINE
34 #else
35 #error "Please add the noinline property for your new compiler here."
27 #endif 36 #endif
28 #include "ipc/ipc_channel_handle.h"
29 #include "ipc/ipc_sync_message.h"
30 37
31 // Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique 38 // Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
32 // base. Messages have unique IDs across channels in order for the IPC logging 39 // base. Messages have unique IDs across channels in order for the IPC logging
33 // code to figure out the message class from its ID. 40 // code to figure out the message class from its ID.
34 enum IPCMessageStart { 41 enum IPCMessageStart {
35 // By using a start value of 0 for automation messages, we keep backward 42 // By using a start value of 0 for automation messages, we keep backward
36 // compatibility with old builds. 43 // compatibility with old builds.
37 AutomationMsgStart = 0, 44 AutomationMsgStart = 0,
38 ViewMsgStart, 45 ViewMsgStart,
39 ViewHostMsgStart, 46 ViewHostMsgStart,
(...skipping 20 matching lines...) Expand all
60 GpuChannelMsgStart, 67 GpuChannelMsgStart,
61 GpuVideoDecoderHostMsgStart, 68 GpuVideoDecoderHostMsgStart,
62 GpuVideoDecoderMsgStart, 69 GpuVideoDecoderMsgStart,
63 ServiceMsgStart, 70 ServiceMsgStart,
64 ServiceHostMsgStart, 71 ServiceHostMsgStart,
65 // NOTE: When you add a new message class, also update 72 // NOTE: When you add a new message class, also update
66 // IPCStatusView::IPCStatusView to ensure logging works. 73 // IPCStatusView::IPCStatusView to ensure logging works.
67 LastMsgIndex 74 LastMsgIndex
68 }; 75 };
69 76
77 class DictionaryValue;
78 class FilePath;
79 class ListValue;
80 class NullableString16;
81
82 namespace base {
83 class Time;
84 struct FileDescriptor;
85 }
86
70 namespace IPC { 87 namespace IPC {
71 88
89 struct ChannelHandle;
90
72 //----------------------------------------------------------------------------- 91 //-----------------------------------------------------------------------------
73 // An iterator class for reading the fields contained within a Message. 92 // An iterator class for reading the fields contained within a Message.
74 93
75 class MessageIterator { 94 class MessageIterator {
76 public: 95 public:
77 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) { 96 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
78 } 97 }
79 int NextInt() const { 98 int NextInt() const {
80 int val = -1; 99 int val = -1;
81 if (!msg_.ReadInt(&iter_, &val)) 100 if (!msg_.ReadInt(&iter_, &val))
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 return result; 318 return result;
300 } 319 }
301 static void Log(const param_type& p, std::wstring* l) { 320 static void Log(const param_type& p, std::wstring* l) {
302 l->append(StringPrintf(L"%lc", p)); 321 l->append(StringPrintf(L"%lc", p));
303 } 322 }
304 }; 323 };
305 324
306 template <> 325 template <>
307 struct ParamTraits<base::Time> { 326 struct ParamTraits<base::Time> {
308 typedef base::Time param_type; 327 typedef base::Time param_type;
309 static void Write(Message* m, const param_type& p) { 328 static void Write(Message* m, const param_type& p);
310 ParamTraits<int64>::Write(m, p.ToInternalValue()); 329 static bool Read(const Message* m, void** iter, param_type* r);
311 } 330 static void Log(const param_type& p, std::wstring* l);
312 static bool Read(const Message* m, void** iter, param_type* r) {
313 int64 value;
314 if (!ParamTraits<int64>::Read(m, iter, &value))
315 return false;
316 *r = base::Time::FromInternalValue(value);
317 return true;
318 }
319 static void Log(const param_type& p, std::wstring* l) {
320 ParamTraits<int64>::Log(p.ToInternalValue(), l);
321 }
322 }; 331 };
323 332
324 #if defined(OS_WIN) 333 #if defined(OS_WIN)
325 template <> 334 template <>
326 struct ParamTraits<LOGFONT> { 335 struct ParamTraits<LOGFONT> {
327 typedef LOGFONT param_type; 336 typedef LOGFONT param_type;
328 static void Write(Message* m, const param_type& p) { 337 static void Write(Message* m, const param_type& p) {
329 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT)); 338 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
330 } 339 }
331 static bool Read(const Message* m, void** iter, param_type* r) { 340 static bool Read(const Message* m, void** iter, param_type* r) {
(...skipping 26 matching lines...) Expand all
358 bool result = m->ReadData(iter, &data, &data_size); 367 bool result = m->ReadData(iter, &data, &data_size);
359 if (result && data_size == sizeof(MSG)) { 368 if (result && data_size == sizeof(MSG)) {
360 memcpy(r, data, sizeof(MSG)); 369 memcpy(r, data, sizeof(MSG));
361 } else { 370 } else {
362 result = false; 371 result = false;
363 NOTREACHED(); 372 NOTREACHED();
364 } 373 }
365 374
366 return result; 375 return result;
367 } 376 }
377 static void Log(const param_type& p, std::wstring* l) {
378 l->append(L"<MSG>");
379 }
368 }; 380 };
369 #endif // defined(OS_WIN) 381 #endif // defined(OS_WIN)
370 382
371 template <> 383 template <>
372 struct ParamTraits<DictionaryValue> { 384 struct ParamTraits<DictionaryValue> {
373 typedef DictionaryValue param_type; 385 typedef DictionaryValue param_type;
374 static void Write(Message* m, const param_type& p); 386 static void Write(Message* m, const param_type& p);
375 static bool Read(const Message* m, void** iter, param_type* r); 387 static bool Read(const Message* m, void** iter, param_type* r);
376 static void Log(const param_type& p, std::wstring* l); 388 static void Log(const param_type& p, std::wstring* l);
377 }; 389 };
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 LogParam(p.first, l); 603 LogParam(p.first, l);
592 l->append(L", "); 604 l->append(L", ");
593 LogParam(p.second, l); 605 LogParam(p.second, l);
594 l->append(L")"); 606 l->append(L")");
595 } 607 }
596 }; 608 };
597 609
598 template <> 610 template <>
599 struct ParamTraits<NullableString16> { 611 struct ParamTraits<NullableString16> {
600 typedef NullableString16 param_type; 612 typedef NullableString16 param_type;
601 static void Write(Message* m, const param_type& p) { 613 static void Write(Message* m, const param_type& p);
602 WriteParam(m, p.string()); 614 static bool Read(const Message* m, void** iter, param_type* r);
603 WriteParam(m, p.is_null()); 615 static void Log(const param_type& p, std::wstring* l);
604 }
605 static bool Read(const Message* m, void** iter, param_type* r) {
606 string16 string;
607 if (!ReadParam(m, iter, &string))
608 return false;
609 bool is_null;
610 if (!ReadParam(m, iter, &is_null))
611 return false;
612 *r = NullableString16(string, is_null);
613 return true;
614 }
615 static void Log(const param_type& p, std::wstring* l) {
616 l->append(L"(");
617 LogParam(p.string(), l);
618 l->append(L", ");
619 LogParam(p.is_null(), l);
620 l->append(L")");
621 }
622 }; 616 };
623 617
624 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't 618 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
625 // need this trait. 619 // need this trait.
626 #if !defined(WCHAR_T_IS_UTF16) 620 #if !defined(WCHAR_T_IS_UTF16)
627 template <> 621 template <>
628 struct ParamTraits<string16> { 622 struct ParamTraits<string16> {
629 typedef string16 param_type; 623 typedef string16 param_type;
630 static void Write(Message* m, const param_type& p) { 624 static void Write(Message* m, const param_type& p) {
631 m->WriteString16(p); 625 m->WriteString16(p);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 } 696 }
703 static void Log(const param_type& p, std::wstring* l) { 697 static void Log(const param_type& p, std::wstring* l) {
704 l->append(StringPrintf(L"(%d, %d)", p.x, p.y)); 698 l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
705 } 699 }
706 }; 700 };
707 #endif // defined(OS_WIN) 701 #endif // defined(OS_WIN)
708 702
709 template <> 703 template <>
710 struct ParamTraits<FilePath> { 704 struct ParamTraits<FilePath> {
711 typedef FilePath param_type; 705 typedef FilePath param_type;
712 static void Write(Message* m, const param_type& p) { 706 static void Write(Message* m, const param_type& p);
713 ParamTraits<FilePath::StringType>::Write(m, p.value()); 707 static bool Read(const Message* m, void** iter, param_type* r);
714 } 708 static void Log(const param_type& p, std::wstring* l);
715 static bool Read(const Message* m, void** iter, param_type* r) {
716 FilePath::StringType value;
717 if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
718 return false;
719 *r = FilePath(value);
720 return true;
721 }
722 static void Log(const param_type& p, std::wstring* l) {
723 ParamTraits<FilePath::StringType>::Log(p.value(), l);
724 }
725 }; 709 };
726 710
727 #if defined(OS_POSIX) 711 #if defined(OS_POSIX)
728 // FileDescriptors may be serialised over IPC channels on POSIX. On the 712 // FileDescriptors may be serialised over IPC channels on POSIX. On the
729 // receiving side, the FileDescriptor is a valid duplicate of the file 713 // receiving side, the FileDescriptor is a valid duplicate of the file
730 // descriptor which was transmitted: *it is not just a copy of the integer like 714 // descriptor which was transmitted: *it is not just a copy of the integer like
731 // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In 715 // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
732 // this case, the receiving end will see a value of -1. *Zero is a valid file 716 // this case, the receiving end will see a value of -1. *Zero is a valid file
733 // descriptor*. 717 // descriptor*.
734 // 718 //
735 // The received file descriptor will have the |auto_close| flag set to true. The 719 // The received file descriptor will have the |auto_close| flag set to true. The
736 // code which handles the message is responsible for taking ownership of it. 720 // code which handles the message is responsible for taking ownership of it.
737 // File descriptors are OS resources and must be closed when no longer needed. 721 // File descriptors are OS resources and must be closed when no longer needed.
738 // 722 //
739 // When sending a file descriptor, the file descriptor must be valid at the time 723 // When sending a file descriptor, the file descriptor must be valid at the time
740 // of transmission. Since transmission is not synchronous, one should consider 724 // of transmission. Since transmission is not synchronous, one should consider
741 // dup()ing any file descriptors to be transmitted and setting the |auto_close| 725 // dup()ing any file descriptors to be transmitted and setting the |auto_close|
742 // flag, which causes the file descriptor to be closed after writing. 726 // flag, which causes the file descriptor to be closed after writing.
743 template<> 727 template<>
744 struct ParamTraits<base::FileDescriptor> { 728 struct ParamTraits<base::FileDescriptor> {
745 typedef base::FileDescriptor param_type; 729 typedef base::FileDescriptor param_type;
746 static void Write(Message* m, const param_type& p) { 730 static void Write(Message* m, const param_type& p);
747 const bool valid = p.fd >= 0; 731 static bool Read(const Message* m, void** iter, param_type* r);
748 WriteParam(m, valid); 732 static void Log(const param_type& p, std::wstring* l);
749
750 if (valid) {
751 if (!m->WriteFileDescriptor(p))
752 NOTREACHED();
753 }
754 }
755 static bool Read(const Message* m, void** iter, param_type* r) {
756 bool valid;
757 if (!ReadParam(m, iter, &valid))
758 return false;
759
760 if (!valid) {
761 r->fd = -1;
762 r->auto_close = false;
763 return true;
764 }
765
766 return m->ReadFileDescriptor(iter, r);
767 }
768 static void Log(const param_type& p, std::wstring* l) {
769 if (p.auto_close) {
770 l->append(StringPrintf(L"FD(%d auto-close)", p.fd));
771 } else {
772 l->append(StringPrintf(L"FD(%d)", p.fd));
773 }
774 }
775 }; 733 };
776 #endif // defined(OS_POSIX) 734 #endif // defined(OS_POSIX)
777 735
778 // A ChannelHandle is basically a platform-inspecific wrapper around the 736 // A ChannelHandle is basically a platform-inspecific wrapper around the
779 // fact that IPC endpoints are handled specially on POSIX. See above comments 737 // fact that IPC endpoints are handled specially on POSIX. See above comments
780 // on FileDescriptor for more background. 738 // on FileDescriptor for more background.
781 template<> 739 template<>
782 struct ParamTraits<IPC::ChannelHandle> { 740 struct ParamTraits<IPC::ChannelHandle> {
783 typedef ChannelHandle param_type; 741 typedef ChannelHandle param_type;
784 static void Write(Message* m, const param_type& p) { 742 static void Write(Message* m, const param_type& p);
785 WriteParam(m, p.name); 743 static bool Read(const Message* m, void** iter, param_type* r);
786 #if defined(OS_POSIX) 744 static void Log(const param_type& p, std::wstring* l);
787 WriteParam(m, p.socket);
788 #endif
789 }
790 static bool Read(const Message* m, void** iter, param_type* r) {
791 return ReadParam(m, iter, &r->name)
792 #if defined(OS_POSIX)
793 && ReadParam(m, iter, &r->socket)
794 #endif
795 ;
796 }
797 static void Log(const param_type& p, std::wstring* l) {
798 l->append(ASCIIToWide(StringPrintf("ChannelHandle(%s", p.name.c_str())));
799 #if defined(OS_POSIX)
800 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
801 #endif
802 l->append(L")");
803 }
804 }; 745 };
805 746
806 #if defined(OS_WIN) 747 #if defined(OS_WIN)
807 template <> 748 template <>
808 struct ParamTraits<XFORM> { 749 struct ParamTraits<XFORM> {
809 typedef XFORM param_type; 750 typedef XFORM param_type;
810 static void Write(Message* m, const param_type& p) { 751 static void Write(Message* m, const param_type& p) {
811 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM)); 752 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
812 } 753 }
813 static bool Read(const Message* m, void** iter, param_type* r) { 754 static bool Read(const Message* m, void** iter, param_type* r) {
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 }; 960 };
1020 961
1021 //----------------------------------------------------------------------------- 962 //-----------------------------------------------------------------------------
1022 // Generic message subclasses 963 // Generic message subclasses
1023 964
1024 // Used for asynchronous messages. 965 // Used for asynchronous messages.
1025 template <class ParamType> 966 template <class ParamType>
1026 class MessageWithTuple : public Message { 967 class MessageWithTuple : public Message {
1027 public: 968 public:
1028 typedef ParamType Param; 969 typedef ParamType Param;
1029 typedef typename ParamType::ParamTuple RefParam; 970 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
1030 971
1031 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p) 972 // The constructor and the Read() method's templated implementations are in
1032 : Message(routing_id, type, PRIORITY_NORMAL) { 973 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
1033 WriteParam(this, p); 974 // the templated versions of these and make sure there are instantiations in
1034 } 975 // those translation units.
976 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
1035 977
1036 static bool Read(const Message* msg, Param* p) { 978 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
1037 void* iter = NULL;
1038 if (ReadParam(msg, &iter, p))
1039 return true;
1040 NOTREACHED() << "Error deserializing message " << msg->type();
1041 return false;
1042 }
1043 979
1044 // Generic dispatcher. Should cover most cases. 980 // Generic dispatcher. Should cover most cases.
1045 template<class T, class Method> 981 template<class T, class Method>
1046 static bool Dispatch(const Message* msg, T* obj, Method func) { 982 static bool Dispatch(const Message* msg, T* obj, Method func) {
1047 Param p; 983 Param p;
1048 if (Read(msg, &p)) { 984 if (Read(msg, &p)) {
1049 DispatchToMethod(obj, func, p); 985 DispatchToMethod(obj, func, p);
1050 return true; 986 return true;
1051 } 987 }
1052 return false; 988 return false;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 static bool Dispatch(const Message* msg, T* obj, 1040 static bool Dispatch(const Message* msg, T* obj,
1105 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) { 1041 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1106 Param p; 1042 Param p;
1107 if (Read(msg, &p)) { 1043 if (Read(msg, &p)) {
1108 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e); 1044 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1109 return true; 1045 return true;
1110 } 1046 }
1111 return false; 1047 return false;
1112 } 1048 }
1113 1049
1114 static void Log(const Message* msg, std::wstring* l) {
1115 Param p;
1116 if (Read(msg, &p))
1117 LogParam(p, l);
1118 }
1119
1120 // Functions used to do manual unpacking. Only used by the automation code, 1050 // Functions used to do manual unpacking. Only used by the automation code,
1121 // these should go away once that code uses SyncChannel. 1051 // these should go away once that code uses SyncChannel.
1122 template<typename TA, typename TB> 1052 template<typename TA, typename TB>
1123 static bool Read(const IPC::Message* msg, TA* a, TB* b) { 1053 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1124 ParamType params; 1054 ParamType params;
1125 if (!Read(msg, &params)) 1055 if (!Read(msg, &params))
1126 return false; 1056 return false;
1127 *a = params.a; 1057 *a = params.a;
1128 *b = params.b; 1058 *b = params.b;
1129 return true; 1059 return true;
(...skipping 29 matching lines...) Expand all
1159 return false; 1089 return false;
1160 *a = params.a; 1090 *a = params.a;
1161 *b = params.b; 1091 *b = params.b;
1162 *c = params.c; 1092 *c = params.c;
1163 *d = params.d; 1093 *d = params.d;
1164 *e = params.e; 1094 *e = params.e;
1165 return true; 1095 return true;
1166 } 1096 }
1167 }; 1097 };
1168 1098
1099 // defined in ipc_logging.cc
1100 void GenerateLogData(const std::string& channel, const Message& message,
1101 LogData* data);
1102
1103
1104 #if defined(IPC_MESSAGE_LOG_ENABLED)
1105 inline void AddOutputParamsToLog(const Message* msg, std::wstring* l) {
1106 const std::wstring& output_params = msg->output_params();
1107 if (!l->empty() && !output_params.empty())
1108 l->append(L", ");
1109
1110 l->append(output_params);
1111 }
1112
1113 template <class ReplyParamType>
1114 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1115 const Message* msg) {
1116 if (msg->received_time() != 0) {
1117 std::wstring output_params;
1118 LogParam(reply_params, &output_params);
1119 msg->set_output_params(output_params);
1120 }
1121 }
1122
1123 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1124 if (msg->sent_time()) {
1125 // Don't log the sync message after dispatch, as we don't have the
1126 // output parameters at that point. Instead, save its data and log it
1127 // with the outgoing reply message when it's sent.
1128 LogData* data = new LogData;
1129 GenerateLogData("", *msg, data);
1130 msg->set_dont_log();
1131 reply->set_sync_log_data(data);
1132 }
1133 }
1134 #else
1135 inline void AddOutputParamsToLog(const Message* msg, std::wstring* l) {}
1136
1137 template <class ReplyParamType>
1138 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1139 const Message* msg) {}
1140
1141 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1142 #endif
1143
1169 // This class assumes that its template argument is a RefTuple (a Tuple with 1144 // This class assumes that its template argument is a RefTuple (a Tuple with
1170 // reference elements). 1145 // reference elements). This would go into ipc_message_utils_impl.h, but it is
1146 // also used by chrome_frame.
1171 template <class RefTuple> 1147 template <class RefTuple>
1172 class ParamDeserializer : public MessageReplyDeserializer { 1148 class ParamDeserializer : public MessageReplyDeserializer {
1173 public: 1149 public:
1174 explicit ParamDeserializer(const RefTuple& out) : out_(out) { } 1150 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
1175 1151
1176 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) { 1152 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1177 return ReadParam(&msg, &iter, &out_); 1153 return ReadParam(&msg, &iter, &out_);
1178 } 1154 }
1179 1155
1180 RefTuple out_; 1156 RefTuple out_;
1181 }; 1157 };
1182 1158
1183 // defined in ipc_logging.cc
1184 void GenerateLogData(const std::string& channel, const Message& message,
1185 LogData* data);
1186
1187 // Used for synchronous messages. 1159 // Used for synchronous messages.
1188 template <class SendParamType, class ReplyParamType> 1160 template <class SendParamType, class ReplyParamType>
1189 class MessageWithReply : public SyncMessage { 1161 class MessageWithReply : public SyncMessage {
1190 public: 1162 public:
1191 typedef SendParamType SendParam; 1163 typedef SendParamType SendParam;
1192 typedef typename SendParam::ParamTuple RefSendParam; 1164 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
1193 typedef ReplyParamType ReplyParam; 1165 typedef ReplyParamType ReplyParam;
1194 1166
1195 MessageWithReply(int32 routing_id, uint32 type, 1167 MessageWithReply(int32 routing_id, uint32 type,
1196 const RefSendParam& send, const ReplyParam& reply) 1168 const RefSendParam& send, const ReplyParam& reply);
1197 : SyncMessage(routing_id, type, PRIORITY_NORMAL, 1169 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1198 new ParamDeserializer<ReplyParam>(reply)) { 1170 static bool ReadReplyParam(
1199 WriteParam(this, send); 1171 const Message* msg,
1200 } 1172 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
1201
1202 static void Log(const Message* msg, std::wstring* l) {
1203 if (msg->is_sync()) {
1204 SendParam p;
1205 void* iter = SyncMessage::GetDataIterator(msg);
1206 if (ReadParam(msg, &iter, &p))
1207 LogParam(p, l);
1208
1209 #if defined(IPC_MESSAGE_LOG_ENABLED)
1210 const std::wstring& output_params = msg->output_params();
1211 if (!l->empty() && !output_params.empty())
1212 l->append(L", ");
1213
1214 l->append(output_params);
1215 #endif
1216 } else {
1217 // This is an outgoing reply. Now that we have the output parameters, we
1218 // can finally log the message.
1219 typename ReplyParam::ValueTuple p;
1220 void* iter = SyncMessage::GetDataIterator(msg);
1221 if (ReadParam(msg, &iter, &p))
1222 LogParam(p, l);
1223 }
1224 }
1225 1173
1226 template<class T, class Method> 1174 template<class T, class Method>
1227 static bool Dispatch(const Message* msg, T* obj, Method func) { 1175 static bool Dispatch(const Message* msg, T* obj, Method func) {
1228 SendParam send_params; 1176 SendParam send_params;
1229 void* iter = GetDataIterator(msg);
1230 Message* reply = GenerateReply(msg); 1177 Message* reply = GenerateReply(msg);
1231 bool error; 1178 bool error;
1232 if (ReadParam(msg, &iter, &send_params)) { 1179 if (ReadSendParam(msg, &send_params)) {
1233 typename ReplyParam::ValueTuple reply_params; 1180 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
1234 DispatchToMethod(obj, func, send_params, &reply_params); 1181 DispatchToMethod(obj, func, send_params, &reply_params);
1235 WriteParam(reply, reply_params); 1182 WriteParam(reply, reply_params);
1236 error = false; 1183 error = false;
1237 #ifdef IPC_MESSAGE_LOG_ENABLED 1184 LogReplyParamsToMessage(reply_params, msg);
1238 if (msg->received_time() != 0) {
1239 std::wstring output_params;
1240 LogParam(reply_params, &output_params);
1241 msg->set_output_params(output_params);
1242 }
1243 #endif
1244 } else { 1185 } else {
1245 NOTREACHED() << "Error deserializing message " << msg->type(); 1186 NOTREACHED() << "Error deserializing message " << msg->type();
1246 reply->set_reply_error(); 1187 reply->set_reply_error();
1247 error = true; 1188 error = true;
1248 } 1189 }
1249 1190
1250 obj->Send(reply); 1191 obj->Send(reply);
1251 return !error; 1192 return !error;
1252 } 1193 }
1253 1194
1254 template<class T, class Method> 1195 template<class T, class Method>
1255 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) { 1196 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
1256 SendParam send_params; 1197 SendParam send_params;
1257 void* iter = GetDataIterator(msg);
1258 Message* reply = GenerateReply(msg); 1198 Message* reply = GenerateReply(msg);
1259 bool error; 1199 bool error;
1260 if (ReadParam(msg, &iter, &send_params)) { 1200 if (ReadSendParam(msg, &send_params)) {
1261 Tuple1<Message&> t = MakeRefTuple(*reply); 1201 Tuple1<Message&> t = MakeRefTuple(*reply);
1262 1202 ConnectMessageAndReply(msg, reply);
1263 #ifdef IPC_MESSAGE_LOG_ENABLED
1264 if (msg->sent_time()) {
1265 // Don't log the sync message after dispatch, as we don't have the
1266 // output parameters at that point. Instead, save its data and log it
1267 // with the outgoing reply message when it's sent.
1268 LogData* data = new LogData;
1269 GenerateLogData("", *msg, data);
1270 msg->set_dont_log();
1271 reply->set_sync_log_data(data);
1272 }
1273 #endif
1274 DispatchToMethod(obj, func, send_params, &t); 1203 DispatchToMethod(obj, func, send_params, &t);
1275 error = false; 1204 error = false;
1276 } else { 1205 } else {
1277 NOTREACHED() << "Error deserializing message " << msg->type(); 1206 NOTREACHED() << "Error deserializing message " << msg->type();
1278 reply->set_reply_error(); 1207 reply->set_reply_error();
1279 obj->Send(reply); 1208 obj->Send(reply);
1280 error = true; 1209 error = true;
1281 } 1210 }
1282 return !error; 1211 return !error;
1283 } 1212 }
(...skipping 27 matching lines...) Expand all
1311 ReplyParam p(a, b, c, d, e); 1240 ReplyParam p(a, b, c, d, e);
1312 WriteParam(reply, p); 1241 WriteParam(reply, p);
1313 } 1242 }
1314 }; 1243 };
1315 1244
1316 //----------------------------------------------------------------------------- 1245 //-----------------------------------------------------------------------------
1317 1246
1318 } // namespace IPC 1247 } // namespace IPC
1319 1248
1320 #endif // IPC_IPC_MESSAGE_UTILS_H_ 1249 #endif // IPC_IPC_MESSAGE_UTILS_H_
OLDNEW
« no previous file with comments | « ipc/ipc_message_macros.h ('k') | ipc/ipc_message_utils.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698