| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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_TEMPLATES_H_ | 5 #ifndef IPC_IPC_MESSAGE_TEMPLATES_H_ |
| 6 #define IPC_IPC_MESSAGE_TEMPLATES_H_ | 6 #define IPC_IPC_MESSAGE_TEMPLATES_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <tuple> |
| 10 #include <type_traits> | 11 #include <type_traits> |
| 11 | 12 |
| 12 #include "base/logging.h" | 13 #include "base/logging.h" |
| 13 #include "base/tuple.h" | 14 #include "base/tuple.h" |
| 14 #include "build/build_config.h" | 15 #include "build/build_config.h" |
| 15 #include "ipc/ipc_message.h" | 16 #include "ipc/ipc_message.h" |
| 16 #include "ipc/ipc_message_utils.h" | 17 #include "ipc/ipc_message_utils.h" |
| 17 | 18 |
| 18 namespace IPC { | 19 namespace IPC { |
| 19 | 20 |
| 20 // This function is for all the async IPCs that don't pass an extra parameter | 21 // This function is for all the async IPCs that don't pass an extra parameter |
| 21 // using IPC_BEGIN_MESSAGE_MAP_WITH_PARAM. | 22 // using IPC_BEGIN_MESSAGE_MAP_WITH_PARAM. |
| 22 template <typename ObjT, typename Method, typename P, typename Tuple> | 23 template <typename ObjT, typename Method, typename P, typename Tuple> |
| 23 void DispatchToMethod(ObjT* obj, Method method, P*, const Tuple& tuple) { | 24 void DispatchToMethod(ObjT* obj, Method method, P*, const Tuple& tuple) { |
| 24 base::DispatchToMethod(obj, method, tuple); | 25 base::DispatchToMethod(obj, method, tuple); |
| 25 } | 26 } |
| 26 | 27 |
| 27 template <typename ObjT, | 28 template <typename ObjT, |
| 28 typename Method, | 29 typename Method, |
| 29 typename P, | 30 typename P, |
| 30 typename Tuple, | 31 typename Tuple, |
| 31 size_t... Ns> | 32 size_t... Ns> |
| 32 void DispatchToMethodImpl(ObjT* obj, | 33 void DispatchToMethodImpl(ObjT* obj, |
| 33 Method method, | 34 Method method, |
| 34 P* parameter, | 35 P* parameter, |
| 35 const Tuple& tuple, | 36 const Tuple& tuple, |
| 36 base::IndexSequence<Ns...>) { | 37 base::IndexSequence<Ns...>) { |
| 37 // TODO(mdempsky): Apply UnwrapTraits like base::DispatchToMethod? | 38 // TODO(mdempsky): Apply UnwrapTraits like base::DispatchToMethod? |
| 38 (obj->*method)(parameter, base::get<Ns>(tuple)...); | 39 (obj->*method)(parameter, std::get<Ns>(tuple)...); |
| 39 } | 40 } |
| 40 | 41 |
| 41 // The following function is for async IPCs which have a dispatcher with an | 42 // The following function is for async IPCs which have a dispatcher with an |
| 42 // extra parameter specified using IPC_BEGIN_MESSAGE_MAP_WITH_PARAM. | 43 // extra parameter specified using IPC_BEGIN_MESSAGE_MAP_WITH_PARAM. |
| 43 template <typename ObjT, typename P, typename... Args, typename... Ts> | 44 template <typename ObjT, typename P, typename... Args, typename... Ts> |
| 44 typename std::enable_if<sizeof...(Args) == sizeof...(Ts)>::type | 45 typename std::enable_if<sizeof...(Args) == sizeof...(Ts)>::type |
| 45 DispatchToMethod(ObjT* obj, | 46 DispatchToMethod(ObjT* obj, |
| 46 void (ObjT::*method)(P*, Args...), | 47 void (ObjT::*method)(P*, Args...), |
| 47 P* parameter, | 48 P* parameter, |
| 48 const base::Tuple<Ts...>& tuple) { | 49 const std::tuple<Ts...>& tuple) { |
| 49 DispatchToMethodImpl(obj, method, parameter, tuple, | 50 DispatchToMethodImpl(obj, method, parameter, tuple, |
| 50 base::MakeIndexSequence<sizeof...(Ts)>()); | 51 base::MakeIndexSequence<sizeof...(Ts)>()); |
| 51 } | 52 } |
| 52 | 53 |
| 53 enum class MessageKind { | 54 enum class MessageKind { |
| 54 CONTROL, | 55 CONTROL, |
| 55 ROUTED, | 56 ROUTED, |
| 56 }; | 57 }; |
| 57 | 58 |
| 58 // Routing is a helper struct so MessageT's private common constructor has a | 59 // Routing is a helper struct so MessageT's private common constructor has a |
| (...skipping 18 matching lines...) Expand all Loading... |
| 77 | 78 |
| 78 // MessageT is the common template used for all user-defined message types. | 79 // MessageT is the common template used for all user-defined message types. |
| 79 // It's intended to be used via the macros defined in ipc_message_macros.h. | 80 // It's intended to be used via the macros defined in ipc_message_macros.h. |
| 80 template <typename Meta, | 81 template <typename Meta, |
| 81 typename InTuple = typename Meta::InTuple, | 82 typename InTuple = typename Meta::InTuple, |
| 82 typename OutTuple = typename Meta::OutTuple> | 83 typename OutTuple = typename Meta::OutTuple> |
| 83 class MessageT; | 84 class MessageT; |
| 84 | 85 |
| 85 // Asynchronous message partial specialization. | 86 // Asynchronous message partial specialization. |
| 86 template <typename Meta, typename... Ins> | 87 template <typename Meta, typename... Ins> |
| 87 class MessageT<Meta, base::Tuple<Ins...>, void> : public Message { | 88 class MessageT<Meta, std::tuple<Ins...>, void> : public Message { |
| 88 public: | 89 public: |
| 89 using Param = base::Tuple<Ins...>; | 90 using Param = std::tuple<Ins...>; |
| 90 enum { ID = Meta::ID }; | 91 enum { ID = Meta::ID }; |
| 91 | 92 |
| 92 // TODO(mdempsky): Remove. Uses of MyMessage::Schema::Param can be replaced | 93 // TODO(mdempsky): Remove. Uses of MyMessage::Schema::Param can be replaced |
| 93 // with just MyMessage::Param. | 94 // with just MyMessage::Param. |
| 94 using Schema = MessageT; | 95 using Schema = MessageT; |
| 95 | 96 |
| 96 IPC_MESSAGET_SFINAE(Meta::kKind == MessageKind::CONTROL) | 97 IPC_MESSAGET_SFINAE(Meta::kKind == MessageKind::CONTROL) |
| 97 MessageT(const Ins&... ins) : MessageT(Routing(MSG_ROUTING_CONTROL), ins...) { | 98 MessageT(const Ins&... ins) : MessageT(Routing(MSG_ROUTING_CONTROL), ins...) { |
| 98 DCHECK(Meta::kKind == MessageKind::CONTROL) << Meta::kName; | 99 DCHECK(Meta::kKind == MessageKind::CONTROL) << Meta::kName; |
| 99 } | 100 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 120 } | 121 } |
| 121 return false; | 122 return false; |
| 122 } | 123 } |
| 123 | 124 |
| 124 private: | 125 private: |
| 125 MessageT(Routing routing, const Ins&... ins); | 126 MessageT(Routing routing, const Ins&... ins); |
| 126 }; | 127 }; |
| 127 | 128 |
| 128 // Synchronous message partial specialization. | 129 // Synchronous message partial specialization. |
| 129 template <typename Meta, typename... Ins, typename... Outs> | 130 template <typename Meta, typename... Ins, typename... Outs> |
| 130 class MessageT<Meta, base::Tuple<Ins...>, base::Tuple<Outs...>> | 131 class MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>> |
| 131 : public SyncMessage { | 132 : public SyncMessage { |
| 132 public: | 133 public: |
| 133 using SendParam = base::Tuple<Ins...>; | 134 using SendParam = std::tuple<Ins...>; |
| 134 using ReplyParam = base::Tuple<Outs...>; | 135 using ReplyParam = std::tuple<Outs...>; |
| 135 enum { ID = Meta::ID }; | 136 enum { ID = Meta::ID }; |
| 136 | 137 |
| 137 // TODO(mdempsky): Remove. Uses of MyMessage::Schema::{Send,Reply}Param can | 138 // TODO(mdempsky): Remove. Uses of MyMessage::Schema::{Send,Reply}Param can |
| 138 // be replaced with just MyMessage::{Send,Reply}Param. | 139 // be replaced with just MyMessage::{Send,Reply}Param. |
| 139 using Schema = MessageT; | 140 using Schema = MessageT; |
| 140 | 141 |
| 141 IPC_MESSAGET_SFINAE(Meta::kKind == MessageKind::CONTROL) | 142 IPC_MESSAGET_SFINAE(Meta::kKind == MessageKind::CONTROL) |
| 142 MessageT(const Ins&... ins, Outs*... outs) | 143 MessageT(const Ins&... ins, Outs*... outs) |
| 143 : MessageT(Routing(MSG_ROUTING_CONTROL), ins..., outs...) { | 144 : MessageT(Routing(MSG_ROUTING_CONTROL), ins..., outs...) { |
| 144 DCHECK(Meta::kKind == MessageKind::CONTROL) << Meta::kName; | 145 DCHECK(Meta::kKind == MessageKind::CONTROL) << Meta::kName; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 | 180 |
| 180 template <class T, class P, class Method> | 181 template <class T, class P, class Method> |
| 181 static bool DispatchDelayReply(const Message* msg, | 182 static bool DispatchDelayReply(const Message* msg, |
| 182 T* obj, | 183 T* obj, |
| 183 P* parameter, | 184 P* parameter, |
| 184 Method func) { | 185 Method func) { |
| 185 SendParam send_params; | 186 SendParam send_params; |
| 186 bool ok = ReadSendParam(msg, &send_params); | 187 bool ok = ReadSendParam(msg, &send_params); |
| 187 Message* reply = SyncMessage::GenerateReply(msg); | 188 Message* reply = SyncMessage::GenerateReply(msg); |
| 188 if (ok) { | 189 if (ok) { |
| 189 base::Tuple<Message&> t = base::MakeRefTuple(*reply); | 190 std::tuple<Message&> t = std::tie(*reply); |
| 190 ConnectMessageAndReply(msg, reply); | 191 ConnectMessageAndReply(msg, reply); |
| 191 base::DispatchToMethod(obj, func, send_params, &t); | 192 base::DispatchToMethod(obj, func, send_params, &t); |
| 192 } else { | 193 } else { |
| 193 NOTREACHED() << "Error deserializing message " << msg->type(); | 194 NOTREACHED() << "Error deserializing message " << msg->type(); |
| 194 reply->set_reply_error(); | 195 reply->set_reply_error(); |
| 195 obj->Send(reply); | 196 obj->Send(reply); |
| 196 } | 197 } |
| 197 return ok; | 198 return ok; |
| 198 } | 199 } |
| 199 | 200 |
| 200 private: | 201 private: |
| 201 MessageT(Routing routing, const Ins&... ins, Outs*... outs); | 202 MessageT(Routing routing, const Ins&... ins, Outs*... outs); |
| 202 }; | 203 }; |
| 203 | 204 |
| 204 } // namespace IPC | 205 } // namespace IPC |
| 205 | 206 |
| 206 #if defined(IPC_MESSAGE_IMPL) | 207 #if defined(IPC_MESSAGE_IMPL) |
| 207 #include "ipc/ipc_message_templates_impl.h" | 208 #include "ipc/ipc_message_templates_impl.h" |
| 208 #endif | 209 #endif |
| 209 | 210 |
| 210 #endif // IPC_IPC_MESSAGE_TEMPLATES_H_ | 211 #endif // IPC_IPC_MESSAGE_TEMPLATES_H_ |
| OLD | NEW |