xref: /aosp_15_r20/external/cronet/ipc/ipc_sync_message.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_sync_message.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include "base/atomic_sequence_num.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
13*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker namespace {
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker base::AtomicSequenceNumber g_next_id;
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker }  // namespace
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker namespace IPC {
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker #define kSyncMessageHeaderSize 4
24*6777b538SAndroid Build Coastguard Worker 
SyncMessage(int32_t routing_id,uint32_t type,PriorityValue priority,std::unique_ptr<MessageReplyDeserializer> deserializer)25*6777b538SAndroid Build Coastguard Worker SyncMessage::SyncMessage(int32_t routing_id,
26*6777b538SAndroid Build Coastguard Worker                          uint32_t type,
27*6777b538SAndroid Build Coastguard Worker                          PriorityValue priority,
28*6777b538SAndroid Build Coastguard Worker                          std::unique_ptr<MessageReplyDeserializer> deserializer)
29*6777b538SAndroid Build Coastguard Worker     : Message(routing_id, type, priority),
30*6777b538SAndroid Build Coastguard Worker       deserializer_(std::move(deserializer)) {
31*6777b538SAndroid Build Coastguard Worker   set_sync();
32*6777b538SAndroid Build Coastguard Worker   set_unblock(true);
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker   // Add synchronous message data before the message payload.
35*6777b538SAndroid Build Coastguard Worker   SyncHeader header;
36*6777b538SAndroid Build Coastguard Worker   header.message_id = g_next_id.GetNext();
37*6777b538SAndroid Build Coastguard Worker   WriteSyncHeader(this, header);
38*6777b538SAndroid Build Coastguard Worker }
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker SyncMessage::~SyncMessage() = default;
41*6777b538SAndroid Build Coastguard Worker 
TakeReplyDeserializer()42*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MessageReplyDeserializer> SyncMessage::TakeReplyDeserializer() {
43*6777b538SAndroid Build Coastguard Worker   DCHECK(deserializer_);
44*6777b538SAndroid Build Coastguard Worker   return std::move(deserializer_);
45*6777b538SAndroid Build Coastguard Worker }
46*6777b538SAndroid Build Coastguard Worker 
IsMessageReplyTo(const Message & msg,int request_id)47*6777b538SAndroid Build Coastguard Worker bool SyncMessage::IsMessageReplyTo(const Message& msg, int request_id) {
48*6777b538SAndroid Build Coastguard Worker   if (!msg.is_reply())
49*6777b538SAndroid Build Coastguard Worker     return false;
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker   return GetMessageId(msg) == request_id;
52*6777b538SAndroid Build Coastguard Worker }
53*6777b538SAndroid Build Coastguard Worker 
GetDataIterator(const Message * msg)54*6777b538SAndroid Build Coastguard Worker base::PickleIterator SyncMessage::GetDataIterator(const Message* msg) {
55*6777b538SAndroid Build Coastguard Worker   base::PickleIterator iter(*msg);
56*6777b538SAndroid Build Coastguard Worker   if (!iter.SkipBytes(kSyncMessageHeaderSize))
57*6777b538SAndroid Build Coastguard Worker     return base::PickleIterator();
58*6777b538SAndroid Build Coastguard Worker   else
59*6777b538SAndroid Build Coastguard Worker     return iter;
60*6777b538SAndroid Build Coastguard Worker }
61*6777b538SAndroid Build Coastguard Worker 
GetMessageId(const Message & msg)62*6777b538SAndroid Build Coastguard Worker int SyncMessage::GetMessageId(const Message& msg) {
63*6777b538SAndroid Build Coastguard Worker   if (!msg.is_sync() && !msg.is_reply())
64*6777b538SAndroid Build Coastguard Worker     return 0;
65*6777b538SAndroid Build Coastguard Worker 
66*6777b538SAndroid Build Coastguard Worker   SyncHeader header;
67*6777b538SAndroid Build Coastguard Worker   if (!ReadSyncHeader(msg, &header))
68*6777b538SAndroid Build Coastguard Worker     return 0;
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker   return header.message_id;
71*6777b538SAndroid Build Coastguard Worker }
72*6777b538SAndroid Build Coastguard Worker 
GenerateReply(const Message * msg)73*6777b538SAndroid Build Coastguard Worker Message* SyncMessage::GenerateReply(const Message* msg) {
74*6777b538SAndroid Build Coastguard Worker   DCHECK(msg->is_sync());
75*6777b538SAndroid Build Coastguard Worker 
76*6777b538SAndroid Build Coastguard Worker   Message* reply = new Message(msg->routing_id(), IPC_REPLY_ID,
77*6777b538SAndroid Build Coastguard Worker                                msg->priority());
78*6777b538SAndroid Build Coastguard Worker   reply->set_reply();
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker   SyncHeader header;
81*6777b538SAndroid Build Coastguard Worker 
82*6777b538SAndroid Build Coastguard Worker   // use the same message id, but this time reply bit is set
83*6777b538SAndroid Build Coastguard Worker   header.message_id = GetMessageId(*msg);
84*6777b538SAndroid Build Coastguard Worker   WriteSyncHeader(reply, header);
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker   return reply;
87*6777b538SAndroid Build Coastguard Worker }
88*6777b538SAndroid Build Coastguard Worker 
ReadSyncHeader(const Message & msg,SyncHeader * header)89*6777b538SAndroid Build Coastguard Worker bool SyncMessage::ReadSyncHeader(const Message& msg, SyncHeader* header) {
90*6777b538SAndroid Build Coastguard Worker   DCHECK(msg.is_sync() || msg.is_reply());
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   base::PickleIterator iter(msg);
93*6777b538SAndroid Build Coastguard Worker   bool result = iter.ReadInt(&header->message_id);
94*6777b538SAndroid Build Coastguard Worker   if (!result) {
95*6777b538SAndroid Build Coastguard Worker     NOTREACHED();
96*6777b538SAndroid Build Coastguard Worker     return false;
97*6777b538SAndroid Build Coastguard Worker   }
98*6777b538SAndroid Build Coastguard Worker 
99*6777b538SAndroid Build Coastguard Worker   return true;
100*6777b538SAndroid Build Coastguard Worker }
101*6777b538SAndroid Build Coastguard Worker 
WriteSyncHeader(Message * msg,const SyncHeader & header)102*6777b538SAndroid Build Coastguard Worker bool SyncMessage::WriteSyncHeader(Message* msg, const SyncHeader& header) {
103*6777b538SAndroid Build Coastguard Worker   DCHECK(msg->is_sync() || msg->is_reply());
104*6777b538SAndroid Build Coastguard Worker   DCHECK(msg->payload_size() == 0);
105*6777b538SAndroid Build Coastguard Worker   msg->WriteInt(header.message_id);
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker   // Note: if you add anything here, you need to update kSyncMessageHeaderSize.
108*6777b538SAndroid Build Coastguard Worker   DCHECK(kSyncMessageHeaderSize == msg->payload_size());
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker   return true;
111*6777b538SAndroid Build Coastguard Worker }
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker 
SerializeOutputParameters(const Message & msg)114*6777b538SAndroid Build Coastguard Worker bool MessageReplyDeserializer::SerializeOutputParameters(const Message& msg) {
115*6777b538SAndroid Build Coastguard Worker   return SerializeOutputParameters(msg, SyncMessage::GetDataIterator(&msg));
116*6777b538SAndroid Build Coastguard Worker }
117*6777b538SAndroid Build Coastguard Worker 
PendingSyncMsg(int id,std::unique_ptr<MessageReplyDeserializer> d,std::unique_ptr<base::WaitableEvent> e)118*6777b538SAndroid Build Coastguard Worker PendingSyncMsg::PendingSyncMsg(int id,
119*6777b538SAndroid Build Coastguard Worker                                std::unique_ptr<MessageReplyDeserializer> d,
120*6777b538SAndroid Build Coastguard Worker                                std::unique_ptr<base::WaitableEvent> e)
121*6777b538SAndroid Build Coastguard Worker     : id(id), deserializer(std::move(d)), done_event(std::move(e)) {}
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker PendingSyncMsg::PendingSyncMsg(PendingSyncMsg&& that) = default;
124*6777b538SAndroid Build Coastguard Worker 
125*6777b538SAndroid Build Coastguard Worker PendingSyncMsg::~PendingSyncMsg() = default;
126*6777b538SAndroid Build Coastguard Worker 
127*6777b538SAndroid Build Coastguard Worker }  // namespace IPC
128