ipc/chromium/src/chrome/common/ipc_sync_message.cc

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:eca4d3c8ff61
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.
4
5 #include "build/build_config.h"
6
7 #if defined(OS_WIN)
8 #include <windows.h>
9 #endif
10 #include <stack>
11
12 #include "base/logging.h"
13 #include "base/waitable_event.h"
14 #include "chrome/common/ipc_sync_message.h"
15
16 namespace IPC {
17
18 uint32_t SyncMessage::next_id_ = 0;
19 #define kSyncMessageHeaderSize 4
20
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);
32
33 // Add synchronous message data before the message payload.
34 SyncHeader header;
35 header.message_id = ++next_id_;
36 WriteSyncHeader(this, header);
37 }
38
39 MessageReplyDeserializer* SyncMessage::GetReplyDeserializer() {
40 MessageReplyDeserializer* rv = deserializer_;
41 DCHECK(rv);
42 deserializer_ = NULL;
43 return rv;
44 }
45
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 }
51
52 bool SyncMessage::IsMessageReplyTo(const Message& msg, int request_id) {
53 if (!msg.is_reply())
54 return false;
55
56 return GetMessageId(msg) == request_id;
57 }
58
59 void* SyncMessage::GetDataIterator(const Message* msg) {
60 void* iter = const_cast<char*>(msg->payload());
61 UpdateIter(&iter, kSyncMessageHeaderSize);
62 return iter;
63 }
64
65 int SyncMessage::GetMessageId(const Message& msg) {
66 if (!msg.is_sync() && !msg.is_reply())
67 return 0;
68
69 SyncHeader header;
70 if (!ReadSyncHeader(msg, &header))
71 return 0;
72
73 return header.message_id;
74 }
75
76 Message* SyncMessage::GenerateReply(const Message* msg) {
77 DCHECK(msg->is_sync());
78
79 Message* reply = new Message(msg->routing_id(), IPC_REPLY_ID,
80 msg->priority());
81 reply->set_reply();
82
83 SyncHeader header;
84
85 // use the same message id, but this time reply bit is set
86 header.message_id = GetMessageId(*msg);
87 WriteSyncHeader(reply, header);
88
89 return reply;
90 }
91
92 bool SyncMessage::ReadSyncHeader(const Message& msg, SyncHeader* header) {
93 DCHECK(msg.is_sync() || msg.is_reply());
94
95 void* iter = NULL;
96 bool result = msg.ReadInt(&iter, &header->message_id);
97 if (!result) {
98 NOTREACHED();
99 return false;
100 }
101
102 return true;
103 }
104
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 }
113
114 // Note: if you add anything here, you need to update kSyncMessageHeaderSize.
115 DCHECK(kSyncMessageHeaderSize == msg->payload_size());
116
117 return true;
118 }
119
120
121 bool MessageReplyDeserializer::SerializeOutputParameters(const Message& msg) {
122 return SerializeOutputParameters(msg, SyncMessage::GetDataIterator(&msg));
123 }
124
125 } // namespace IPC

mercurial