| 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 |