blob: 2229cdd6a06a4863c247c6f1a82d6a5cd3786143 [file] [log] [blame]
[email protected]ce208f872012-03-07 20:42:561// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]946d1b22009-07-22 23:57:215#include "ipc/ipc_message.h"
initial.commit09911bf2008-07-26 23:55:296
[email protected]dc4fa482014-02-25 15:30:157#include "base/atomic_sequence_num.h"
initial.commit09911bf2008-07-26 23:55:298#include "base/logging.h"
[email protected]526776c2009-02-07 00:39:269#include "build/build_config.h"
morrita1aa788c2015-01-31 05:45:4210#include "ipc/ipc_message_attachment.h"
morrita4b5c28e22015-01-14 21:17:0611#include "ipc/ipc_message_attachment_set.h"
initial.commit09911bf2008-07-26 23:55:2912
[email protected]7135bb042009-02-12 04:05:2813#if defined(OS_POSIX)
morrita96693852014-09-24 20:11:4514#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4215#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]7135bb042009-02-12 04:05:2816#endif
17
[email protected]2a2e3d62012-09-04 23:08:0918namespace {
19
[email protected]dc4fa482014-02-25 15:30:1520base::StaticAtomicSequenceNumber g_ref_num;
[email protected]2a2e3d62012-09-04 23:08:0921
22// Create a reference number for identifying IPC messages in traces. The return
23// values has the reference number stored in the upper 24 bits, leaving the low
24// 8 bits set to 0 for use as flags.
tfarina10a5c062015-09-04 18:47:5725inline uint32_t GetRefNumUpper24() {
ssid759dd8c2015-02-09 21:25:3926 base::trace_event::TraceLog* trace_log =
27 base::trace_event::TraceLog::GetInstance();
tfarina10a5c062015-09-04 18:47:5728 uint32_t pid = trace_log ? trace_log->process_id() : 0;
29 uint32_t count = g_ref_num.GetNext();
[email protected]2a2e3d62012-09-04 23:08:0930 // The 24 bit hash is composed of 14 bits of the count and 10 bits of the
31 // Process ID. With the current trace event buffer cap, the 14-bit count did
32 // not appear to wrap during a trace. Note that it is not a big deal if
33 // collisions occur, as this is only used for debugging and trace analysis.
[email protected]40cb13052013-08-14 00:37:4734 return ((pid << 14) | (count & 0x3fff)) << 8;
[email protected]2a2e3d62012-09-04 23:08:0935}
36
37} // namespace
38
initial.commit09911bf2008-07-26 23:55:2939namespace IPC {
40
41//------------------------------------------------------------------------------
42
43Message::~Message() {
44}
45
brettwbd4d7112015-06-03 04:29:2546Message::Message() : base::Pickle(sizeof(Header)) {
[email protected]2a2e3d62012-09-04 23:08:0947 header()->routing = header()->type = 0;
48 header()->flags = GetRefNumUpper24();
[email protected]526776c2009-02-07 00:39:2649#if defined(OS_POSIX)
50 header()->num_fds = 0;
[email protected]15b97af032009-12-05 00:00:5851 header()->pad = 0;
[email protected]526776c2009-02-07 00:39:2652#endif
[email protected]ef2f6ba2014-05-15 23:06:0753 Init();
initial.commit09911bf2008-07-26 23:55:2954}
55
tfarina10a5c062015-09-04 18:47:5756Message::Message(int32_t routing_id, uint32_t type, PriorityValue priority)
brettwbd4d7112015-06-03 04:29:2557 : base::Pickle(sizeof(Header)) {
initial.commit09911bf2008-07-26 23:55:2958 header()->routing = routing_id;
59 header()->type = type;
[email protected]753bb252013-11-04 22:28:1260 DCHECK((priority & 0xffffff00) == 0);
61 header()->flags = priority | GetRefNumUpper24();
[email protected]526776c2009-02-07 00:39:2662#if defined(OS_POSIX)
63 header()->num_fds = 0;
[email protected]15b97af032009-12-05 00:00:5864 header()->pad = 0;
[email protected]526776c2009-02-07 00:39:2665#endif
[email protected]ef2f6ba2014-05-15 23:06:0766 Init();
initial.commit09911bf2008-07-26 23:55:2967}
68
brettwbd4d7112015-06-03 04:29:2569Message::Message(const char* data, int data_len)
70 : base::Pickle(data, data_len) {
[email protected]ef2f6ba2014-05-15 23:06:0771 Init();
initial.commit09911bf2008-07-26 23:55:2972}
73
brettwbd4d7112015-06-03 04:29:2574Message::Message(const Message& other) : base::Pickle(other) {
[email protected]ef2f6ba2014-05-15 23:06:0775 Init();
morrita4b5c28e22015-01-14 21:17:0676 attachment_set_ = other.attachment_set_;
initial.commit09911bf2008-07-26 23:55:2977}
78
[email protected]ef2f6ba2014-05-15 23:06:0779void Message::Init() {
80 dispatch_error_ = false;
erikchen3c175a32015-07-28 23:16:4881 sender_pid_ = base::kNullProcessId;
initial.commit09911bf2008-07-26 23:55:2982#ifdef IPC_MESSAGE_LOG_ENABLED
83 received_time_ = 0;
84 dont_log_ = false;
85 log_data_ = NULL;
86#endif
87}
88
89Message& Message::operator=(const Message& other) {
brettwbd4d7112015-06-03 04:29:2590 *static_cast<base::Pickle*>(this) = other;
morrita4b5c28e22015-01-14 21:17:0691 attachment_set_ = other.attachment_set_;
initial.commit09911bf2008-07-26 23:55:2992 return *this;
93}
94
tfarina10a5c062015-09-04 18:47:5795void Message::SetHeaderValues(int32_t routing, uint32_t type, uint32_t flags) {
[email protected]34d48612012-06-29 00:05:0496 // This should only be called when the message is already empty.
97 DCHECK(payload_size() == 0);
98
99 header()->routing = routing;
100 header()->type = type;
101 header()->flags = flags;
102}
103
morrita4b5c28e22015-01-14 21:17:06104void Message::EnsureMessageAttachmentSet() {
105 if (attachment_set_.get() == NULL)
106 attachment_set_ = new MessageAttachmentSet;
107}
108
initial.commit09911bf2008-07-26 23:55:29109#ifdef IPC_MESSAGE_LOG_ENABLED
tfarina10a5c062015-09-04 18:47:57110void Message::set_sent_time(int64_t time) {
initial.commit09911bf2008-07-26 23:55:29111 DCHECK((header()->flags & HAS_SENT_TIME_BIT) == 0);
112 header()->flags |= HAS_SENT_TIME_BIT;
113 WriteInt64(time);
114}
115
tfarina10a5c062015-09-04 18:47:57116int64_t Message::sent_time() const {
initial.commit09911bf2008-07-26 23:55:29117 if ((header()->flags & HAS_SENT_TIME_BIT) == 0)
118 return 0;
119
120 const char* data = end_of_payload();
tfarina10a5c062015-09-04 18:47:57121 data -= sizeof(int64_t);
122 return *(reinterpret_cast<const int64_t*>(data));
initial.commit09911bf2008-07-26 23:55:29123}
124
tfarina10a5c062015-09-04 18:47:57125void Message::set_received_time(int64_t time) const {
initial.commit09911bf2008-07-26 23:55:29126 received_time_ = time;
127}
128#endif
129
morrita1aa788c2015-01-31 05:45:42130bool Message::WriteAttachment(scoped_refptr<MessageAttachment> attachment) {
[email protected]7135bb042009-02-12 04:05:28131 // We write the index of the descriptor so that we don't have to
132 // keep the current descriptor as extra decoding state when deserialising.
morrita4b5c28e22015-01-14 21:17:06133 WriteInt(attachment_set()->size());
morrita1aa788c2015-01-31 05:45:42134 return attachment_set()->AddAttachment(attachment);
[email protected]7135bb042009-02-12 04:05:28135}
136
morrita1aa788c2015-01-31 05:45:42137bool Message::ReadAttachment(
brettwbd4d7112015-06-03 04:29:25138 base::PickleIterator* iter,
morrita1aa788c2015-01-31 05:45:42139 scoped_refptr<MessageAttachment>* attachment) const {
[email protected]7135bb042009-02-12 04:05:28140 int descriptor_index;
avi48fc13b2014-12-28 23:31:48141 if (!iter->ReadInt(&descriptor_index))
[email protected]7135bb042009-02-12 04:05:28142 return false;
143
morrita4b5c28e22015-01-14 21:17:06144 MessageAttachmentSet* attachment_set = attachment_set_.get();
145 if (!attachment_set)
[email protected]7135bb042009-02-12 04:05:28146 return false;
147
morrita1aa788c2015-01-31 05:45:42148 *attachment = attachment_set->GetAttachmentAt(descriptor_index);
149 return nullptr != attachment->get();
[email protected]7135bb042009-02-12 04:05:28150}
151
morrita1aa788c2015-01-31 05:45:42152bool Message::HasAttachments() const {
morrita4b5c28e22015-01-14 21:17:06153 return attachment_set_.get() && !attachment_set_->empty();
[email protected]7135bb042009-02-12 04:05:28154}
155
morrita81b17e02015-02-06 00:58:30156bool Message::HasMojoHandles() const {
erikcheneece6c32015-07-07 22:13:11157 return attachment_set_.get() && attachment_set_->num_mojo_handles() > 0;
158}
159
160bool Message::HasBrokerableAttachments() const {
161 return attachment_set_.get() &&
162 attachment_set_->num_brokerable_attachments() > 0;
morrita81b17e02015-02-06 00:58:30163}
164
[email protected]d284a5f2010-01-05 23:20:30165} // namespace IPC