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_EVENT1("ipc,toplevel", "ChannelReader::DispatchInputData", "name", | 158 TRACE_EVENT1("ipc,toplevel", "ChannelReader::DispatchInputData", "name", |
168 name); | 159 name); |
169 #else | 160 #else |
170 TRACE_EVENT2("ipc,toplevel", "ChannelReader::DispatchInputData", "class", | 161 TRACE_EVENT2("ipc,toplevel", "ChannelReader::DispatchInputData", "class", |
(...skipping 17 matching lines...) Expand all Loading... |
188 if (m->dispatch_error()) | 179 if (m->dispatch_error()) |
189 listener_->OnBadMessageReceived(*m); | 180 listener_->OnBadMessageReceived(*m); |
190 } | 181 } |
191 | 182 |
192 ChannelReader::AttachmentIdSet ChannelReader::GetBrokeredAttachments( | 183 ChannelReader::AttachmentIdSet ChannelReader::GetBrokeredAttachments( |
193 Message* msg) { | 184 Message* msg) { |
194 std::set<BrokerableAttachment::AttachmentId> blocked_ids; | 185 std::set<BrokerableAttachment::AttachmentId> blocked_ids; |
195 | 186 |
196 #if USE_ATTACHMENT_BROKER | 187 #if USE_ATTACHMENT_BROKER |
197 MessageAttachmentSet* set = msg->attachment_set(); | 188 MessageAttachmentSet* set = msg->attachment_set(); |
198 std::vector<const BrokerableAttachment*> brokerable_attachments_copy = | 189 for (const scoped_refptr<BrokerableAttachment>& attachment : |
199 set->PeekBrokerableAttachments(); | 190 set->GetBrokerableAttachmentsForUpdating()) { |
200 for (const BrokerableAttachment* attachment : brokerable_attachments_copy) { | |
201 if (attachment->NeedsBrokering()) { | 191 if (attachment->NeedsBrokering()) { |
202 AttachmentBroker* broker = GetAttachmentBroker(); | 192 AttachmentBroker* broker = GetAttachmentBroker(); |
203 scoped_refptr<BrokerableAttachment> brokered_attachment; | 193 scoped_refptr<BrokerableAttachment> brokered_attachment; |
204 bool result = broker->GetAttachmentWithId(attachment->GetIdentifier(), | 194 bool result = broker->GetAttachmentWithId(attachment->GetIdentifier(), |
205 &brokered_attachment); | 195 &brokered_attachment); |
206 if (!result) { | 196 if (!result) { |
207 blocked_ids.insert(attachment->GetIdentifier()); | 197 blocked_ids.insert(attachment->GetIdentifier()); |
208 continue; | 198 continue; |
209 } | 199 } |
210 | 200 |
211 set->ReplacePlaceholderWithAttachment(brokered_attachment); | 201 attachment->PopulateWithAttachment(brokered_attachment.get()); |
212 } | 202 } |
213 } | 203 } |
214 #endif // USE_ATTACHMENT_BROKER | 204 #endif // USE_ATTACHMENT_BROKER |
215 | 205 |
216 return blocked_ids; | 206 return blocked_ids; |
217 } | 207 } |
218 | 208 |
219 void ChannelReader::ReceivedBrokerableAttachmentWithId( | 209 void ChannelReader::ReceivedBrokerableAttachmentWithId( |
220 const BrokerableAttachment::AttachmentId& id) { | 210 const BrokerableAttachment::AttachmentId& id) { |
221 if (blocked_ids_.empty()) | 211 if (blocked_ids_.empty()) |
(...skipping 16 matching lines...) Expand all Loading... |
238 } | 228 } |
239 | 229 |
240 void ChannelReader::StopObservingAttachmentBroker() { | 230 void ChannelReader::StopObservingAttachmentBroker() { |
241 #if USE_ATTACHMENT_BROKER | 231 #if USE_ATTACHMENT_BROKER |
242 GetAttachmentBroker()->RemoveObserver(this); | 232 GetAttachmentBroker()->RemoveObserver(this); |
243 #endif // USE_ATTACHMENT_BROKER | 233 #endif // USE_ATTACHMENT_BROKER |
244 } | 234 } |
245 | 235 |
246 } // namespace internal | 236 } // namespace internal |
247 } // namespace IPC | 237 } // namespace IPC |
OLD | NEW |