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

Unified Diff: ipc/ipc_message_templates.h

Issue 1532053002: use variadic macros/templates in IPC message implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: simplify Created 5 years 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 side-by-side diff with in-line comments
Download patch
Index: ipc/ipc_message_templates.h
diff --git a/ipc/ipc_message_templates.h b/ipc/ipc_message_templates.h
new file mode 100644
index 0000000000000000000000000000000000000000..caf9cfc46bfb432de289685ea72ad2d721a8560a
--- /dev/null
+++ b/ipc/ipc_message_templates.h
@@ -0,0 +1,199 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IPC_IPC_MESSAGE_TEMPLATES_H_
+#define IPC_IPC_MESSAGE_TEMPLATES_H_
+
+#include <stdint.h>
+
+#include <type_traits>
+
+#include "base/tuple.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_message_utils.h"
+
+namespace IPC {
+
+// This function is for all the async IPCs that don't pass an extra parameter
+// using IPC_BEGIN_MESSAGE_MAP_WITH_PARAM.
+template <typename ObjT, typename Method, typename P, typename Tuple>
+void DispatchToMethod(ObjT* obj, Method method, P*, const Tuple& tuple) {
+ base::DispatchToMethod(obj, method, tuple);
+}
+
+template <typename ObjT,
+ typename Method,
+ typename P,
+ typename Tuple,
+ size_t... Ns>
+void DispatchToMethodImpl(ObjT* obj,
+ Method method,
+ P* parameter,
+ const Tuple& tuple,
+ base::IndexSequence<Ns...>) {
+ // TODO(mdempsky): Apply UnwrapTraits like base::DispatchToMethod?
+ (obj->*method)(parameter, base::get<Ns>(tuple)...);
+}
+
+// The following function is for async IPCs which have a dispatcher with an
+// extra parameter specified using IPC_BEGIN_MESSAGE_MAP_WITH_PARAM.
+template <typename ObjT, typename P, typename... Args, typename... Ts>
+typename std::enable_if<sizeof...(Args) == sizeof...(Ts)>::type
+DispatchToMethod(ObjT* obj,
+ void (ObjT::*method)(P*, Args...),
+ P* parameter,
+ const base::Tuple<Ts...>& tuple) {
+ DispatchToMethodImpl(obj, method, parameter, tuple,
+ base::MakeIndexSequence<sizeof...(Ts)>());
+}
+
+template <uint32_t Id, const char* Name, typename InTuple, typename OutTuple>
+class CommonAsyncMessage;
+
+template <uint32_t Id, const char* Name, typename... Ins>
danakj 2015/12/19 00:15:06 There's a real lack of comments in here to explain
mdempsky 2015/12/19 02:14:48 I'll add some. (To be fair, I preserved *both* of
+class CommonAsyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>>
+ : public Message {
+ public:
+ using Schema = MessageSchema<base::Tuple<Ins...>>;
+ using Param = typename Schema::Param;
+ enum { ID = Id };
+
+ CommonAsyncMessage(int32_t routing_id, const Ins&... ins);
+
+ static bool Read(const Message* msg, Param* p);
+ static void Log(std::string* name, const Message* msg, std::string* l);
+
+ template <class T, class S, class P, class Method>
+ static bool Dispatch(const Message* msg,
+ T* obj,
+ S* sender,
+ P* parameter,
+ Method func) {
+ Param p;
+ if (Read(msg, &p)) {
+ DispatchToMethod(obj, func, parameter, p);
+ return true;
+ }
+ return false;
+ }
+};
+
+template <uint32_t Id, const char* Name, typename InTuple, typename OutTuple>
+class CommonSyncMessage;
+
+template <uint32_t Id, const char* Name, typename... Ins, typename... Outs>
+class CommonSyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<Outs...>>
+ : public SyncMessage {
+ public:
+ using Schema = SyncMessageSchema<
+ base::Tuple<Ins...>,
+ typename base::TupleTypes<base::Tuple<Outs...>>::RefTuple>;
+ using ReplyParam = typename Schema::ReplyParam;
+ using SendParam = typename Schema::SendParam;
+ enum { ID = Id };
+
+ CommonSyncMessage(int32_t routing_id, const Ins&... ins, Outs*... outs);
+
+ static bool ReadSendParam(const Message* msg, SendParam* p);
+ static bool ReadReplyParam(
+ const Message* msg,
+ typename base::TupleTypes<ReplyParam>::ValueTuple* p);
+ static void Log(std::string* name, const Message* msg, std::string* l);
+
+ template <class T, class S, class P, class Method>
+ static bool Dispatch(const Message* msg,
+ T* obj,
+ S* sender,
+ P* parameter,
+ Method func) {
+ SendParam send_params;
+ bool ok = ReadSendParam(msg, &send_params);
+ return Schema::DispatchWithSendParams(ok, send_params, msg, obj, sender,
+ func);
+ }
+
+ template <class T, class P, class Method>
+ static bool DispatchDelayReply(const Message* msg,
+ T* obj,
+ P* parameter,
+ Method func) {
+ SendParam send_params;
+ bool ok = ReadSendParam(msg, &send_params);
+ return Schema::DispatchDelayReplyWithSendParams(ok, send_params, msg, obj,
+ func);
+ }
+
+ template <typename... Args>
+ static void WriteReplyParams(Message* reply, Args... args) {
+ Schema::WriteReplyParams(reply, args...);
+ }
+};
+
+template <uint32_t Id, const char* Name, typename InTuple, typename OutTuple>
+class AsyncControlMessage;
+
+template <uint32_t Id, const char* Name, typename... Ins>
+class AsyncControlMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>>
+ : public CommonAsyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>> {
+ public:
+ AsyncControlMessage(const Ins&... ins)
+ : CommonAsyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>>(
+ MSG_ROUTING_CONTROL,
+ ins...) {}
+};
+
+template <uint32_t Id, const char* Name, typename InTuple, typename OutTuple>
+class AsyncRoutedMessage;
+
+template <uint32_t Id, const char* Name, typename... Ins>
+class AsyncRoutedMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>>
+ : public CommonAsyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>> {
+ public:
+ AsyncRoutedMessage(int32_t routing_id, const Ins&... ins)
+ : CommonAsyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<>>(
+ routing_id,
+ ins...) {}
+};
+
+template <uint32_t Id, const char* Name, typename InTuple, typename OutTuple>
+class SyncControlMessage;
+
+template <uint32_t Id, const char* Name, typename... Ins, typename... Outs>
+class SyncControlMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<Outs...>>
+ : public CommonSyncMessage<Id,
+ Name,
+ base::Tuple<Ins...>,
+ base::Tuple<Outs...>> {
+ public:
+ SyncControlMessage(const Ins&... ins, Outs*... outs)
+ : CommonSyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<Outs...>>(
+ MSG_ROUTING_CONTROL,
+ ins...,
+ outs...) {}
+};
+
+template <uint32_t Id, const char* Name, typename InTuple, typename OutTuple>
+class SyncRoutedMessage;
+
+template <uint32_t Id, const char* Name, typename... Ins, typename... Outs>
+class SyncRoutedMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<Outs...>>
+ : public CommonSyncMessage<Id,
+ Name,
+ base::Tuple<Ins...>,
+ base::Tuple<Outs...>> {
+ public:
+ SyncRoutedMessage(int32_t routing_id, const Ins&... ins, Outs*... outs)
+ : CommonSyncMessage<Id, Name, base::Tuple<Ins...>, base::Tuple<Outs...>>(
+ routing_id,
+ ins...,
+ outs...) {}
+};
+
+} // namespace IPC
+
+#if defined(IPC_MESSAGE_IMPL)
+#include "ipc/ipc_message_templates_impl.h"
+#endif
+
+#endif // IPC_IPC_MESSAGE_TEMPLATES_H_

Powered by Google App Engine
This is Rietveld 408576698