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"
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"
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(
28 PriorityValue priority
,
29 MessageReplyDeserializer
* deserializer
)
30 : Message(routing_id
, type
, priority
),
31 deserializer_(deserializer
),
32 pump_messages_event_(NULL
)
37 // Add synchronous message data before the message payload.
39 header
.message_id
= g_next_id
.GetNext();
40 WriteSyncHeader(this, header
);
43 MessageReplyDeserializer
* SyncMessage::GetReplyDeserializer() {
44 MessageReplyDeserializer
* rv
= deserializer_
;
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
) {
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
);
68 int SyncMessage::GetMessageId(const Message
& msg
) {
69 if (!msg
.is_sync() && !msg
.is_reply())
73 if (!ReadSyncHeader(msg
, &header
))
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
,
88 // use the same message id, but this time reply bit is set
89 header
.message_id
= GetMessageId(*msg
);
90 WriteSyncHeader(reply
, header
);
95 bool SyncMessage::ReadSyncHeader(const Message
& msg
, SyncHeader
* header
) {
96 DCHECK(msg
.is_sync() || msg
.is_reply());
99 bool result
= msg
.ReadInt(&iter
, &header
->message_id
);
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
);
117 // Note: if you add anything here, you need to update kSyncMessageHeaderSize.
118 DCHECK(kSyncMessageHeaderSize
== msg
->payload_size());
124 bool MessageReplyDeserializer::SerializeOutputParameters(const Message
& msg
) {
125 return SerializeOutputParameters(msg
, SyncMessage::GetDataIterator(&msg
));