summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authordarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-26 21:27:30 +0000
committerdarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-26 21:27:30 +0000
commit1d4ecf498386569dfb438f7536b573213bbcaaba (patch)
tree2f05a90aa931e14aac6f9acee38ba471b5e55ea4 /ipc
parent80f6c7266b94973ce98e96ff743507a750dd7ae0 (diff)
downloadchromium_src-1d4ecf498386569dfb438f7536b573213bbcaaba.zip
chromium_src-1d4ecf498386569dfb438f7536b573213bbcaaba.tar.gz
chromium_src-1d4ecf498386569dfb438f7536b573213bbcaaba.tar.bz2
Add support for exporting IPC messages from component DLLs.
This removes MessageWithTuple and MessageWithReply since it is not easy to export a class that inherits from a template specialization. The functionality of those classes are split now between new classes, MessageSchema and SyncMessageSchema, and being declared inline via macros. The key point is that we want to avoid inlining the constructor and Read functions for messages. That avoids code bloat since those functions contain all of the parameter serialization and deserialization code. Those are the functions that we really want to have contained with component DLLs. To export IPC messages from a DLL, it is necessary to #define IPC_MESSAGE_EXPORT above message declarations. You can see this in action here: http://codereview.chromium.org/7687005/diff/41012/ppapi/proxy/ppapi_messages.h Review URL: http://codereview.chromium.org/7768001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@98491 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc')
-rw-r--r--ipc/ipc_fuzzing_tests.cc69
-rw-r--r--ipc/ipc_message_macros.h295
-rw-r--r--ipc/ipc_message_utils.h162
-rw-r--r--ipc/ipc_message_utils_impl.h29
-rw-r--r--ipc/sync_socket_unittest.cc83
5 files changed, 325 insertions, 313 deletions
diff --git a/ipc/ipc_fuzzing_tests.cc b/ipc/ipc_fuzzing_tests.cc
index 7c96587..c7076cc 100644
--- a/ipc/ipc_fuzzing_tests.cc
+++ b/ipc/ipc_fuzzing_tests.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -11,12 +11,31 @@
#include "base/threading/platform_thread.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_proxy.h"
-#include "ipc/ipc_message_utils.h"
-#include "ipc/ipc_message_utils_impl.h"
#include "ipc/ipc_tests.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"
+// IPC messages for testing ---------------------------------------------------
+
+#define IPC_MESSAGE_IMPL
+#include "ipc/ipc_message_macros.h"
+
+#define IPC_MESSAGE_START TestMsgStart
+
+// Generic message class that is an int followed by a wstring.
+IPC_MESSAGE_CONTROL2(MsgClassIS, int, std::wstring)
+
+// Generic message class that is a wstring followed by an int.
+IPC_MESSAGE_CONTROL2(MsgClassSI, std::wstring, int)
+
+// Message to create a mutex in the IPC server, using the received name.
+IPC_MESSAGE_CONTROL2(MsgDoMutex, std::wstring, int)
+
+// Used to generate an ID for a message that should not exist.
+IPC_MESSAGE_CONTROL0(MsgUnhandled)
+
+// ----------------------------------------------------------------------------
+
TEST(IPCMessageIntegrity, ReadBeyondBufferStr) {
//This was BUG 984408.
uint32 v1 = kuint32max - 1;
@@ -96,46 +115,6 @@ TEST(IPCMessageIntegrity, ReadVectorTooLarge2) {
EXPECT_FALSE(ReadParam(&m, &iter, &vec));
}
-// We don't actually use the messages defined in this file, but we do this
-// to get to the IPC macros.
-#include "ipc/ipc_sync_message_unittest.h"
-
-enum IPCMessageIds {
- UNUSED_IPC_TYPE,
- SERVER_FIRST_IPC_TYPE, // 1st Test message tag.
- SERVER_SECOND_IPC_TYPE, // 2nd Test message tag.
- SERVER_THIRD_IPC_TYPE, // 3rd Test message tag.
- CLIENT_MALFORMED_IPC, // Sent to client if server detects bad message.
- CLIENT_UNHANDLED_IPC // Sent to client if server detects unhanded IPC.
-};
-
-// Generic message class that is an int followed by a wstring.
-class MsgClassIS : public IPC::MessageWithTuple< Tuple2<int, std::wstring> > {
- public:
- enum { ID = SERVER_FIRST_IPC_TYPE };
- MsgClassIS(const int& arg1, const std::wstring& arg2)
- : IPC::MessageWithTuple< Tuple2<int, std::wstring> >(
- MSG_ROUTING_CONTROL, ID, MakeRefTuple(arg1, arg2)) {}
-};
-
-// Generic message class that is a wstring followed by an int.
-class MsgClassSI : public IPC::MessageWithTuple< Tuple2<std::wstring, int> > {
- public:
- enum { ID = SERVER_SECOND_IPC_TYPE };
- MsgClassSI(const std::wstring& arg1, const int& arg2)
- : IPC::MessageWithTuple< Tuple2<std::wstring, int> >(
- MSG_ROUTING_CONTROL, ID, MakeRefTuple(arg1, arg2)) {}
-};
-
-// Message to create a mutex in the IPC server, using the received name.
-class MsgDoMutex : public IPC::MessageWithTuple< Tuple2<std::wstring, int> > {
- public:
- enum { ID = SERVER_THIRD_IPC_TYPE };
- MsgDoMutex(const std::wstring& mutex_name, const int& unused)
- : IPC::MessageWithTuple< Tuple2<std::wstring, int> >(
- MSG_ROUTING_CONTROL, ID, MakeRefTuple(mutex_name, unused)) {}
-};
-
class SimpleListener : public IPC::Channel::Listener {
public:
SimpleListener() : other_(NULL) {
@@ -202,7 +181,7 @@ class FuzzerServerListener : public SimpleListener {
}
void ReplyMsgNotHandled(uint32 type_id) {
- RoundtripAckReply(FUZZER_ROUTING_ID, CLIENT_UNHANDLED_IPC, type_id);
+ RoundtripAckReply(FUZZER_ROUTING_ID, MsgUnhandled::ID, type_id);
Cleanup();
}
@@ -249,7 +228,7 @@ class FuzzerClientListener : public SimpleListener {
}
bool ExpectMsgNotHandled(uint32 type_id) {
- return ExpectMessage(type_id, CLIENT_UNHANDLED_IPC);
+ return ExpectMessage(type_id, MsgUnhandled::ID);
}
private:
diff --git a/ipc/ipc_message_macros.h b/ipc/ipc_message_macros.h
index f0b847d..63faa48 100644
--- a/ipc/ipc_message_macros.h
+++ b/ipc/ipc_message_macros.h
@@ -194,6 +194,11 @@
#define IPC_STRUCT_MEMBER(type, name) type name;
#define IPC_STRUCT_END() };
+// Override this to force message classes to be exported.
+#ifndef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT
+#endif
+
// Message macros collect specific numbers of arguments and funnel them into
// the common message generation macro. These should never be redefined.
#define IPC_MESSAGE_CONTROL0(msg_class) \
@@ -412,6 +417,174 @@
#define IPC_SYNC_MESSAGE_ROUTED5_4(msg_class, type1_in, type2_in, type3_in, type4_in, type5_in, type1_out, type2_out, type3_out, type4_out) \
IPC_MESSAGE_DECL(SYNC, ROUTED, msg_class, 5, 4, (type1_in, type2_in, type3_in, type4_in, type5_in), (type1_out, type2_out, type3_out, type4_out))
+// The following macros define the common set of methods provided by ASYNC
+// message classes.
+#define IPC_ASYNC_MESSAGE_METHODS_GENERIC \
+ template<class T, class S, class Method> \
+ static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) { \
+ Schema::Param p; \
+ if (Read(msg, &p)) { \
+ DispatchToMethod(obj, func, p); \
+ return true; \
+ } \
+ return false; \
+ }
+#define IPC_ASYNC_MESSAGE_METHODS_1 \
+ IPC_ASYNC_MESSAGE_METHODS_GENERIC \
+ template<class T, class S, typename TA> \
+ static bool Dispatch(const Message* msg, T* obj, S* sender, \
+ void (T::*func)(const Message&, TA)) { \
+ Schema::Param p; \
+ if (Read(msg, &p)) { \
+ (obj->*func)(*msg, p.a); \
+ return true; \
+ } \
+ return false; \
+ }
+#define IPC_ASYNC_MESSAGE_METHODS_2 \
+ IPC_ASYNC_MESSAGE_METHODS_GENERIC \
+ template<class T, class S, typename TA, typename TB> \
+ static bool Dispatch(const Message* msg, T* obj, S* sender, \
+ void (T::*func)(const Message&, TA, TB)) { \
+ Schema::Param p; \
+ if (Read(msg, &p)) { \
+ (obj->*func)(*msg, p.a, p.b); \
+ return true; \
+ } \
+ return false; \
+ } \
+ template<typename TA, typename TB> \
+ static bool Read(const IPC::Message* msg, TA* a, TB* b) { \
+ Schema::Param p; \
+ if (!Read(msg, &p)) \
+ return false; \
+ *a = p.a; \
+ *b = p.b; \
+ return true; \
+ }
+#define IPC_ASYNC_MESSAGE_METHODS_3 \
+ IPC_ASYNC_MESSAGE_METHODS_GENERIC \
+ template<class T, class S, typename TA, typename TB, typename TC> \
+ static bool Dispatch(const Message* msg, T* obj, S* sender, \
+ void (T::*func)(const Message&, TA, TB, TC)) { \
+ Schema::Param p; \
+ if (Read(msg, &p)) { \
+ (obj->*func)(*msg, p.a, p.b, p.c); \
+ return true; \
+ } \
+ return false; \
+ } \
+ template<typename TA, typename TB, typename TC> \
+ static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) { \
+ Schema::Param p; \
+ if (!Read(msg, &p)) \
+ return false; \
+ *a = p.a; \
+ *b = p.b; \
+ *c = p.c; \
+ return true; \
+ }
+#define IPC_ASYNC_MESSAGE_METHODS_4 \
+ IPC_ASYNC_MESSAGE_METHODS_GENERIC \
+ template<class T, class S, typename TA, typename TB, typename TC, \
+ typename TD> \
+ static bool Dispatch(const Message* msg, T* obj, S* sender, \
+ void (T::*func)(const Message&, TA, TB, TC, TD)) { \
+ Schema::Param p; \
+ if (Read(msg, &p)) { \
+ (obj->*func)(*msg, p.a, p.b, p.c, p.d); \
+ return true; \
+ } \
+ return false; \
+ } \
+ template<typename TA, typename TB, typename TC, typename TD> \
+ static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) { \
+ Schema::Param p; \
+ if (!Read(msg, &p)) \
+ return false; \
+ *a = p.a; \
+ *b = p.b; \
+ *c = p.c; \
+ *d = p.d; \
+ return true; \
+ }
+#define IPC_ASYNC_MESSAGE_METHODS_5 \
+ IPC_ASYNC_MESSAGE_METHODS_GENERIC \
+ template<class T, class S, typename TA, typename TB, typename TC, \
+ typename TD, typename TE> \
+ static bool Dispatch(const Message* msg, T* obj, S* sender, \
+ void (T::*func)(const Message&, TA, TB, TC, TD, TE)) { \
+ Schema::Param p; \
+ if (Read(msg, &p)) { \
+ (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e); \
+ return true; \
+ } \
+ return false; \
+ } \
+ template<typename TA, typename TB, typename TC, typename TD, typename TE> \
+ static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, \
+ TE* e) { \
+ Schema::Param p; \
+ if (!Read(msg, &p)) \
+ return false; \
+ *a = p.a; \
+ *b = p.b; \
+ *c = p.c; \
+ *d = p.d; \
+ *e = p.e; \
+ return true; \
+ }
+
+// The following macros define the common set of methods provided by SYNC
+// message classes.
+#define IPC_SYNC_MESSAGE_METHODS_GENERIC \
+ template<class T, class S, class Method> \
+ static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) { \
+ Schema::SendParam send_params; \
+ bool ok = ReadSendParam(msg, &send_params); \
+ return Schema::DispatchWithSendParams(ok, send_params, msg, obj, sender, \
+ func); \
+ } \
+ template<class T, class Method> \
+ static bool DispatchDelayReply(const Message* msg, T* obj, Method func) { \
+ Schema::SendParam send_params; \
+ bool ok = ReadSendParam(msg, &send_params); \
+ return Schema::DispatchDelayReplyWithSendParams(ok, send_params, msg, \
+ obj, func); \
+ }
+#define IPC_SYNC_MESSAGE_METHODS_0 \
+ IPC_SYNC_MESSAGE_METHODS_GENERIC
+#define IPC_SYNC_MESSAGE_METHODS_1 \
+ IPC_SYNC_MESSAGE_METHODS_GENERIC \
+ template<typename TA> \
+ static void WriteReplyParams(Message* reply, TA a) { \
+ Schema::WriteReplyParams(reply, a); \
+ }
+#define IPC_SYNC_MESSAGE_METHODS_2 \
+ IPC_SYNC_MESSAGE_METHODS_GENERIC \
+ template<typename TA, typename TB> \
+ static void WriteReplyParams(Message* reply, TA a, TB b) { \
+ Schema::WriteReplyParams(reply, a, b); \
+ }
+#define IPC_SYNC_MESSAGE_METHODS_3 \
+ IPC_SYNC_MESSAGE_METHODS_GENERIC \
+ template<typename TA, typename TB, typename TC> \
+ static void WriteReplyParams(Message* reply, TA a, TB b, TC c) { \
+ Schema::WriteReplyParams(reply, a, b, c); \
+ }
+#define IPC_SYNC_MESSAGE_METHODS_4 \
+ IPC_SYNC_MESSAGE_METHODS_GENERIC \
+ template<typename TA, typename TB, typename TC, typename TD> \
+ static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) { \
+ Schema::WriteReplyParams(reply, a, b, c, d); \
+ }
+#define IPC_SYNC_MESSAGE_METHODS_5 \
+ IPC_SYNC_MESSAGE_METHODS_GENERIC \
+ template<typename TA, typename TB, typename TC, typename TD, typename TE> \
+ static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) { \
+ Schema::WriteReplyParams(reply, a, b, c, d, e); \
+ }
+
// Common message macro which dispatches into one of the 6 (sync x kind)
// routines. There is a way that these 6 cases can be lumped together,
// but the macros get very complicated in that case.
@@ -424,6 +597,7 @@
#define IPC_EMPTY_CONTROL_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \
class msg_class : public IPC::Message { \
public: \
+ typedef IPC::Message Schema; \
enum { ID = IPC_MESSAGE_ID() }; \
msg_class() : IPC::Message(MSG_ROUTING_CONTROL, ID, PRIORITY_NORMAL) {} \
};
@@ -431,50 +605,66 @@
#define IPC_EMPTY_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \
class msg_class : public IPC::Message { \
public: \
+ typedef IPC::Message Schema; \
enum { ID = IPC_MESSAGE_ID() }; \
msg_class(int32 routing_id) \
: IPC::Message(routing_id, ID, PRIORITY_NORMAL) {} \
};
#define IPC_ASYNC_CONTROL_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \
- class msg_class : \
- public IPC::MessageWithTuple<IPC_TUPLE_IN_##in_cnt in_list> { \
+ class IPC_MESSAGE_EXPORT msg_class : public IPC::Message { \
public: \
+ typedef IPC::MessageSchema<IPC_TUPLE_IN_##in_cnt in_list> Schema; \
+ typedef Schema::Param Param; \
enum { ID = IPC_MESSAGE_ID() }; \
msg_class(IPC_TYPE_IN_##in_cnt in_list); \
virtual ~msg_class(); \
+ static bool Read(const Message* msg, Schema::Param* p); \
static void Log(std::string* name, const Message* msg, std::string* l); \
+ IPC_ASYNC_MESSAGE_METHODS_##in_cnt \
};
#define IPC_ASYNC_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \
- class msg_class : \
- public IPC::MessageWithTuple<IPC_TUPLE_IN_##in_cnt in_list> { \
+ class IPC_MESSAGE_EXPORT msg_class : public IPC::Message { \
public: \
+ typedef IPC::MessageSchema<IPC_TUPLE_IN_##in_cnt in_list> Schema; \
+ typedef Schema::Param Param; \
enum { ID = IPC_MESSAGE_ID() }; \
msg_class(int32 routing_id IPC_COMMA_##in_cnt \
IPC_TYPE_IN_##in_cnt in_list); \
virtual ~msg_class(); \
+ static bool Read(const Message* msg, Schema::Param* p); \
static void Log(std::string* name, const Message* msg, std::string* l); \
+ IPC_ASYNC_MESSAGE_METHODS_##in_cnt \
};
#define IPC_SYNC_CONTROL_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \
- class msg_class : \
- public IPC::MessageWithReply<IPC_TUPLE_IN_##in_cnt in_list, \
- IPC_TUPLE_OUT_##out_cnt out_list> { \
+ class IPC_MESSAGE_EXPORT msg_class : public IPC::SyncMessage { \
public: \
+ typedef IPC::SyncMessageSchema<IPC_TUPLE_IN_##in_cnt in_list, \
+ IPC_TUPLE_OUT_##out_cnt out_list> Schema; \
+ typedef Schema::ReplyParam ReplyParam; \
+ typedef Schema::SendParam SendParam; \
enum { ID = IPC_MESSAGE_ID() }; \
msg_class(IPC_TYPE_IN_##in_cnt in_list \
IPC_COMMA_AND_##in_cnt(IPC_COMMA_##out_cnt) \
IPC_TYPE_OUT_##out_cnt out_list); \
virtual ~msg_class(); \
+ static bool ReadSendParam(const Message* msg, Schema::SendParam* p); \
+ static bool ReadReplyParam( \
+ const Message* msg, \
+ TupleTypes<ReplyParam>::ValueTuple* p); \
static void Log(std::string* name, const Message* msg, std::string* l); \
+ IPC_SYNC_MESSAGE_METHODS_##out_cnt \
};
#define IPC_SYNC_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \
- class msg_class : \
- public IPC::MessageWithReply<IPC_TUPLE_IN_##in_cnt in_list, \
- IPC_TUPLE_OUT_##out_cnt out_list> { \
+ class IPC_MESSAGE_EXPORT msg_class : public IPC::SyncMessage { \
public: \
+ typedef IPC::SyncMessageSchema<IPC_TUPLE_IN_##in_cnt in_list, \
+ IPC_TUPLE_OUT_##out_cnt out_list> Schema; \
+ typedef Schema::ReplyParam ReplyParam; \
+ typedef Schema::SendParam SendParam; \
enum { ID = IPC_MESSAGE_ID() }; \
msg_class(int32 routing_id \
IPC_COMMA_OR_##in_cnt(IPC_COMMA_##out_cnt) \
@@ -482,7 +672,12 @@
IPC_COMMA_AND_##in_cnt(IPC_COMMA_##out_cnt) \
IPC_TYPE_OUT_##out_cnt out_list); \
virtual ~msg_class(); \
+ static bool ReadSendParam(const Message* msg, Schema::SendParam* p); \
+ static bool ReadReplyParam( \
+ const Message* msg, \
+ TupleTypes<ReplyParam>::ValueTuple* p); \
static void Log(std::string* name, const Message* msg, std::string* l); \
+ IPC_SYNC_MESSAGE_METHODS_##out_cnt \
};
#if defined(IPC_MESSAGE_IMPL)
@@ -501,30 +696,42 @@
#define IPC_ASYNC_CONTROL_IMPL(msg_class, in_cnt, out_cnt, in_list, out_list) \
msg_class::msg_class(IPC_TYPE_IN_##in_cnt in_list) : \
- IPC::MessageWithTuple<IPC_TUPLE_IN_##in_cnt in_list> \
- (MSG_ROUTING_CONTROL, ID, IPC_NAME_IN_##in_cnt in_list) \
- {} \
- msg_class::~msg_class() {}
+ IPC::Message(MSG_ROUTING_CONTROL, ID, PRIORITY_NORMAL) { \
+ Schema::Write(this, IPC_NAME_IN_##in_cnt in_list); \
+ } \
+ msg_class::~msg_class() {} \
+ bool msg_class::Read(const Message* msg, Schema::Param* p) { \
+ return Schema::Read(msg, p); \
+ }
#define IPC_ASYNC_ROUTED_IMPL(msg_class, in_cnt, out_cnt, in_list, out_list) \
msg_class::msg_class(int32 routing_id IPC_COMMA_##in_cnt \
IPC_TYPE_IN_##in_cnt in_list) : \
- IPC::MessageWithTuple<IPC_TUPLE_IN_##in_cnt in_list> \
- (routing_id, ID, IPC_NAME_IN_##in_cnt in_list) \
- {} \
- msg_class::~msg_class() {}
+ IPC::Message(routing_id, ID, PRIORITY_NORMAL) { \
+ Schema::Write(this, IPC_NAME_IN_##in_cnt in_list); \
+ } \
+ msg_class::~msg_class() {} \
+ bool msg_class::Read(const Message* msg, Schema::Param* p) { \
+ return Schema::Read(msg, p); \
+ }
#define IPC_SYNC_CONTROL_IMPL(msg_class, in_cnt, out_cnt, in_list, out_list) \
msg_class::msg_class(IPC_TYPE_IN_##in_cnt in_list \
IPC_COMMA_AND_##in_cnt(IPC_COMMA_##out_cnt) \
IPC_TYPE_OUT_##out_cnt out_list) : \
- IPC::MessageWithReply<IPC_TUPLE_IN_##in_cnt in_list, \
- IPC_TUPLE_OUT_##out_cnt out_list> \
- (MSG_ROUTING_CONTROL, ID, \
- IPC_NAME_IN_##in_cnt in_list, \
- IPC_NAME_OUT_##out_cnt out_list) \
- {} \
- msg_class::~msg_class() {}
+ IPC::SyncMessage(MSG_ROUTING_CONTROL, ID, PRIORITY_NORMAL, \
+ new IPC::ParamDeserializer<Schema::ReplyParam>( \
+ IPC_NAME_OUT_##out_cnt out_list)) { \
+ Schema::Write(this, IPC_NAME_IN_##in_cnt in_list); \
+ } \
+ msg_class::~msg_class() {} \
+ bool msg_class::ReadSendParam(const Message* msg, Schema::SendParam* p) { \
+ return Schema::ReadSendParam(msg, p); \
+ } \
+ bool msg_class::ReadReplyParam(const Message* msg, \
+ TupleTypes<ReplyParam>::ValueTuple* p) { \
+ return Schema::ReadReplyParam(msg, p); \
+ }
#define IPC_SYNC_ROUTED_IMPL(msg_class, in_cnt, out_cnt, in_list, out_list) \
msg_class::msg_class(int32 routing_id \
@@ -532,13 +739,19 @@
IPC_TYPE_IN_##in_cnt in_list \
IPC_COMMA_AND_##in_cnt(IPC_COMMA_##out_cnt) \
IPC_TYPE_OUT_##out_cnt out_list) : \
- IPC::MessageWithReply<IPC_TUPLE_IN_##in_cnt in_list, \
- IPC_TUPLE_OUT_##out_cnt out_list> \
- (routing_id, ID, \
- IPC_NAME_IN_##in_cnt in_list, \
- IPC_NAME_OUT_##out_cnt out_list) \
- {} \
- msg_class::~msg_class() {}
+ IPC::SyncMessage(routing_id, ID, PRIORITY_NORMAL, \
+ new IPC::ParamDeserializer<Schema::ReplyParam>( \
+ IPC_NAME_OUT_##out_cnt out_list)) { \
+ Schema::Write(this, IPC_NAME_IN_##in_cnt in_list); \
+ } \
+ msg_class::~msg_class() {} \
+ bool msg_class::ReadSendParam(const Message* msg, Schema::SendParam* p) { \
+ return Schema::ReadSendParam(msg, p); \
+ } \
+ bool msg_class::ReadReplyParam(const Message* msg, \
+ TupleTypes<ReplyParam>::ValueTuple* p) { \
+ return Schema::ReadReplyParam(msg, p); \
+ }
#define IPC_EMPTY_MESSAGE_LOG(msg_class)
@@ -550,8 +763,8 @@
*name = #msg_class; \
if (!msg || !l) \
return; \
- Param p; \
- if (Read(msg, &p)) \
+ Schema::Param p; \
+ if (Schema::Read(msg, &p)) \
IPC::LogParam(p, l); \
}
@@ -564,13 +777,13 @@
if (!msg || !l) \
return; \
if (msg->is_sync()) { \
- TupleTypes<SendParam>::ValueTuple p; \
- if (ReadSendParam(msg, &p)) \
+ TupleTypes<Schema::SendParam>::ValueTuple p; \
+ if (Schema::ReadSendParam(msg, &p)) \
IPC::LogParam(p, l); \
AddOutputParamsToLog(msg, l); \
} else { \
- TupleTypes<ReplyParam>::ValueTuple p; \
- if (ReadReplyParam(msg, &p)) \
+ TupleTypes<Schema::ReplyParam>::ValueTuple p; \
+ if (Schema::ReadReplyParam(msg, &p)) \
IPC::LogParam(p, l); \
} \
}
@@ -722,7 +935,8 @@ LogFunctionMap g_log_function_mapping;
#define IPC_MESSAGE_FORWARD(msg_class, obj, member_func) \
case msg_class::ID: \
- msg_is_ok__ = msg_class::Dispatch(&ipc_message__, obj, this, &member_func); \
+ msg_is_ok__ = msg_class::Dispatch(&ipc_message__, obj, this, \
+ &member_func); \
break;
#define IPC_MESSAGE_HANDLER(msg_class, member_func) \
@@ -730,7 +944,8 @@ LogFunctionMap g_log_function_mapping;
#define IPC_MESSAGE_FORWARD_DELAY_REPLY(msg_class, obj, member_func) \
case msg_class::ID: \
- msg_is_ok__ = msg_class::DispatchDelayReply(&ipc_message__, obj, &member_func); \
+ msg_is_ok__ = msg_class::DispatchDelayReply(&ipc_message__, obj, \
+ &member_func); \
break;
#define IPC_MESSAGE_HANDLER_DELAY_REPLY(msg_class, member_func) \
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h
index ae7490c..9da9eba4 100644
--- a/ipc/ipc_message_utils.h
+++ b/ipc/ipc_message_utils.h
@@ -944,136 +944,13 @@ struct ParamTraits< Tuple5<A, B, C, D, E> > {
// Used for asynchronous messages.
template <class ParamType>
-class MessageWithTuple : public Message {
+class MessageSchema {
public:
typedef ParamType Param;
typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
- // The constructor and the Read() method's templated implementations are in
- // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
- // the templated versions of these and make sure there are instantiations in
- // those translation units.
- MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
-
+ static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
-
- // Generic dispatcher. Should cover most cases.
- template<class T, class S, class Method>
- static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
- Param p;
- if (Read(msg, &p)) {
- DispatchToMethod(obj, func, p);
- return true;
- }
- return false;
- }
-
- // The following dispatchers exist for the case where the callback function
- // needs the message as well. They assume that "Param" is a type of Tuple
- // (except the one arg case, as there is no Tuple1).
- template<class T, class S, typename TA>
- static bool Dispatch(const Message* msg, T* obj, S* sender,
- void (T::*func)(const Message&, TA)) {
- Param p;
- if (Read(msg, &p)) {
- (obj->*func)(*msg, p.a);
- return true;
- }
- return false;
- }
-
- template<class T, class S, typename TA, typename TB>
- static bool Dispatch(const Message* msg, T* obj, S* sender,
- void (T::*func)(const Message&, TA, TB)) {
- Param p;
- if (Read(msg, &p)) {
- (obj->*func)(*msg, p.a, p.b);
- return true;
- }
- return false;
- }
-
- template<class T, class S, typename TA, typename TB, typename TC>
- static bool Dispatch(const Message* msg, T* obj, S* sender,
- void (T::*func)(const Message&, TA, TB, TC)) {
- Param p;
- if (Read(msg, &p)) {
- (obj->*func)(*msg, p.a, p.b, p.c);
- return true;
- }
- return false;
- }
-
- template<class T, class S, typename TA, typename TB, typename TC, typename TD>
- static bool Dispatch(const Message* msg, T* obj, S* sender,
- void (T::*func)(const Message&, TA, TB, TC, TD)) {
- Param p;
- if (Read(msg, &p)) {
- (obj->*func)(*msg, p.a, p.b, p.c, p.d);
- return true;
- }
- return false;
- }
-
- template<class T, class S, typename TA, typename TB, typename TC, typename TD,
- typename TE>
- static bool Dispatch(const Message* msg, T* obj, S* sender,
- void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
- Param p;
- if (Read(msg, &p)) {
- (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
- return true;
- }
- return false;
- }
-
- // Functions used to do manual unpacking. Only used by the automation code,
- // these should go away once that code uses SyncChannel.
- template<typename TA, typename TB>
- static bool Read(const IPC::Message* msg, TA* a, TB* b) {
- ParamType params;
- if (!Read(msg, &params))
- return false;
- *a = params.a;
- *b = params.b;
- return true;
- }
-
- template<typename TA, typename TB, typename TC>
- static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
- ParamType params;
- if (!Read(msg, &params))
- return false;
- *a = params.a;
- *b = params.b;
- *c = params.c;
- return true;
- }
-
- template<typename TA, typename TB, typename TC, typename TD>
- static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
- ParamType params;
- if (!Read(msg, &params))
- return false;
- *a = params.a;
- *b = params.b;
- *c = params.c;
- *d = params.d;
- return true;
- }
-
- template<typename TA, typename TB, typename TC, typename TD, typename TE>
- static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
- ParamType params;
- if (!Read(msg, &params))
- return false;
- *a = params.a;
- *b = params.b;
- *c = params.c;
- *d = params.d;
- *e = params.e;
- return true;
- }
};
// defined in ipc_logging.cc
@@ -1139,57 +1016,52 @@ class ParamDeserializer : public MessageReplyDeserializer {
// Used for synchronous messages.
template <class SendParamType, class ReplyParamType>
-class MessageWithReply : public SyncMessage {
+class SyncMessageSchema {
public:
typedef SendParamType SendParam;
typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
typedef ReplyParamType ReplyParam;
- MessageWithReply(int32 routing_id, uint32 type,
- const RefSendParam& send, const ReplyParam& reply);
+ static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
static bool ReadReplyParam(
const Message* msg,
typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
template<class T, class S, class Method>
- static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
- SendParam send_params;
- Message* reply = GenerateReply(msg);
- bool error;
- if (ReadSendParam(msg, &send_params)) {
+ static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
+ const Message* msg, T* obj, S* sender,
+ Method func) {
+ Message* reply = SyncMessage::GenerateReply(msg);
+ if (ok) {
typename TupleTypes<ReplyParam>::ValueTuple reply_params;
DispatchToMethod(obj, func, send_params, &reply_params);
WriteParam(reply, reply_params);
- error = false;
LogReplyParamsToMessage(reply_params, msg);
} else {
NOTREACHED() << "Error deserializing message " << msg->type();
reply->set_reply_error();
- error = true;
}
-
sender->Send(reply);
- return !error;
+ return ok;
}
template<class T, class Method>
- static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
- SendParam send_params;
- Message* reply = GenerateReply(msg);
- bool error;
- if (ReadSendParam(msg, &send_params)) {
+ static bool DispatchDelayReplyWithSendParams(bool ok,
+ const SendParam& send_params,
+ const Message* msg, T* obj,
+ Method func) {
+ Message* reply = SyncMessage::GenerateReply(msg);
+ if (ok) {
Tuple1<Message&> t = MakeRefTuple(*reply);
ConnectMessageAndReply(msg, reply);
DispatchToMethod(obj, func, send_params, &t);
- error = false;
} else {
NOTREACHED() << "Error deserializing message " << msg->type();
reply->set_reply_error();
obj->Send(reply);
- error = true;
}
- return !error;
+ return ok;
}
template<typename TA>
diff --git a/ipc/ipc_message_utils_impl.h b/ipc/ipc_message_utils_impl.h
index 98e62c8..f078b2a 100644
--- a/ipc/ipc_message_utils_impl.h
+++ b/ipc/ipc_message_utils_impl.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
//
@@ -12,14 +12,12 @@
namespace IPC {
template <class ParamType>
-MessageWithTuple<ParamType>::MessageWithTuple(
- int32 routing_id, uint32 type, const RefParam& p)
- : Message(routing_id, type, PRIORITY_NORMAL) {
- WriteParam(this, p);
+void MessageSchema<ParamType>::Write(Message* msg, const RefParam& p) {
+ WriteParam(msg, p);
}
template <class ParamType>
-bool MessageWithTuple<ParamType>::Read(const Message* msg, Param* p) {
+bool MessageSchema<ParamType>::Read(const Message* msg, Param* p) {
void* iter = NULL;
if (ReadParam(msg, &iter, p))
return true;
@@ -27,29 +25,22 @@ bool MessageWithTuple<ParamType>::Read(const Message* msg, Param* p) {
return false;
}
-// We can't migrate the template for Log() to MessageWithTuple, because each
-// subclass needs to have Log() to call Read(), which instantiates the above
-// template.
-
template <class SendParamType, class ReplyParamType>
-MessageWithReply<SendParamType, ReplyParamType>::MessageWithReply(
- int32 routing_id, uint32 type,
- const RefSendParam& send,
- const ReplyParam& reply)
- : SyncMessage(routing_id, type, PRIORITY_NORMAL,
- new ParamDeserializer<ReplyParam>(reply)) {
- WriteParam(this, send);
+void SyncMessageSchema<SendParamType, ReplyParamType>::Write(
+ Message* msg,
+ const RefSendParam& send) {
+ WriteParam(msg, send);
}
template <class SendParamType, class ReplyParamType>
-bool MessageWithReply<SendParamType, ReplyParamType>::ReadSendParam(
+bool SyncMessageSchema<SendParamType, ReplyParamType>::ReadSendParam(
const Message* msg, SendParam* p) {
void* iter = SyncMessage::GetDataIterator(msg);
return ReadParam(msg, &iter, p);
}
template <class SendParamType, class ReplyParamType>
-bool MessageWithReply<SendParamType, ReplyParamType>::ReadReplyParam(
+bool SyncMessageSchema<SendParamType, ReplyParamType>::ReadReplyParam(
const Message* msg, typename TupleTypes<ReplyParam>::ValueTuple* p) {
void* iter = SyncMessage::GetDataIterator(msg);
return ReadParam(msg, &iter, p);
diff --git a/ipc/sync_socket_unittest.cc b/ipc/sync_socket_unittest.cc
index 1a4ae13..79cf6c3 100644
--- a/ipc/sync_socket_unittest.cc
+++ b/ipc/sync_socket_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,12 +10,7 @@
#include "base/message_loop.h"
#include "base/process_util.h"
-#include "build/build_config.h"
-#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_proxy.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_message_utils.h"
-#include "ipc/ipc_message_utils_impl.h"
#include "ipc/ipc_tests.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"
@@ -24,74 +19,34 @@
#include "base/file_descriptor_posix.h"
#endif
-enum IPCMessageIds {
- UNUSED_IPC_TYPE,
- SERVER_FIRST_IPC_TYPE, // SetHandle message sent to server.
- SERVER_SECOND_IPC_TYPE, // Shutdown message sent to server.
- CLIENT_FIRST_IPC_TYPE // Response message sent to client.
-};
+// IPC messages for testing ---------------------------------------------------
-namespace {
-const char kHelloString[] = "Hello, SyncSocket Client";
-const size_t kHelloStringLength = arraysize(kHelloString);
-} // namespace
+#define IPC_MESSAGE_IMPL
+#include "ipc/ipc_message_macros.h"
+
+#define IPC_MESSAGE_START TestMsgStart
-// Message class to pass a base::SyncSocket::Handle to another process.
-// This is not as easy as it sounds, because of the differences in transferring
+// Message class to pass a base::SyncSocket::Handle to another process. This
+// is not as easy as it sounds, because of the differences in transferring
// Windows HANDLEs versus posix file descriptors.
#if defined(OS_WIN)
-class MsgClassSetHandle
- : public IPC::MessageWithTuple< Tuple1<base::SyncSocket::Handle> > {
- public:
- enum { ID = SERVER_FIRST_IPC_TYPE };
- explicit MsgClassSetHandle(const base::SyncSocket::Handle arg1)
- : IPC::MessageWithTuple< Tuple1<base::SyncSocket::Handle> >(
- MSG_ROUTING_CONTROL, ID, MakeRefTuple(arg1)) {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MsgClassSetHandle);
-};
+IPC_MESSAGE_CONTROL1(MsgClassSetHandle, base::SyncSocket::Handle)
#elif defined(OS_POSIX)
-class MsgClassSetHandle
- : public IPC::MessageWithTuple< Tuple1<base::FileDescriptor> > {
- public:
- enum { ID = SERVER_FIRST_IPC_TYPE };
- explicit MsgClassSetHandle(const base::FileDescriptor& arg1)
- : IPC::MessageWithTuple< Tuple1<base::FileDescriptor> >(
- MSG_ROUTING_CONTROL, ID, MakeRefTuple(arg1)) {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MsgClassSetHandle);
-};
-#else
-# error "What platform?"
-#endif // defined(OS_WIN)
+IPC_MESSAGE_CONTROL1(MsgClassSetHandle, base::FileDescriptor)
+#endif
// Message class to pass a response to the server.
-class MsgClassResponse
- : public IPC::MessageWithTuple< Tuple1<std::string> > {
- public:
- enum { ID = CLIENT_FIRST_IPC_TYPE };
- explicit MsgClassResponse(const std::string& arg1)
- : IPC::MessageWithTuple< Tuple1<std::string> >(
- MSG_ROUTING_CONTROL, ID, MakeRefTuple(arg1)) {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MsgClassResponse);
-};
+IPC_MESSAGE_CONTROL1(MsgClassResponse, std::string)
// Message class to tell the server to shut down.
-class MsgClassShutdown
- : public IPC::MessageWithTuple< Tuple0 > {
- public:
- enum { ID = SERVER_SECOND_IPC_TYPE };
- MsgClassShutdown()
- : IPC::MessageWithTuple< Tuple0 >(
- MSG_ROUTING_CONTROL, ID, MakeTuple()) {}
+IPC_MESSAGE_CONTROL0(MsgClassShutdown)
- private:
- DISALLOW_COPY_AND_ASSIGN(MsgClassShutdown);
-};
+// ----------------------------------------------------------------------------
+
+namespace {
+const char kHelloString[] = "Hello, SyncSocket Client";
+const size_t kHelloStringLength = arraysize(kHelloString);
+} // namespace
// The SyncSocket server listener class processes two sorts of
// messages from the client.