Updating trunk VERSION from 780.0 to 781.0
[chromium-blink-merge.git] / ipc / ipc_sync_message.cc
blob21fae8fe6d4dcfda15cec5ed34d7276038f819d7
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "build/build_config.h"
7 #if defined(OS_WIN)
8 #include <windows.h>
9 #endif
10 #include <stack>
12 #include "base/atomic_sequence_num.h"
13 #include "base/logging.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "ipc/ipc_sync_message.h"
17 namespace IPC {
19 #define kSyncMessageHeaderSize 4
21 static base::AtomicSequenceNumber g_next_id(base::LINKER_INITIALIZED);
23 static base::WaitableEvent* dummy_event = new base::WaitableEvent(true, true);
25 SyncMessage::SyncMessage(
26 int32 routing_id,
27 uint32 type,
28 PriorityValue priority,
29 MessageReplyDeserializer* deserializer)
30 : Message(routing_id, type, priority),
31 deserializer_(deserializer),
32 pump_messages_event_(NULL)
34 set_sync();
35 set_unblock(true);
37 // Add synchronous message data before the message payload.
38 SyncHeader header;
39 header.message_id = g_next_id.GetNext();
40 WriteSyncHeader(this, header);
43 MessageReplyDeserializer* SyncMessage::GetReplyDeserializer() {
44 MessageReplyDeserializer* rv = deserializer_;
45 DCHECK(rv);
46 deserializer_ = NULL;
47 return rv;
50 void SyncMessage::EnableMessagePumping() {
51 DCHECK(!pump_messages_event_);
52 set_pump_messages_event(dummy_event);
55 bool SyncMessage::IsMessageReplyTo(const Message& msg, int request_id) {
56 if (!msg.is_reply())
57 return false;
59 return GetMessageId(msg) == request_id;
62 void* SyncMessage::GetDataIterator(const Message* msg) {
63 void* iter = const_cast<char*>(msg->payload());
64 UpdateIter(&iter, kSyncMessageHeaderSize);
65 return iter;
68 int SyncMessage::GetMessageId(const Message& msg) {
69 if (!msg.is_sync() && !msg.is_reply())
70 return 0;
72 SyncHeader header;
73 if (!ReadSyncHeader(msg, &header))
74 return 0;
76 return header.message_id;
79 Message* SyncMessage::GenerateReply(const Message* msg) {
80 DCHECK(msg->is_sync());
82 Message* reply = new Message(msg->routing_id(), IPC_REPLY_ID,
83 msg->priority());
84 reply->set_reply();
86 SyncHeader header;
88 // use the same message id, but this time reply bit is set
89 header.message_id = GetMessageId(*msg);
90 WriteSyncHeader(reply, header);
92 return reply;
95 bool SyncMessage::ReadSyncHeader(const Message& msg, SyncHeader* header) {
96 DCHECK(msg.is_sync() || msg.is_reply());
98 void* iter = NULL;
99 bool result = msg.ReadInt(&iter, &header->message_id);
100 if (!result) {
101 NOTREACHED();
102 return false;
105 return true;
108 bool SyncMessage::WriteSyncHeader(Message* msg, const SyncHeader& header) {
109 DCHECK(msg->is_sync() || msg->is_reply());
110 DCHECK(msg->payload_size() == 0);
111 bool result = msg->WriteInt(header.message_id);
112 if (!result) {
113 NOTREACHED();
114 return false;
117 // Note: if you add anything here, you need to update kSyncMessageHeaderSize.
118 DCHECK(kSyncMessageHeaderSize == msg->payload_size());
120 return true;
124 bool MessageReplyDeserializer::SerializeOutputParameters(const Message& msg) {
125 return SerializeOutputParameters(msg, SyncMessage::GetDataIterator(&msg));
128 } // namespace IPC