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