OLD | NEW |
| (Empty) |
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 SyncMessage::next_id_ = 0; | |
19 #define kSyncMessageHeaderSize 4 | |
20 | |
21 base::WaitableEvent* dummy_event = new base::WaitableEvent(true, true); | |
22 | |
23 SyncMessage::SyncMessage( | |
24 int32 routing_id, | |
25 uint16 type, | |
26 PriorityValue priority, | |
27 MessageReplyDeserializer* deserializer) | |
28 : Message(routing_id, type, priority), | |
29 deserializer_(deserializer), | |
30 pump_messages_event_(NULL) | |
31 { | |
32 set_sync(); | |
33 set_unblock(true); | |
34 | |
35 // Add synchronous message data before the message payload. | |
36 SyncHeader header; | |
37 header.message_id = ++next_id_; | |
38 WriteSyncHeader(this, header); | |
39 } | |
40 | |
41 MessageReplyDeserializer* SyncMessage::GetReplyDeserializer() { | |
42 MessageReplyDeserializer* rv = deserializer_; | |
43 DCHECK(rv); | |
44 deserializer_ = NULL; | |
45 return rv; | |
46 } | |
47 | |
48 void SyncMessage::EnableMessagePumping() { | |
49 DCHECK(!pump_messages_event_); | |
50 set_pump_messages_event(dummy_event); | |
51 } | |
52 | |
53 bool SyncMessage::IsMessageReplyTo(const Message& msg, int request_id) { | |
54 if (!msg.is_reply()) | |
55 return false; | |
56 | |
57 return GetMessageId(msg) == request_id; | |
58 } | |
59 | |
60 void* SyncMessage::GetDataIterator(const Message* msg) { | |
61 void* iter = const_cast<char*>(msg->payload()); | |
62 UpdateIter(&iter, kSyncMessageHeaderSize); | |
63 return iter; | |
64 } | |
65 | |
66 int SyncMessage::GetMessageId(const Message& msg) { | |
67 if (!msg.is_sync() && !msg.is_reply()) | |
68 return 0; | |
69 | |
70 SyncHeader header; | |
71 if (!ReadSyncHeader(msg, &header)) | |
72 return 0; | |
73 | |
74 return header.message_id; | |
75 } | |
76 | |
77 Message* SyncMessage::GenerateReply(const Message* msg) { | |
78 DCHECK(msg->is_sync()); | |
79 | |
80 Message* reply = new Message(msg->routing_id(), IPC_REPLY_ID, | |
81 msg->priority()); | |
82 reply->set_reply(); | |
83 | |
84 SyncHeader header; | |
85 | |
86 // use the same message id, but this time reply bit is set | |
87 header.message_id = GetMessageId(*msg); | |
88 WriteSyncHeader(reply, header); | |
89 | |
90 return reply; | |
91 } | |
92 | |
93 bool SyncMessage::ReadSyncHeader(const Message& msg, SyncHeader* header) { | |
94 DCHECK(msg.is_sync() || msg.is_reply()); | |
95 | |
96 void* iter = NULL; | |
97 bool result = msg.ReadInt(&iter, &header->message_id); | |
98 if (!result) { | |
99 NOTREACHED(); | |
100 return false; | |
101 } | |
102 | |
103 return true; | |
104 } | |
105 | |
106 bool SyncMessage::WriteSyncHeader(Message* msg, const SyncHeader& header) { | |
107 DCHECK(msg->is_sync() || msg->is_reply()); | |
108 DCHECK(msg->payload_size() == 0); | |
109 bool result = msg->WriteInt(header.message_id); | |
110 if (!result) { | |
111 NOTREACHED(); | |
112 return false; | |
113 } | |
114 | |
115 // Note: if you add anything here, you need to update kSyncMessageHeaderSize. | |
116 DCHECK(kSyncMessageHeaderSize == msg->payload_size()); | |
117 | |
118 return true; | |
119 } | |
120 | |
121 | |
122 bool MessageReplyDeserializer::SerializeOutputParameters(const Message& msg) { | |
123 return SerializeOutputParameters(msg, SyncMessage::GetDataIterator(&msg)); | |
124 } | |
125 | |
126 } // namespace IPC | |
OLD | NEW |