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