OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 | 7 |
8 #include <limits.h> | 8 #include <limits.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <stdint.h> | 10 #include <stdint.h> |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "base/strings/string16.h" | 24 #include "base/strings/string16.h" |
25 #include "base/strings/string_util.h" | 25 #include "base/strings/string_util.h" |
26 #include "base/strings/stringprintf.h" | 26 #include "base/strings/stringprintf.h" |
27 #include "base/tuple.h" | 27 #include "base/tuple.h" |
28 #include "build/build_config.h" | 28 #include "build/build_config.h" |
29 #include "ipc/brokerable_attachment.h" | 29 #include "ipc/brokerable_attachment.h" |
30 #include "ipc/ipc_message_start.h" | 30 #include "ipc/ipc_message_start.h" |
31 #include "ipc/ipc_param_traits.h" | 31 #include "ipc/ipc_param_traits.h" |
32 #include "ipc/ipc_sync_message.h" | 32 #include "ipc/ipc_sync_message.h" |
33 | 33 |
34 #if defined(COMPILER_GCC) | |
35 // GCC "helpfully" tries to inline template methods in release mode. Except we | |
36 // want the majority of the template junk being expanded once in the | |
37 // implementation file (and only provide the definitions in | |
38 // ipc_message_utils_impl.h in those files) and exported, instead of expanded | |
39 // at every call site. Special note: GCC happily accepts the attribute before | |
40 // the method declaration, but only acts on it if it is after. | |
41 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500 | |
42 // Starting in gcc 4.5, the noinline no longer implies the concept covered by | |
43 // the introduced noclone attribute, which will create specialized versions of | |
44 // functions/methods when certain types are constant. | |
45 // www.gnu.org/software/gcc/gcc-4.5/changes.html | |
46 #define IPC_MSG_NOINLINE __attribute__((noinline, noclone)); | |
47 #else | |
48 #define IPC_MSG_NOINLINE __attribute__((noinline)); | |
49 #endif | |
50 #elif defined(COMPILER_MSVC) | |
51 // MSVC++ doesn't do this. | |
52 #define IPC_MSG_NOINLINE | |
53 #else | |
54 #error "Please add the noinline property for your new compiler here." | |
55 #endif | |
56 | |
57 namespace base { | 34 namespace base { |
58 class DictionaryValue; | 35 class DictionaryValue; |
59 class FilePath; | 36 class FilePath; |
60 class ListValue; | 37 class ListValue; |
61 class NullableString16; | 38 class NullableString16; |
62 class Time; | 39 class Time; |
63 class TimeDelta; | 40 class TimeDelta; |
64 class TimeTicks; | 41 class TimeTicks; |
65 struct FileDescriptor; | 42 struct FileDescriptor; |
66 | 43 |
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 static bool Read(const Message* m, | 902 static bool Read(const Message* m, |
926 base::PickleIterator* iter, | 903 base::PickleIterator* iter, |
927 param_type* r); | 904 param_type* r); |
928 static void Log(const param_type& p, std::string* l); | 905 static void Log(const param_type& p, std::string* l); |
929 }; | 906 }; |
930 #endif // defined(OS_WIN) | 907 #endif // defined(OS_WIN) |
931 | 908 |
932 //----------------------------------------------------------------------------- | 909 //----------------------------------------------------------------------------- |
933 // Generic message subclasses | 910 // Generic message subclasses |
934 | 911 |
935 // Used for asynchronous messages. | |
936 template <class ParamType> | |
937 class MessageSchema { | |
938 public: | |
939 typedef ParamType Param; | |
940 typedef typename base::TupleTypes<ParamType>::ParamTuple RefParam; | |
941 | |
942 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE; | |
943 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE; | |
944 }; | |
945 | |
946 // defined in ipc_logging.cc | 912 // defined in ipc_logging.cc |
947 IPC_EXPORT void GenerateLogData(const std::string& channel, | 913 IPC_EXPORT void GenerateLogData(const std::string& channel, |
948 const Message& message, | 914 const Message& message, |
949 LogData* data, bool get_params); | 915 LogData* data, bool get_params); |
950 | 916 |
951 | 917 |
952 #if defined(IPC_MESSAGE_LOG_ENABLED) | 918 #if defined(IPC_MESSAGE_LOG_ENABLED) |
953 inline void AddOutputParamsToLog(const Message* msg, std::string* l) { | 919 inline void AddOutputParamsToLog(const Message* msg, std::string* l) { |
954 const std::string& output_params = msg->output_params(); | 920 const std::string& output_params = msg->output_params(); |
955 if (!l->empty() && !output_params.empty()) | 921 if (!l->empty() && !output_params.empty()) |
(...skipping 26 matching lines...) Expand all Loading... |
982 #else | 948 #else |
983 inline void AddOutputParamsToLog(const Message* msg, std::string* l) {} | 949 inline void AddOutputParamsToLog(const Message* msg, std::string* l) {} |
984 | 950 |
985 template <class ReplyParamType> | 951 template <class ReplyParamType> |
986 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params, | 952 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params, |
987 const Message* msg) {} | 953 const Message* msg) {} |
988 | 954 |
989 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {} | 955 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {} |
990 #endif | 956 #endif |
991 | 957 |
992 // This class assumes that its template argument is a RefTuple (a Tuple with | |
993 // reference elements). This would go into ipc_message_utils_impl.h, but it is | |
994 // also used by chrome_frame. | |
995 template <class RefTuple> | |
996 class ParamDeserializer : public MessageReplyDeserializer { | |
997 public: | |
998 explicit ParamDeserializer(const RefTuple& out) : out_(out) { } | |
999 | |
1000 bool SerializeOutputParameters(const IPC::Message& msg, | |
1001 base::PickleIterator iter) override { | |
1002 return ReadParam(&msg, &iter, &out_); | |
1003 } | |
1004 | |
1005 RefTuple out_; | |
1006 }; | |
1007 | |
1008 // Used for synchronous messages. | |
1009 template <class SendParamType, class ReplyParamType> | |
1010 class SyncMessageSchema { | |
1011 public: | |
1012 typedef SendParamType SendParam; | |
1013 typedef typename base::TupleTypes<SendParam>::ParamTuple RefSendParam; | |
1014 typedef ReplyParamType ReplyParam; | |
1015 | |
1016 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE; | |
1017 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE; | |
1018 static bool ReadReplyParam( | |
1019 const Message* msg, | |
1020 typename base::TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE; | |
1021 | |
1022 template<class T, class S, class Method> | |
1023 static bool DispatchWithSendParams(bool ok, const SendParam& send_params, | |
1024 const Message* msg, T* obj, S* sender, | |
1025 Method func) { | |
1026 Message* reply = SyncMessage::GenerateReply(msg); | |
1027 if (ok) { | |
1028 typename base::TupleTypes<ReplyParam>::ValueTuple reply_params; | |
1029 base::DispatchToMethod(obj, func, send_params, &reply_params); | |
1030 WriteParam(reply, reply_params); | |
1031 LogReplyParamsToMessage(reply_params, msg); | |
1032 } else { | |
1033 NOTREACHED() << "Error deserializing message " << msg->type(); | |
1034 reply->set_reply_error(); | |
1035 } | |
1036 sender->Send(reply); | |
1037 return ok; | |
1038 } | |
1039 | |
1040 template<class T, class Method> | |
1041 static bool DispatchDelayReplyWithSendParams(bool ok, | |
1042 const SendParam& send_params, | |
1043 const Message* msg, T* obj, | |
1044 Method func) { | |
1045 Message* reply = SyncMessage::GenerateReply(msg); | |
1046 if (ok) { | |
1047 base::Tuple<Message&> t = base::MakeRefTuple(*reply); | |
1048 ConnectMessageAndReply(msg, reply); | |
1049 base::DispatchToMethod(obj, func, send_params, &t); | |
1050 } else { | |
1051 NOTREACHED() << "Error deserializing message " << msg->type(); | |
1052 reply->set_reply_error(); | |
1053 obj->Send(reply); | |
1054 } | |
1055 return ok; | |
1056 } | |
1057 | |
1058 template <typename... Ts> | |
1059 static void WriteReplyParams(Message* reply, Ts... args) { | |
1060 ReplyParam p(args...); | |
1061 WriteParam(reply, p); | |
1062 } | |
1063 }; | |
1064 | |
1065 } // namespace IPC | 958 } // namespace IPC |
1066 | 959 |
1067 #endif // IPC_IPC_MESSAGE_UTILS_H_ | 960 #endif // IPC_IPC_MESSAGE_UTILS_H_ |
OLD | NEW |