Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/message_port_service.h" | 5 #include "content/browser/message_port_service.h" |
| 6 | 6 |
| 7 #include "content/browser/message_port_message_filter.h" | 7 #include "content/browser/message_port_delegate.h" |
| 8 #include "content/common/message_port_messages.h" | 8 #include "content/common/message_port_messages.h" |
| 9 #include "content/public/browser/browser_thread.h" | |
| 9 | 10 |
| 10 namespace content { | 11 namespace content { |
| 11 | 12 |
| 12 struct MessagePortService::MessagePort { | 13 struct MessagePortService::MessagePort { |
| 13 // |filter| and |route_id| are what we need to send messages to the port. | 14 // |delegate| and |route_id| are what we need to send messages to the port. |
| 14 // |filter| is just a weak pointer since we get notified when its process has | 15 // |delegate| is just a weak pointer since we get notified when its process |
|
scheib
2014/12/18 00:24:10
Old comment out of date, I suggest:
"|delegate| is
Marijn Kruisselbrink
2014/12/19 00:09:21
Done.
| |
| 15 // gone away and remove it. | 16 // has gone away and remove it. |
| 16 MessagePortMessageFilter* filter; | 17 MessagePortDelegate* delegate; |
| 17 int route_id; | 18 int route_id; |
| 18 // A globally unique id for this message port. | 19 // A globally unique id for this message port. |
| 19 int message_port_id; | 20 int message_port_id; |
| 20 // The globally unique id of the entangled message port. | 21 // The globally unique id of the entangled message port. |
| 21 int entangled_message_port_id; | 22 int entangled_message_port_id; |
| 22 // If true, all messages to this message port are queued and not delivered. | 23 // If true, all messages to this message port are queued and not delivered. |
| 23 // This is needed so that when a message port is sent between processes all | 24 // This is needed so that when a message port is sent between processes all |
| 24 // pending message get transferred. There are two possibilities for pending | 25 // pending message get transferred. There are two possibilities for pending |
| 25 // messages: either they are already received by the child process, or they're | 26 // messages: either they are already received by the child process, or they're |
| 26 // in-flight. This flag ensures that the latter type get flushed through the | 27 // in-flight. This flag ensures that the latter type get flushed through the |
| 27 // system. | 28 // system. |
| 28 // This flag should only be set to true in response to | 29 // This flag should only be set to true in response to |
| 29 // MessagePortHostMsg_QueueMessages. | 30 // MessagePortHostMsg_QueueMessages. |
| 30 bool queue_for_inflight_messages; | 31 bool queue_for_inflight_messages; |
| 31 // If true, all messages to this message port are queued and not delivered. | 32 // If true, all messages to this message port are queued and not delivered. |
| 32 // This is needed so that when a message port is sent to a new process all | 33 // This is needed so that when a message port is sent to a new process all |
| 33 // messages are held in the browser process until the destination process is | 34 // messages are held in the browser process until the destination process is |
| 34 // ready to receive messages. This flag is set true when a message port is | 35 // ready to receive messages. This flag is set true when a message port is |
| 35 // transferred to a different process but there isn't immediately a | 36 // transferred to a different process but there isn't immediately a |
| 36 // MessagePortMessageFilter available for that new process. Once the | 37 // MessagePortDelegate available for that new process. Once the |
| 37 // destination process is ready to receive messages it sends | 38 // destination process is ready to receive messages it sends |
| 38 // MessagePortHostMsg_ReleaseMessages to set this flag to false. | 39 // MessagePortHostMsg_ReleaseMessages to set this flag to false. |
| 39 bool hold_messages_for_destination; | 40 bool hold_messages_for_destination; |
| 40 // Returns true if messages should be queued for either reason. | 41 // Returns true if messages should be queued for either reason. |
| 41 bool queue_messages() const { | 42 bool queue_messages() const { |
| 42 return queue_for_inflight_messages || hold_messages_for_destination; | 43 return queue_for_inflight_messages || hold_messages_for_destination; |
| 43 } | 44 } |
| 44 // If true, the message port should be destroyed but was currently still | 45 // If true, the message port should be destroyed but was currently still |
| 45 // waiting for a SendQueuedMessages message from a renderer. As soon as that | 46 // waiting for a SendQueuedMessages message from a renderer. As soon as that |
| 46 // message is received the port will actually be destroyed. | 47 // message is received the port will actually be destroyed. |
| 47 bool should_be_destroyed; | 48 bool should_be_destroyed; |
| 48 QueuedMessages queued_messages; | 49 QueuedMessages queued_messages; |
| 49 }; | 50 }; |
| 50 | 51 |
| 51 MessagePortService* MessagePortService::GetInstance() { | 52 MessagePortService* MessagePortService::GetInstance() { |
| 52 return Singleton<MessagePortService>::get(); | 53 return Singleton<MessagePortService>::get(); |
| 53 } | 54 } |
| 54 | 55 |
| 55 MessagePortService::MessagePortService() | 56 MessagePortService::MessagePortService() |
| 56 : next_message_port_id_(0) { | 57 : next_message_port_id_(0) { |
| 57 } | 58 } |
| 58 | 59 |
| 59 MessagePortService::~MessagePortService() { | 60 MessagePortService::~MessagePortService() { |
| 60 } | 61 } |
| 61 | 62 |
| 62 void MessagePortService::UpdateMessagePort( | 63 void MessagePortService::UpdateMessagePort(int message_port_id, |
| 63 int message_port_id, | 64 MessagePortDelegate* delegate, |
| 64 MessagePortMessageFilter* filter, | 65 int routing_id) { |
| 65 int routing_id) { | |
| 66 if (!message_ports_.count(message_port_id)) { | 66 if (!message_ports_.count(message_port_id)) { |
| 67 NOTREACHED(); | 67 NOTREACHED(); |
| 68 return; | 68 return; |
| 69 } | 69 } |
| 70 | 70 |
| 71 MessagePort& port = message_ports_[message_port_id]; | 71 MessagePort& port = message_ports_[message_port_id]; |
| 72 port.filter = filter; | 72 port.delegate = delegate; |
| 73 port.route_id = routing_id; | 73 port.route_id = routing_id; |
| 74 } | 74 } |
| 75 | 75 |
| 76 void MessagePortService::OnMessagePortMessageFilterClosing( | 76 void MessagePortService::OnMessagePortDelegateClosing( |
| 77 MessagePortMessageFilter* filter) { | 77 MessagePortDelegate* delegate) { |
| 78 // Check if the (possibly) crashed process had any message ports. | 78 // Check if the (possibly) crashed process had any message ports. |
| 79 for (MessagePorts::iterator iter = message_ports_.begin(); | 79 for (MessagePorts::iterator iter = message_ports_.begin(); |
| 80 iter != message_ports_.end();) { | 80 iter != message_ports_.end();) { |
| 81 MessagePorts::iterator cur_item = iter++; | 81 MessagePorts::iterator cur_item = iter++; |
| 82 if (cur_item->second.filter == filter) { | 82 if (cur_item->second.delegate == delegate) { |
| 83 Erase(cur_item->first); | 83 Erase(cur_item->first); |
| 84 } | 84 } |
| 85 } | 85 } |
| 86 } | 86 } |
| 87 | 87 |
| 88 void MessagePortService::Create(int route_id, | 88 void MessagePortService::Create(int route_id, |
| 89 MessagePortMessageFilter* filter, | 89 MessagePortDelegate* delegate, |
| 90 int* message_port_id) { | 90 int* message_port_id) { |
| 91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 92 *message_port_id = ++next_message_port_id_; | 92 *message_port_id = ++next_message_port_id_; |
| 93 | 93 |
| 94 MessagePort port; | 94 MessagePort port; |
| 95 port.filter = filter; | 95 port.delegate = delegate; |
| 96 port.route_id = route_id; | 96 port.route_id = route_id; |
| 97 port.message_port_id = *message_port_id; | 97 port.message_port_id = *message_port_id; |
| 98 port.entangled_message_port_id = MSG_ROUTING_NONE; | 98 port.entangled_message_port_id = MSG_ROUTING_NONE; |
| 99 port.queue_for_inflight_messages = false; | 99 port.queue_for_inflight_messages = false; |
| 100 port.hold_messages_for_destination = false; | 100 port.hold_messages_for_destination = false; |
| 101 port.should_be_destroyed = false; | 101 port.should_be_destroyed = false; |
| 102 message_ports_[*message_port_id] = port; | 102 message_ports_[*message_port_id] = port; |
| 103 } | 103 } |
| 104 | 104 |
| 105 void MessagePortService::Destroy(int message_port_id) { | 105 void MessagePortService::Destroy(int message_port_id) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 176 // put in this state. | 176 // put in this state. |
| 177 if (entangled_port.hold_messages_for_destination) { | 177 if (entangled_port.hold_messages_for_destination) { |
| 178 for (int sent_message_port_id : sent_message_port_ids) | 178 for (int sent_message_port_id : sent_message_port_ids) |
| 179 HoldMessages(sent_message_port_id); | 179 HoldMessages(sent_message_port_id); |
| 180 } | 180 } |
| 181 entangled_port.queued_messages.push_back( | 181 entangled_port.queued_messages.push_back( |
| 182 std::make_pair(message, sent_message_port_ids)); | 182 std::make_pair(message, sent_message_port_ids)); |
| 183 return; | 183 return; |
| 184 } | 184 } |
| 185 | 185 |
| 186 if (!entangled_port.filter) { | 186 if (!entangled_port.delegate) { |
| 187 NOTREACHED(); | 187 NOTREACHED(); |
| 188 return; | 188 return; |
| 189 } | 189 } |
| 190 | 190 |
| 191 // If a message port was sent around, the new location will need a routing | |
| 192 // id. Instead of having the created port send us a sync message to get it, | |
| 193 // send along with the message. | |
| 194 std::vector<int> new_routing_ids(sent_message_port_ids.size()); | |
| 195 for (size_t i = 0; i < sent_message_port_ids.size(); ++i) { | |
| 196 new_routing_ids[i] = entangled_port.filter->GetNextRoutingID(); | |
| 197 sent_ports[i]->filter = entangled_port.filter; | |
| 198 | |
| 199 // Update the entry for the sent port as it can be in a different process. | |
| 200 sent_ports[i]->route_id = new_routing_ids[i]; | |
| 201 } | |
| 202 | |
| 203 // Now send the message to the entangled port. | 191 // Now send the message to the entangled port. |
| 204 entangled_port.filter->Send(new MessagePortMsg_Message( | 192 entangled_port.delegate->SendMessage(entangled_port.route_id, message, |
| 205 entangled_port.route_id, message, sent_message_port_ids, | 193 sent_message_port_ids); |
| 206 new_routing_ids)); | |
| 207 } | 194 } |
| 208 | 195 |
| 209 void MessagePortService::QueueMessages(int message_port_id) { | 196 void MessagePortService::QueueMessages(int message_port_id) { |
| 210 if (!message_ports_.count(message_port_id)) { | 197 if (!message_ports_.count(message_port_id)) { |
| 211 NOTREACHED(); | 198 NOTREACHED(); |
| 212 return; | 199 return; |
| 213 } | 200 } |
| 214 | 201 |
| 215 MessagePort& port = message_ports_[message_port_id]; | 202 MessagePort& port = message_ports_[message_port_id]; |
| 216 if (port.filter) { | 203 if (port.delegate) { |
| 217 port.filter->Send(new MessagePortMsg_MessagesQueued(port.route_id)); | 204 port.delegate->SendMessagesAreQueued(port.route_id); |
| 218 port.queue_for_inflight_messages = true; | 205 port.queue_for_inflight_messages = true; |
| 219 port.filter = NULL; | 206 port.delegate = NULL; |
| 220 } | 207 } |
| 221 } | 208 } |
| 222 | 209 |
| 223 void MessagePortService::SendQueuedMessages( | 210 void MessagePortService::SendQueuedMessages( |
| 224 int message_port_id, | 211 int message_port_id, |
| 225 const QueuedMessages& queued_messages) { | 212 const QueuedMessages& queued_messages) { |
| 226 if (!message_ports_.count(message_port_id)) { | 213 if (!message_ports_.count(message_port_id)) { |
| 227 NOTREACHED(); | 214 NOTREACHED(); |
| 228 return; | 215 return; |
| 229 } | 216 } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 251 SendQueuedMessagesIfPossible(message_port_id); | 238 SendQueuedMessagesIfPossible(message_port_id); |
| 252 } | 239 } |
| 253 | 240 |
| 254 void MessagePortService::SendQueuedMessagesIfPossible(int message_port_id) { | 241 void MessagePortService::SendQueuedMessagesIfPossible(int message_port_id) { |
| 255 if (!message_ports_.count(message_port_id)) { | 242 if (!message_ports_.count(message_port_id)) { |
| 256 NOTREACHED(); | 243 NOTREACHED(); |
| 257 return; | 244 return; |
| 258 } | 245 } |
| 259 | 246 |
| 260 MessagePort& port = message_ports_[message_port_id]; | 247 MessagePort& port = message_ports_[message_port_id]; |
| 261 if (port.queue_messages() || !port.filter) | 248 if (port.queue_messages() || !port.delegate) |
| 262 return; | 249 return; |
| 263 | 250 |
| 264 for (QueuedMessages::iterator iter = port.queued_messages.begin(); | 251 for (QueuedMessages::iterator iter = port.queued_messages.begin(); |
| 265 iter != port.queued_messages.end(); ++iter) { | 252 iter != port.queued_messages.end(); ++iter) { |
| 266 PostMessageTo(message_port_id, iter->first, iter->second); | 253 PostMessageTo(message_port_id, iter->first, iter->second); |
| 267 } | 254 } |
| 268 port.queued_messages.clear(); | 255 port.queued_messages.clear(); |
| 269 } | 256 } |
| 270 | 257 |
| 271 void MessagePortService::HoldMessages(int message_port_id) { | 258 void MessagePortService::HoldMessages(int message_port_id) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 // Do the disentanglement (and be paranoid about the other side existing | 307 // Do the disentanglement (and be paranoid about the other side existing |
| 321 // just in case something unusual happened during entanglement). | 308 // just in case something unusual happened during entanglement). |
| 322 if (message_ports_.count(entangled_id)) { | 309 if (message_ports_.count(entangled_id)) { |
| 323 message_ports_[entangled_id].entangled_message_port_id = MSG_ROUTING_NONE; | 310 message_ports_[entangled_id].entangled_message_port_id = MSG_ROUTING_NONE; |
| 324 } | 311 } |
| 325 } | 312 } |
| 326 message_ports_.erase(erase_item); | 313 message_ports_.erase(erase_item); |
| 327 } | 314 } |
| 328 | 315 |
| 329 } // namespace content | 316 } // namespace content |
| OLD | NEW |