| Index: ipc/ipc_sync_message.cc
|
| diff --git a/ipc/ipc_sync_message.cc b/ipc/ipc_sync_message.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..519adb17555b5fd49a158d404a55147113938fcd
|
| --- /dev/null
|
| +++ b/ipc/ipc_sync_message.cc
|
| @@ -0,0 +1,126 @@
|
| +// Copyright (c) 2006-2008 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.
|
| +
|
| +#include "build/build_config.h"
|
| +
|
| +#if defined(OS_WIN)
|
| +#include <windows.h>
|
| +#endif
|
| +#include <stack>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/waitable_event.h"
|
| +#include "ipc/ipc_sync_message.h"
|
| +
|
| +namespace IPC {
|
| +
|
| +uint32 SyncMessage::next_id_ = 0;
|
| +#define kSyncMessageHeaderSize 4
|
| +
|
| +base::WaitableEvent* dummy_event = new base::WaitableEvent(true, true);
|
| +
|
| +SyncMessage::SyncMessage(
|
| + int32 routing_id,
|
| + uint16 type,
|
| + PriorityValue priority,
|
| + MessageReplyDeserializer* deserializer)
|
| + : Message(routing_id, type, priority),
|
| + deserializer_(deserializer),
|
| + pump_messages_event_(NULL)
|
| + {
|
| + set_sync();
|
| + set_unblock(true);
|
| +
|
| + // Add synchronous message data before the message payload.
|
| + SyncHeader header;
|
| + header.message_id = ++next_id_;
|
| + WriteSyncHeader(this, header);
|
| +}
|
| +
|
| +MessageReplyDeserializer* SyncMessage::GetReplyDeserializer() {
|
| + MessageReplyDeserializer* rv = deserializer_;
|
| + DCHECK(rv);
|
| + deserializer_ = NULL;
|
| + return rv;
|
| +}
|
| +
|
| +void SyncMessage::EnableMessagePumping() {
|
| + DCHECK(!pump_messages_event_);
|
| + set_pump_messages_event(dummy_event);
|
| +}
|
| +
|
| +bool SyncMessage::IsMessageReplyTo(const Message& msg, int request_id) {
|
| + if (!msg.is_reply())
|
| + return false;
|
| +
|
| + return GetMessageId(msg) == request_id;
|
| +}
|
| +
|
| +void* SyncMessage::GetDataIterator(const Message* msg) {
|
| + void* iter = const_cast<char*>(msg->payload());
|
| + UpdateIter(&iter, kSyncMessageHeaderSize);
|
| + return iter;
|
| +}
|
| +
|
| +int SyncMessage::GetMessageId(const Message& msg) {
|
| + if (!msg.is_sync() && !msg.is_reply())
|
| + return 0;
|
| +
|
| + SyncHeader header;
|
| + if (!ReadSyncHeader(msg, &header))
|
| + return 0;
|
| +
|
| + return header.message_id;
|
| +}
|
| +
|
| +Message* SyncMessage::GenerateReply(const Message* msg) {
|
| + DCHECK(msg->is_sync());
|
| +
|
| + Message* reply = new Message(msg->routing_id(), IPC_REPLY_ID,
|
| + msg->priority());
|
| + reply->set_reply();
|
| +
|
| + SyncHeader header;
|
| +
|
| + // use the same message id, but this time reply bit is set
|
| + header.message_id = GetMessageId(*msg);
|
| + WriteSyncHeader(reply, header);
|
| +
|
| + return reply;
|
| +}
|
| +
|
| +bool SyncMessage::ReadSyncHeader(const Message& msg, SyncHeader* header) {
|
| + DCHECK(msg.is_sync() || msg.is_reply());
|
| +
|
| + void* iter = NULL;
|
| + bool result = msg.ReadInt(&iter, &header->message_id);
|
| + if (!result) {
|
| + NOTREACHED();
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool SyncMessage::WriteSyncHeader(Message* msg, const SyncHeader& header) {
|
| + DCHECK(msg->is_sync() || msg->is_reply());
|
| + DCHECK(msg->payload_size() == 0);
|
| + bool result = msg->WriteInt(header.message_id);
|
| + if (!result) {
|
| + NOTREACHED();
|
| + return false;
|
| + }
|
| +
|
| + // Note: if you add anything here, you need to update kSyncMessageHeaderSize.
|
| + DCHECK(kSyncMessageHeaderSize == msg->payload_size());
|
| +
|
| + return true;
|
| +}
|
| +
|
| +
|
| +bool MessageReplyDeserializer::SerializeOutputParameters(const Message& msg) {
|
| + return SerializeOutputParameters(msg, SyncMessage::GetDataIterator(&msg));
|
| +}
|
| +
|
| +} // namespace IPC
|
|
|