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

Unified Diff: ipc/ipc_message_utils.h

Issue 3106018: Reapplies all the IPC system work (reverts the revert r56272). (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Created 10 years, 4 months 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
« no previous file with comments | « ipc/ipc_message_macros.h ('k') | ipc/ipc_message_utils.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ipc/ipc_message_utils.h
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h
index 4667d4b234f75c102f2d19dbd2d29ef14d9e318d..05d39165f248fc0aebd4ed6a7af0fd005cee353e 100644
--- a/ipc/ipc_message_utils.h
+++ b/ipc/ipc_message_utils.h
@@ -12,22 +12,29 @@
#include <map>
#include <set>
-#include "base/file_path.h"
#include "base/format_macros.h"
-#include "base/nullable_string16.h"
#include "base/string16.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
-#include "base/time.h"
#include "base/tuple.h"
#include "base/utf_string_conversions.h"
-#include "base/values.h"
-#if defined(OS_POSIX)
-#include "ipc/file_descriptor_set_posix.h"
-#endif
-#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_sync_message.h"
+#if defined(COMPILER_GCC)
+// GCC "helpfully" tries to inline template methods in release mode. Except we
+// want the majority of the template junk being expanded once in the
+// implementation file (and only provide the definitions in
+// ipc_message_utils_impl.h in those files) and exported, instead of expanded
+// at every call site. Special note: GCC happily accepts the attribute before
+// the method declaration, but only acts on it if it is after.
+#define IPC_MSG_NOINLINE __attribute__((noinline));
+#elif defined(COMPILER_MSVC)
+// MSVC++ doesn't do this.
+#define IPC_MSG_NOINLINE
+#else
+#error "Please add the noinline property for your new compiler here."
+#endif
+
// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
// base. Messages have unique IDs across channels in order for the IPC logging
// code to figure out the message class from its ID.
@@ -67,8 +74,20 @@ enum IPCMessageStart {
LastMsgIndex
};
+class DictionaryValue;
+class FilePath;
+class ListValue;
+class NullableString16;
+
+namespace base {
+class Time;
+struct FileDescriptor;
+}
+
namespace IPC {
+struct ChannelHandle;
+
//-----------------------------------------------------------------------------
// An iterator class for reading the fields contained within a Message.
@@ -306,19 +325,9 @@ struct ParamTraits<wchar_t> {
template <>
struct ParamTraits<base::Time> {
typedef base::Time param_type;
- static void Write(Message* m, const param_type& p) {
- ParamTraits<int64>::Write(m, p.ToInternalValue());
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- int64 value;
- if (!ParamTraits<int64>::Read(m, iter, &value))
- return false;
- *r = base::Time::FromInternalValue(value);
- return true;
- }
- static void Log(const param_type& p, std::wstring* l) {
- ParamTraits<int64>::Log(p.ToInternalValue(), l);
- }
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::wstring* l);
};
#if defined(OS_WIN)
@@ -365,6 +374,9 @@ struct ParamTraits<MSG> {
return result;
}
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(L"<MSG>");
+ }
};
#endif // defined(OS_WIN)
@@ -598,27 +610,9 @@ struct ParamTraits<std::pair<A, B> > {
template <>
struct ParamTraits<NullableString16> {
typedef NullableString16 param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.string());
- WriteParam(m, p.is_null());
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- string16 string;
- if (!ReadParam(m, iter, &string))
- return false;
- bool is_null;
- if (!ReadParam(m, iter, &is_null))
- return false;
- *r = NullableString16(string, is_null);
- return true;
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(L"(");
- LogParam(p.string(), l);
- l->append(L", ");
- LogParam(p.is_null(), l);
- l->append(L")");
- }
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::wstring* l);
};
// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
@@ -709,19 +703,9 @@ struct ParamTraits<POINT> {
template <>
struct ParamTraits<FilePath> {
typedef FilePath param_type;
- static void Write(Message* m, const param_type& p) {
- ParamTraits<FilePath::StringType>::Write(m, p.value());
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- FilePath::StringType value;
- if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
- return false;
- *r = FilePath(value);
- return true;
- }
- static void Log(const param_type& p, std::wstring* l) {
- ParamTraits<FilePath::StringType>::Log(p.value(), l);
- }
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::wstring* l);
};
#if defined(OS_POSIX)
@@ -743,35 +727,9 @@ struct ParamTraits<FilePath> {
template<>
struct ParamTraits<base::FileDescriptor> {
typedef base::FileDescriptor param_type;
- static void Write(Message* m, const param_type& p) {
- const bool valid = p.fd >= 0;
- WriteParam(m, valid);
-
- if (valid) {
- if (!m->WriteFileDescriptor(p))
- NOTREACHED();
- }
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- bool valid;
- if (!ReadParam(m, iter, &valid))
- return false;
-
- if (!valid) {
- r->fd = -1;
- r->auto_close = false;
- return true;
- }
-
- return m->ReadFileDescriptor(iter, r);
- }
- static void Log(const param_type& p, std::wstring* l) {
- if (p.auto_close) {
- l->append(StringPrintf(L"FD(%d auto-close)", p.fd));
- } else {
- l->append(StringPrintf(L"FD(%d)", p.fd));
- }
- }
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::wstring* l);
};
#endif // defined(OS_POSIX)
@@ -781,26 +739,9 @@ struct ParamTraits<base::FileDescriptor> {
template<>
struct ParamTraits<IPC::ChannelHandle> {
typedef ChannelHandle param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.name);
-#if defined(OS_POSIX)
- WriteParam(m, p.socket);
-#endif
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return ReadParam(m, iter, &r->name)
-#if defined(OS_POSIX)
- && ReadParam(m, iter, &r->socket)
-#endif
- ;
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(ASCIIToWide(StringPrintf("ChannelHandle(%s", p.name.c_str())));
-#if defined(OS_POSIX)
- ParamTraits<base::FileDescriptor>::Log(p.socket, l);
-#endif
- l->append(L")");
- }
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::wstring* l);
};
#if defined(OS_WIN)
@@ -1026,20 +967,15 @@ template <class ParamType>
class MessageWithTuple : public Message {
public:
typedef ParamType Param;
- typedef typename ParamType::ParamTuple RefParam;
+ typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
- MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p)
- : Message(routing_id, type, PRIORITY_NORMAL) {
- WriteParam(this, p);
- }
+ // 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 bool Read(const Message* msg, Param* p) {
- void* iter = NULL;
- if (ReadParam(msg, &iter, p))
- return true;
- NOTREACHED() << "Error deserializing message " << msg->type();
- return false;
- }
+ static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
// Generic dispatcher. Should cover most cases.
template<class T, class Method>
@@ -1111,12 +1047,6 @@ class MessageWithTuple : public Message {
return false;
}
- static void Log(const Message* msg, std::wstring* l) {
- Param p;
- if (Read(msg, &p))
- LogParam(p, l);
- }
-
// 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>
@@ -1166,8 +1096,54 @@ class MessageWithTuple : public Message {
}
};
+// defined in ipc_logging.cc
+void GenerateLogData(const std::string& channel, const Message& message,
+ LogData* data);
+
+
+#if defined(IPC_MESSAGE_LOG_ENABLED)
+inline void AddOutputParamsToLog(const Message* msg, std::wstring* l) {
+ const std::wstring& output_params = msg->output_params();
+ if (!l->empty() && !output_params.empty())
+ l->append(L", ");
+
+ l->append(output_params);
+}
+
+template <class ReplyParamType>
+inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
+ const Message* msg) {
+ if (msg->received_time() != 0) {
+ std::wstring output_params;
+ LogParam(reply_params, &output_params);
+ msg->set_output_params(output_params);
+ }
+}
+
+inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
+ if (msg->sent_time()) {
+ // Don't log the sync message after dispatch, as we don't have the
+ // output parameters at that point. Instead, save its data and log it
+ // with the outgoing reply message when it's sent.
+ LogData* data = new LogData;
+ GenerateLogData("", *msg, data);
+ msg->set_dont_log();
+ reply->set_sync_log_data(data);
+ }
+}
+#else
+inline void AddOutputParamsToLog(const Message* msg, std::wstring* l) {}
+
+template <class ReplyParamType>
+inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
+ const Message* msg) {}
+
+inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
+#endif
+
// This class assumes that its template argument is a RefTuple (a Tuple with
-// reference elements).
+// reference elements). This would go into ipc_message_utils_impl.h, but it is
+// also used by chrome_frame.
template <class RefTuple>
class ParamDeserializer : public MessageReplyDeserializer {
public:
@@ -1180,67 +1156,32 @@ class ParamDeserializer : public MessageReplyDeserializer {
RefTuple out_;
};
-// defined in ipc_logging.cc
-void GenerateLogData(const std::string& channel, const Message& message,
- LogData* data);
-
// Used for synchronous messages.
template <class SendParamType, class ReplyParamType>
class MessageWithReply : public SyncMessage {
public:
typedef SendParamType SendParam;
- typedef typename SendParam::ParamTuple RefSendParam;
+ typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
typedef ReplyParamType ReplyParam;
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);
- }
-
- static void Log(const Message* msg, std::wstring* l) {
- if (msg->is_sync()) {
- SendParam p;
- void* iter = SyncMessage::GetDataIterator(msg);
- if (ReadParam(msg, &iter, &p))
- LogParam(p, l);
-
-#if defined(IPC_MESSAGE_LOG_ENABLED)
- const std::wstring& output_params = msg->output_params();
- if (!l->empty() && !output_params.empty())
- l->append(L", ");
-
- l->append(output_params);
-#endif
- } else {
- // This is an outgoing reply. Now that we have the output parameters, we
- // can finally log the message.
- typename ReplyParam::ValueTuple p;
- void* iter = SyncMessage::GetDataIterator(msg);
- if (ReadParam(msg, &iter, &p))
- LogParam(p, l);
- }
- }
+ const RefSendParam& send, const ReplyParam& reply);
+ 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 Method>
static bool Dispatch(const Message* msg, T* obj, Method func) {
SendParam send_params;
- void* iter = GetDataIterator(msg);
Message* reply = GenerateReply(msg);
bool error;
- if (ReadParam(msg, &iter, &send_params)) {
- typename ReplyParam::ValueTuple reply_params;
+ if (ReadSendParam(msg, &send_params)) {
+ typename TupleTypes<ReplyParam>::ValueTuple reply_params;
DispatchToMethod(obj, func, send_params, &reply_params);
WriteParam(reply, reply_params);
error = false;
-#ifdef IPC_MESSAGE_LOG_ENABLED
- if (msg->received_time() != 0) {
- std::wstring output_params;
- LogParam(reply_params, &output_params);
- msg->set_output_params(output_params);
- }
-#endif
+ LogReplyParamsToMessage(reply_params, msg);
} else {
NOTREACHED() << "Error deserializing message " << msg->type();
reply->set_reply_error();
@@ -1254,23 +1195,11 @@ class MessageWithReply : public SyncMessage {
template<class T, class Method>
static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
SendParam send_params;
- void* iter = GetDataIterator(msg);
Message* reply = GenerateReply(msg);
bool error;
- if (ReadParam(msg, &iter, &send_params)) {
+ if (ReadSendParam(msg, &send_params)) {
Tuple1<Message&> t = MakeRefTuple(*reply);
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
- if (msg->sent_time()) {
- // Don't log the sync message after dispatch, as we don't have the
- // output parameters at that point. Instead, save its data and log it
- // with the outgoing reply message when it's sent.
- LogData* data = new LogData;
- GenerateLogData("", *msg, data);
- msg->set_dont_log();
- reply->set_sync_log_data(data);
- }
-#endif
+ ConnectMessageAndReply(msg, reply);
DispatchToMethod(obj, func, send_params, &t);
error = false;
} else {
« no previous file with comments | « ipc/ipc_message_macros.h ('k') | ipc/ipc_message_utils.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698