Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
michael@0 | 1 | // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
michael@0 | 2 | // Use of this source code is governed by a BSD-style license that can be |
michael@0 | 3 | // found in the LICENSE file. |
michael@0 | 4 | |
michael@0 | 5 | #include "build/build_config.h" |
michael@0 | 6 | |
michael@0 | 7 | #if defined(OS_WIN) |
michael@0 | 8 | #include <windows.h> |
michael@0 | 9 | #endif |
michael@0 | 10 | #include <stack> |
michael@0 | 11 | |
michael@0 | 12 | #include "base/logging.h" |
michael@0 | 13 | #include "base/waitable_event.h" |
michael@0 | 14 | #include "chrome/common/ipc_sync_message.h" |
michael@0 | 15 | |
michael@0 | 16 | namespace IPC { |
michael@0 | 17 | |
michael@0 | 18 | uint32_t SyncMessage::next_id_ = 0; |
michael@0 | 19 | #define kSyncMessageHeaderSize 4 |
michael@0 | 20 | |
michael@0 | 21 | SyncMessage::SyncMessage( |
michael@0 | 22 | int32_t routing_id, |
michael@0 | 23 | uint16_t type, |
michael@0 | 24 | PriorityValue priority, |
michael@0 | 25 | MessageReplyDeserializer* deserializer) |
michael@0 | 26 | : Message(routing_id, type, priority), |
michael@0 | 27 | deserializer_(deserializer), |
michael@0 | 28 | pump_messages_event_(NULL) |
michael@0 | 29 | { |
michael@0 | 30 | set_sync(); |
michael@0 | 31 | set_unblock(true); |
michael@0 | 32 | |
michael@0 | 33 | // Add synchronous message data before the message payload. |
michael@0 | 34 | SyncHeader header; |
michael@0 | 35 | header.message_id = ++next_id_; |
michael@0 | 36 | WriteSyncHeader(this, header); |
michael@0 | 37 | } |
michael@0 | 38 | |
michael@0 | 39 | MessageReplyDeserializer* SyncMessage::GetReplyDeserializer() { |
michael@0 | 40 | MessageReplyDeserializer* rv = deserializer_; |
michael@0 | 41 | DCHECK(rv); |
michael@0 | 42 | deserializer_ = NULL; |
michael@0 | 43 | return rv; |
michael@0 | 44 | } |
michael@0 | 45 | |
michael@0 | 46 | void SyncMessage::EnableMessagePumping() { |
michael@0 | 47 | static base::WaitableEvent* dummy_event = new base::WaitableEvent(true, true); |
michael@0 | 48 | DCHECK(!pump_messages_event_); |
michael@0 | 49 | set_pump_messages_event(dummy_event); |
michael@0 | 50 | } |
michael@0 | 51 | |
michael@0 | 52 | bool SyncMessage::IsMessageReplyTo(const Message& msg, int request_id) { |
michael@0 | 53 | if (!msg.is_reply()) |
michael@0 | 54 | return false; |
michael@0 | 55 | |
michael@0 | 56 | return GetMessageId(msg) == request_id; |
michael@0 | 57 | } |
michael@0 | 58 | |
michael@0 | 59 | void* SyncMessage::GetDataIterator(const Message* msg) { |
michael@0 | 60 | void* iter = const_cast<char*>(msg->payload()); |
michael@0 | 61 | UpdateIter(&iter, kSyncMessageHeaderSize); |
michael@0 | 62 | return iter; |
michael@0 | 63 | } |
michael@0 | 64 | |
michael@0 | 65 | int SyncMessage::GetMessageId(const Message& msg) { |
michael@0 | 66 | if (!msg.is_sync() && !msg.is_reply()) |
michael@0 | 67 | return 0; |
michael@0 | 68 | |
michael@0 | 69 | SyncHeader header; |
michael@0 | 70 | if (!ReadSyncHeader(msg, &header)) |
michael@0 | 71 | return 0; |
michael@0 | 72 | |
michael@0 | 73 | return header.message_id; |
michael@0 | 74 | } |
michael@0 | 75 | |
michael@0 | 76 | Message* SyncMessage::GenerateReply(const Message* msg) { |
michael@0 | 77 | DCHECK(msg->is_sync()); |
michael@0 | 78 | |
michael@0 | 79 | Message* reply = new Message(msg->routing_id(), IPC_REPLY_ID, |
michael@0 | 80 | msg->priority()); |
michael@0 | 81 | reply->set_reply(); |
michael@0 | 82 | |
michael@0 | 83 | SyncHeader header; |
michael@0 | 84 | |
michael@0 | 85 | // use the same message id, but this time reply bit is set |
michael@0 | 86 | header.message_id = GetMessageId(*msg); |
michael@0 | 87 | WriteSyncHeader(reply, header); |
michael@0 | 88 | |
michael@0 | 89 | return reply; |
michael@0 | 90 | } |
michael@0 | 91 | |
michael@0 | 92 | bool SyncMessage::ReadSyncHeader(const Message& msg, SyncHeader* header) { |
michael@0 | 93 | DCHECK(msg.is_sync() || msg.is_reply()); |
michael@0 | 94 | |
michael@0 | 95 | void* iter = NULL; |
michael@0 | 96 | bool result = msg.ReadInt(&iter, &header->message_id); |
michael@0 | 97 | if (!result) { |
michael@0 | 98 | NOTREACHED(); |
michael@0 | 99 | return false; |
michael@0 | 100 | } |
michael@0 | 101 | |
michael@0 | 102 | return true; |
michael@0 | 103 | } |
michael@0 | 104 | |
michael@0 | 105 | bool SyncMessage::WriteSyncHeader(Message* msg, const SyncHeader& header) { |
michael@0 | 106 | DCHECK(msg->is_sync() || msg->is_reply()); |
michael@0 | 107 | DCHECK(msg->payload_size() == 0); |
michael@0 | 108 | bool result = msg->WriteInt(header.message_id); |
michael@0 | 109 | if (!result) { |
michael@0 | 110 | NOTREACHED(); |
michael@0 | 111 | return false; |
michael@0 | 112 | } |
michael@0 | 113 | |
michael@0 | 114 | // Note: if you add anything here, you need to update kSyncMessageHeaderSize. |
michael@0 | 115 | DCHECK(kSyncMessageHeaderSize == msg->payload_size()); |
michael@0 | 116 | |
michael@0 | 117 | return true; |
michael@0 | 118 | } |
michael@0 | 119 | |
michael@0 | 120 | |
michael@0 | 121 | bool MessageReplyDeserializer::SerializeOutputParameters(const Message& msg) { |
michael@0 | 122 | return SerializeOutputParameters(msg, SyncMessage::GetDataIterator(&msg)); |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | } // namespace IPC |