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 854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
921 static bool Read(const base::Pickle* m, | 898 static bool Read(const base::Pickle* m, |
922 base::PickleIterator* iter, | 899 base::PickleIterator* iter, |
923 param_type* r); | 900 param_type* r); |
924 static void Log(const param_type& p, std::string* l); | 901 static void Log(const param_type& p, std::string* l); |
925 }; | 902 }; |
926 #endif // defined(OS_WIN) | 903 #endif // defined(OS_WIN) |
927 | 904 |
928 //----------------------------------------------------------------------------- | 905 //----------------------------------------------------------------------------- |
929 // Generic message subclasses | 906 // Generic message subclasses |
930 | 907 |
931 // Used for asynchronous messages. | |
932 template <class ParamType> | |
933 class MessageSchema { | |
934 public: | |
935 typedef ParamType Param; | |
936 typedef typename base::TupleTypes<ParamType>::ParamTuple RefParam; | |
937 | |
938 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE; | |
939 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE; | |
940 }; | |
941 | |
942 // defined in ipc_logging.cc | 908 // defined in ipc_logging.cc |
943 IPC_EXPORT void GenerateLogData(const std::string& channel, | 909 IPC_EXPORT void GenerateLogData(const std::string& channel, |
944 const Message& message, | 910 const Message& message, |
945 LogData* data, bool get_params); | 911 LogData* data, bool get_params); |
946 | 912 |
947 | 913 |
948 #if defined(IPC_MESSAGE_LOG_ENABLED) | 914 #if defined(IPC_MESSAGE_LOG_ENABLED) |
949 inline void AddOutputParamsToLog(const Message* msg, std::string* l) { | 915 inline void AddOutputParamsToLog(const Message* msg, std::string* l) { |
950 const std::string& output_params = msg->output_params(); | 916 const std::string& output_params = msg->output_params(); |
951 if (!l->empty() && !output_params.empty()) | 917 if (!l->empty() && !output_params.empty()) |
(...skipping 26 matching lines...) Expand all Loading... |
978 #else | 944 #else |
979 inline void AddOutputParamsToLog(const Message* msg, std::string* l) {} | 945 inline void AddOutputParamsToLog(const Message* msg, std::string* l) {} |
980 | 946 |
981 template <class ReplyParamType> | 947 template <class ReplyParamType> |
982 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params, | 948 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params, |
983 const Message* msg) {} | 949 const Message* msg) {} |
984 | 950 |
985 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {} | 951 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {} |
986 #endif | 952 #endif |
987 | 953 |
988 // This class assumes that its template argument is a RefTuple (a Tuple with | |
989 // reference elements). This would go into ipc_message_utils_impl.h, but it is | |
990 // also used by chrome_frame. | |
991 template <class RefTuple> | |
992 class ParamDeserializer : public MessageReplyDeserializer { | |
993 public: | |
994 explicit ParamDeserializer(const RefTuple& out) : out_(out) { } | |
995 | |
996 bool SerializeOutputParameters(const IPC::Message& msg, | |
997 base::PickleIterator iter) override { | |
998 return ReadParam(&msg, &iter, &out_); | |
999 } | |
1000 | |
1001 RefTuple out_; | |
1002 }; | |
1003 | |
1004 // Used for synchronous messages. | |
1005 template <class SendParamType, class ReplyParamType> | |
1006 class SyncMessageSchema { | |
1007 public: | |
1008 typedef SendParamType SendParam; | |
1009 typedef typename base::TupleTypes<SendParam>::ParamTuple RefSendParam; | |
1010 typedef ReplyParamType ReplyParam; | |
1011 | |
1012 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE; | |
1013 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE; | |
1014 static bool ReadReplyParam( | |
1015 const Message* msg, | |
1016 typename base::TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE; | |
1017 | |
1018 template<class T, class S, class Method> | |
1019 static bool DispatchWithSendParams(bool ok, const SendParam& send_params, | |
1020 const Message* msg, T* obj, S* sender, | |
1021 Method func) { | |
1022 Message* reply = SyncMessage::GenerateReply(msg); | |
1023 if (ok) { | |
1024 typename base::TupleTypes<ReplyParam>::ValueTuple reply_params; | |
1025 base::DispatchToMethod(obj, func, send_params, &reply_params); | |
1026 WriteParam(reply, reply_params); | |
1027 LogReplyParamsToMessage(reply_params, msg); | |
1028 } else { | |
1029 NOTREACHED() << "Error deserializing message " << msg->type(); | |
1030 reply->set_reply_error(); | |
1031 } | |
1032 sender->Send(reply); | |
1033 return ok; | |
1034 } | |
1035 | |
1036 template<class T, class Method> | |
1037 static bool DispatchDelayReplyWithSendParams(bool ok, | |
1038 const SendParam& send_params, | |
1039 const Message* msg, T* obj, | |
1040 Method func) { | |
1041 Message* reply = SyncMessage::GenerateReply(msg); | |
1042 if (ok) { | |
1043 base::Tuple<Message&> t = base::MakeRefTuple(*reply); | |
1044 ConnectMessageAndReply(msg, reply); | |
1045 base::DispatchToMethod(obj, func, send_params, &t); | |
1046 } else { | |
1047 NOTREACHED() << "Error deserializing message " << msg->type(); | |
1048 reply->set_reply_error(); | |
1049 obj->Send(reply); | |
1050 } | |
1051 return ok; | |
1052 } | |
1053 | |
1054 template <typename... Ts> | |
1055 static void WriteReplyParams(Message* reply, Ts... args) { | |
1056 ReplyParam p(args...); | |
1057 WriteParam(reply, p); | |
1058 } | |
1059 }; | |
1060 | |
1061 } // namespace IPC | 954 } // namespace IPC |
1062 | 955 |
1063 #endif // IPC_IPC_MESSAGE_UTILS_H_ | 956 #endif // IPC_IPC_MESSAGE_UTILS_H_ |
OLD | NEW |