diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-17 00:24:54 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-17 00:24:54 +0000 |
commit | 0cfe5dae9265f8d3be8648e33421c7c76cb31b4e (patch) | |
tree | e66f9a09a25449285587c1734aeeef958e8744b0 /ipc/ipc_message_utils.h | |
parent | 06e3320d99ac84f65837749d579b4768e8d071f7 (diff) | |
download | chromium_src-0cfe5dae9265f8d3be8648e33421c7c76cb31b4e.zip chromium_src-0cfe5dae9265f8d3be8648e33421c7c76cb31b4e.tar.gz chromium_src-0cfe5dae9265f8d3be8648e33421c7c76cb31b4e.tar.bz2 |
Completely revert all my IPC work to see if this was what regressed the page cycler.
BUG=51411,52103
TEST=page cycler
Review URL: http://codereview.chromium.org/3170020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@56272 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc/ipc_message_utils.h')
-rw-r--r-- | ipc/ipc_message_utils.h | 291 |
1 files changed, 181 insertions, 110 deletions
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h index 05d3916..4667d4b 100644 --- a/ipc/ipc_message_utils.h +++ b/ipc/ipc_message_utils.h @@ -12,28 +12,21 @@ #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 "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." +#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" // 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 @@ -74,20 +67,8 @@ 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. @@ -325,9 +306,19 @@ struct ParamTraits<wchar_t> { template <> struct ParamTraits<base::Time> { typedef base::Time param_type; - 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); + 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); + } }; #if defined(OS_WIN) @@ -374,9 +365,6 @@ struct ParamTraits<MSG> { return result; } - static void Log(const param_type& p, std::wstring* l) { - l->append(L"<MSG>"); - } }; #endif // defined(OS_WIN) @@ -610,9 +598,27 @@ struct ParamTraits<std::pair<A, B> > { template <> struct ParamTraits<NullableString16> { typedef NullableString16 param_type; - 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); + 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")"); + } }; // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't @@ -703,9 +709,19 @@ struct ParamTraits<POINT> { template <> struct ParamTraits<FilePath> { typedef FilePath param_type; - 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); + 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); + } }; #if defined(OS_POSIX) @@ -727,9 +743,35 @@ struct ParamTraits<FilePath> { template<> struct ParamTraits<base::FileDescriptor> { typedef base::FileDescriptor param_type; - 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); + 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)); + } + } }; #endif // defined(OS_POSIX) @@ -739,9 +781,26 @@ struct ParamTraits<base::FileDescriptor> { template<> struct ParamTraits<IPC::ChannelHandle> { typedef ChannelHandle param_type; - 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); + 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")"); + } }; #if defined(OS_WIN) @@ -967,15 +1026,20 @@ template <class ParamType> class MessageWithTuple : public Message { public: typedef ParamType Param; - typedef typename TupleTypes<ParamType>::ParamTuple RefParam; + typedef typename 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); + MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p) + : Message(routing_id, type, PRIORITY_NORMAL) { + WriteParam(this, p); + } - static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE; + 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; + } // Generic dispatcher. Should cover most cases. template<class T, class Method> @@ -1047,6 +1111,12 @@ 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> @@ -1096,54 +1166,8 @@ 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). This would go into ipc_message_utils_impl.h, but it is -// also used by chrome_frame. +// reference elements). template <class RefTuple> class ParamDeserializer : public MessageReplyDeserializer { public: @@ -1156,32 +1180,67 @@ 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 TupleTypes<SendParam>::ParamTuple RefSendParam; + typedef typename SendParam::ParamTuple RefSendParam; typedef ReplyParamType ReplyParam; MessageWithReply(int32 routing_id, uint32 type, - 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; + 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); + } + } 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 (ReadSendParam(msg, &send_params)) { - typename TupleTypes<ReplyParam>::ValueTuple reply_params; + if (ReadParam(msg, &iter, &send_params)) { + typename ReplyParam::ValueTuple reply_params; DispatchToMethod(obj, func, send_params, &reply_params); WriteParam(reply, reply_params); error = false; - LogReplyParamsToMessage(reply_params, msg); +#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 } else { NOTREACHED() << "Error deserializing message " << msg->type(); reply->set_reply_error(); @@ -1195,11 +1254,23 @@ 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 (ReadSendParam(msg, &send_params)) { + if (ReadParam(msg, &iter, &send_params)) { Tuple1<Message&> t = MakeRefTuple(*reply); - ConnectMessageAndReply(msg, 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 DispatchToMethod(obj, func, send_params, &t); error = false; } else { |