Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 // Copyright (c) 2006-2008 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/logging.h"
13 #include "base/waitable_event.h"
14 #include "chrome/common/ipc_sync_message.h"
16 namespace IPC {
18 uint32_t SyncMessage::next_id_ = 0;
19 #define kSyncMessageHeaderSize 4
21 SyncMessage::SyncMessage(
22 int32_t routing_id,
23 uint16_t type,
24 PriorityValue priority,
25 MessageReplyDeserializer* deserializer)
26 : Message(routing_id, type, priority),
27 deserializer_(deserializer),
28 pump_messages_event_(NULL)
29 {
30 set_sync();
31 set_unblock(true);
33 // Add synchronous message data before the message payload.
34 SyncHeader header;
35 header.message_id = ++next_id_;
36 WriteSyncHeader(this, header);
37 }
39 MessageReplyDeserializer* SyncMessage::GetReplyDeserializer() {
40 MessageReplyDeserializer* rv = deserializer_;
41 DCHECK(rv);
42 deserializer_ = NULL;
43 return rv;
44 }
46 void SyncMessage::EnableMessagePumping() {
47 static base::WaitableEvent* dummy_event = new base::WaitableEvent(true, true);
48 DCHECK(!pump_messages_event_);
49 set_pump_messages_event(dummy_event);
50 }
52 bool SyncMessage::IsMessageReplyTo(const Message& msg, int request_id) {
53 if (!msg.is_reply())
54 return false;
56 return GetMessageId(msg) == request_id;
57 }
59 void* SyncMessage::GetDataIterator(const Message* msg) {
60 void* iter = const_cast<char*>(msg->payload());
61 UpdateIter(&iter, kSyncMessageHeaderSize);
62 return iter;
63 }
65 int SyncMessage::GetMessageId(const Message& msg) {
66 if (!msg.is_sync() && !msg.is_reply())
67 return 0;
69 SyncHeader header;
70 if (!ReadSyncHeader(msg, &header))
71 return 0;
73 return header.message_id;
74 }
76 Message* SyncMessage::GenerateReply(const Message* msg) {
77 DCHECK(msg->is_sync());
79 Message* reply = new Message(msg->routing_id(), IPC_REPLY_ID,
80 msg->priority());
81 reply->set_reply();
83 SyncHeader header;
85 // use the same message id, but this time reply bit is set
86 header.message_id = GetMessageId(*msg);
87 WriteSyncHeader(reply, header);
89 return reply;
90 }
92 bool SyncMessage::ReadSyncHeader(const Message& msg, SyncHeader* header) {
93 DCHECK(msg.is_sync() || msg.is_reply());
95 void* iter = NULL;
96 bool result = msg.ReadInt(&iter, &header->message_id);
97 if (!result) {
98 NOTREACHED();
99 return false;
100 }
102 return true;
103 }
105 bool SyncMessage::WriteSyncHeader(Message* msg, const SyncHeader& header) {
106 DCHECK(msg->is_sync() || msg->is_reply());
107 DCHECK(msg->payload_size() == 0);
108 bool result = msg->WriteInt(header.message_id);
109 if (!result) {
110 NOTREACHED();
111 return false;
112 }
114 // Note: if you add anything here, you need to update kSyncMessageHeaderSize.
115 DCHECK(kSyncMessageHeaderSize == msg->payload_size());
117 return true;
118 }
121 bool MessageReplyDeserializer::SerializeOutputParameters(const Message& msg) {
122 return SerializeOutputParameters(msg, SyncMessage::GetDataIterator(&msg));
123 }
125 } // namespace IPC