OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ipc/ipc_channel_reader.h" | 5 #include "ipc/ipc_channel_reader.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "ipc/ipc_listener.h" | 9 #include "ipc/ipc_listener.h" |
10 #include "ipc/ipc_logging.h" | 10 #include "ipc/ipc_logging.h" |
11 #include "ipc/ipc_message.h" | 11 #include "ipc/ipc_message.h" |
12 #include "ipc/ipc_message_attachment_set.h" | 12 #include "ipc/ipc_message_attachment_set.h" |
13 #include "ipc/ipc_message_macros.h" | 13 #include "ipc/ipc_message_macros.h" |
14 | 14 |
15 namespace IPC { | 15 namespace IPC { |
16 namespace internal { | 16 namespace internal { |
17 | 17 |
18 ChannelReader::ChannelReader(Listener* listener) : listener_(listener) { | 18 ChannelReader::ChannelReader(Listener* listener) : listener_(listener) { |
19 memset(input_buf_, 0, sizeof(input_buf_)); | 19 memset(input_buf_, 0, sizeof(input_buf_)); |
20 } | 20 } |
21 | 21 |
22 ChannelReader::~ChannelReader() { | 22 ChannelReader::~ChannelReader() { |
23 if (!blocked_ids_.empty()) | 23 DCHECK(blocked_ids_.empty()); |
24 StopObservingAttachmentBroker(); | |
25 } | 24 } |
26 | 25 |
27 ChannelReader::DispatchState ChannelReader::ProcessIncomingMessages() { | 26 ChannelReader::DispatchState ChannelReader::ProcessIncomingMessages() { |
28 while (true) { | 27 while (true) { |
29 int bytes_read = 0; | 28 int bytes_read = 0; |
30 ReadState read_state = ReadData(input_buf_, Channel::kReadBufferSize, | 29 ReadState read_state = ReadData(input_buf_, Channel::kReadBufferSize, |
31 &bytes_read); | 30 &bytes_read); |
32 if (read_state == READ_FAILED) | 31 if (read_state == READ_FAILED) |
33 return DISPATCH_ERROR; | 32 return DISPATCH_ERROR; |
34 if (read_state == READ_PENDING) | 33 if (read_state == READ_PENDING) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 LOG(ERROR) << "IPC message is too big"; | 77 LOG(ERROR) << "IPC message is too big"; |
79 return false; | 78 return false; |
80 } | 79 } |
81 input_overflow_buf_.append(input_data, input_data_len); | 80 input_overflow_buf_.append(input_data, input_data_len); |
82 p = input_overflow_buf_.data(); | 81 p = input_overflow_buf_.data(); |
83 end = p + input_overflow_buf_.size(); | 82 end = p + input_overflow_buf_.size(); |
84 } | 83 } |
85 | 84 |
86 // Dispatch all complete messages in the data buffer. | 85 // Dispatch all complete messages in the data buffer. |
87 while (p < end) { | 86 while (p < end) { |
88 const char* message_tail = Message::FindNext(p, end); | 87 Message::NextMessageInfo info = Message::FindNext(p, end); |
89 if (message_tail) { | 88 if (info.message_found) { |
90 int len = static_cast<int>(message_tail - p); | 89 int pickle_len = static_cast<int>(info.pickle_end - p); |
| 90 Message translated_message(p, pickle_len); |
91 | 91 |
92 Message translated_message(p, len); | 92 for (const auto& id : info.attachment_ids) |
| 93 translated_message.AddPlaceholderBrokerableAttachmentWithId(id); |
| 94 |
93 if (!GetNonBrokeredAttachments(&translated_message)) | 95 if (!GetNonBrokeredAttachments(&translated_message)) |
94 return false; | 96 return false; |
95 | 97 |
96 // If there are no queued messages, attempt to immediately dispatch the | 98 // If there are no queued messages, attempt to immediately dispatch the |
97 // newly translated message. | 99 // newly translated message. |
98 if (queued_messages_.empty()) { | 100 if (queued_messages_.empty()) { |
99 DCHECK(blocked_ids_.empty()); | 101 DCHECK(blocked_ids_.empty()); |
100 AttachmentIdSet blocked_ids = | 102 AttachmentIdSet blocked_ids = |
101 GetBrokeredAttachments(&translated_message); | 103 GetBrokeredAttachments(&translated_message); |
102 | 104 |
103 if (blocked_ids.empty()) { | 105 if (blocked_ids.empty()) { |
104 // Dispatch the message and continue the loop. | 106 // Dispatch the message and continue the loop. |
105 DispatchMessage(&translated_message); | 107 DispatchMessage(&translated_message); |
106 p = message_tail; | 108 p = info.message_end; |
107 continue; | 109 continue; |
108 } | 110 } |
109 | 111 |
110 blocked_ids_.swap(blocked_ids); | 112 blocked_ids_.swap(blocked_ids); |
111 StartObservingAttachmentBroker(); | 113 StartObservingAttachmentBroker(); |
112 } | 114 } |
113 | 115 |
114 // Make a deep copy of |translated_message| to add to the queue. | 116 // Make a deep copy of |translated_message| to add to the queue. |
115 scoped_ptr<Message> m(new Message(translated_message)); | 117 scoped_ptr<Message> m(new Message(translated_message)); |
116 queued_messages_.push_back(m.release()); | 118 queued_messages_.push_back(m.release()); |
117 p = message_tail; | 119 p = info.message_end; |
118 } else { | 120 } else { |
119 // Last message is partial. | 121 // Last message is partial. |
120 break; | 122 break; |
121 } | 123 } |
122 } | 124 } |
123 | 125 |
124 // Save any partial data in the overflow buffer. | 126 // Save any partial data in the overflow buffer. |
125 input_overflow_buf_.assign(p, end - p); | 127 input_overflow_buf_.assign(p, end - p); |
126 | 128 |
127 if (input_overflow_buf_.empty() && !DidEmptyInputBuffers()) | 129 if (input_overflow_buf_.empty() && !DidEmptyInputBuffers()) |
(...skipping 14 matching lines...) Expand all Loading... |
142 StartObservingAttachmentBroker(); | 144 StartObservingAttachmentBroker(); |
143 return DISPATCH_WAITING_ON_BROKER; | 145 return DISPATCH_WAITING_ON_BROKER; |
144 } | 146 } |
145 | 147 |
146 DispatchMessage(m); | 148 DispatchMessage(m); |
147 queued_messages_.erase(queued_messages_.begin()); | 149 queued_messages_.erase(queued_messages_.begin()); |
148 } | 150 } |
149 return DISPATCH_FINISHED; | 151 return DISPATCH_FINISHED; |
150 } | 152 } |
151 | 153 |
| 154 void ChannelReader::CleanUp() { |
| 155 if (!blocked_ids_.empty()) { |
| 156 StopObservingAttachmentBroker(); |
| 157 blocked_ids_.clear(); |
| 158 } |
| 159 } |
| 160 |
152 void ChannelReader::DispatchMessage(Message* m) { | 161 void ChannelReader::DispatchMessage(Message* m) { |
153 m->set_sender_pid(GetSenderPID()); | 162 m->set_sender_pid(GetSenderPID()); |
154 | 163 |
155 #ifdef IPC_MESSAGE_LOG_ENABLED | 164 #ifdef IPC_MESSAGE_LOG_ENABLED |
156 std::string name; | 165 std::string name; |
157 Logging::GetInstance()->GetMessageText(m->type(), &name, m, NULL); | 166 Logging::GetInstance()->GetMessageText(m->type(), &name, m, NULL); |
158 TRACE_EVENT1("ipc,toplevel", "ChannelReader::DispatchInputData", "name", | 167 TRACE_EVENT1("ipc,toplevel", "ChannelReader::DispatchInputData", "name", |
159 name); | 168 name); |
160 #else | 169 #else |
161 TRACE_EVENT2("ipc,toplevel", "ChannelReader::DispatchInputData", "class", | 170 TRACE_EVENT2("ipc,toplevel", "ChannelReader::DispatchInputData", "class", |
(...skipping 17 matching lines...) Expand all Loading... |
179 if (m->dispatch_error()) | 188 if (m->dispatch_error()) |
180 listener_->OnBadMessageReceived(*m); | 189 listener_->OnBadMessageReceived(*m); |
181 } | 190 } |
182 | 191 |
183 ChannelReader::AttachmentIdSet ChannelReader::GetBrokeredAttachments( | 192 ChannelReader::AttachmentIdSet ChannelReader::GetBrokeredAttachments( |
184 Message* msg) { | 193 Message* msg) { |
185 std::set<BrokerableAttachment::AttachmentId> blocked_ids; | 194 std::set<BrokerableAttachment::AttachmentId> blocked_ids; |
186 | 195 |
187 #if USE_ATTACHMENT_BROKER | 196 #if USE_ATTACHMENT_BROKER |
188 MessageAttachmentSet* set = msg->attachment_set(); | 197 MessageAttachmentSet* set = msg->attachment_set(); |
189 for (const scoped_refptr<BrokerableAttachment>& attachment : | 198 std::vector<const BrokerableAttachment*> brokerable_attachments_copy = |
190 set->GetBrokerableAttachmentsForUpdating()) { | 199 set->PeekBrokerableAttachments(); |
| 200 for (const BrokerableAttachment* attachment : brokerable_attachments_copy) { |
191 if (attachment->NeedsBrokering()) { | 201 if (attachment->NeedsBrokering()) { |
192 AttachmentBroker* broker = GetAttachmentBroker(); | 202 AttachmentBroker* broker = GetAttachmentBroker(); |
193 scoped_refptr<BrokerableAttachment> brokered_attachment; | 203 scoped_refptr<BrokerableAttachment> brokered_attachment; |
194 bool result = broker->GetAttachmentWithId(attachment->GetIdentifier(), | 204 bool result = broker->GetAttachmentWithId(attachment->GetIdentifier(), |
195 &brokered_attachment); | 205 &brokered_attachment); |
196 if (!result) { | 206 if (!result) { |
197 blocked_ids.insert(attachment->GetIdentifier()); | 207 blocked_ids.insert(attachment->GetIdentifier()); |
198 continue; | 208 continue; |
199 } | 209 } |
200 | 210 |
201 attachment->PopulateWithAttachment(brokered_attachment.get()); | 211 set->ReplacePlaceholderWithAttachment(brokered_attachment); |
202 } | 212 } |
203 } | 213 } |
204 #endif // USE_ATTACHMENT_BROKER | 214 #endif // USE_ATTACHMENT_BROKER |
205 | 215 |
206 return blocked_ids; | 216 return blocked_ids; |
207 } | 217 } |
208 | 218 |
209 void ChannelReader::ReceivedBrokerableAttachmentWithId( | 219 void ChannelReader::ReceivedBrokerableAttachmentWithId( |
210 const BrokerableAttachment::AttachmentId& id) { | 220 const BrokerableAttachment::AttachmentId& id) { |
211 if (blocked_ids_.empty()) | 221 if (blocked_ids_.empty()) |
(...skipping 16 matching lines...) Expand all Loading... |
228 } | 238 } |
229 | 239 |
230 void ChannelReader::StopObservingAttachmentBroker() { | 240 void ChannelReader::StopObservingAttachmentBroker() { |
231 #if USE_ATTACHMENT_BROKER | 241 #if USE_ATTACHMENT_BROKER |
232 GetAttachmentBroker()->RemoveObserver(this); | 242 GetAttachmentBroker()->RemoveObserver(this); |
233 #endif // USE_ATTACHMENT_BROKER | 243 #endif // USE_ATTACHMENT_BROKER |
234 } | 244 } |
235 | 245 |
236 } // namespace internal | 246 } // namespace internal |
237 } // namespace IPC | 247 } // namespace IPC |
OLD | NEW |