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_message_filter.h" |
8 #include "content/common/message_port_messages.h" | 8 #include "content/common/message_port_messages.h" |
9 | 9 |
10 namespace content { | 10 namespace content { |
11 | 11 |
12 struct MessagePortService::MessagePort { | 12 struct MessagePortService::MessagePort { |
13 // |filter| and |route_id| are what we need to send messages to the port. | 13 // |filter| 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 | 14 // |filter| is just a weak pointer since we get notified when its process has |
15 // gone away and remove it. | 15 // gone away and remove it. |
16 MessagePortMessageFilter* filter; | 16 MessagePortHandler* filter; |
17 int route_id; | 17 int route_id; |
18 // A globally unique id for this message port. | 18 // A globally unique id for this message port. |
19 int message_port_id; | 19 int message_port_id; |
20 // The globally unique id of the entangled message port. | 20 // The globally unique id of the entangled message port. |
21 int entangled_message_port_id; | 21 int entangled_message_port_id; |
22 // If true, all messages to this message port are queued and not delivered. | 22 // 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 | 23 // 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 | 24 // pending message get transferred. There are two possibilities for pending |
25 // messages: either they are already received by the child process, or they're | 25 // 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 | 26 // in-flight. This flag ensures that the latter type get flushed through the |
(...skipping 25 matching lines...) Expand all Loading... |
52 return Singleton<MessagePortService>::get(); | 52 return Singleton<MessagePortService>::get(); |
53 } | 53 } |
54 | 54 |
55 MessagePortService::MessagePortService() | 55 MessagePortService::MessagePortService() |
56 : next_message_port_id_(0) { | 56 : next_message_port_id_(0) { |
57 } | 57 } |
58 | 58 |
59 MessagePortService::~MessagePortService() { | 59 MessagePortService::~MessagePortService() { |
60 } | 60 } |
61 | 61 |
62 void MessagePortService::UpdateMessagePort( | 62 void MessagePortService::UpdateMessagePort(int message_port_id, |
63 int message_port_id, | 63 MessagePortHandler* filter, |
64 MessagePortMessageFilter* filter, | 64 int routing_id) { |
65 int routing_id) { | |
66 if (!message_ports_.count(message_port_id)) { | 65 if (!message_ports_.count(message_port_id)) { |
67 NOTREACHED(); | 66 NOTREACHED(); |
68 return; | 67 return; |
69 } | 68 } |
70 | 69 |
71 MessagePort& port = message_ports_[message_port_id]; | 70 MessagePort& port = message_ports_[message_port_id]; |
72 port.filter = filter; | 71 port.filter = filter; |
73 port.route_id = routing_id; | 72 port.route_id = routing_id; |
74 } | 73 } |
75 | 74 |
76 void MessagePortService::OnMessagePortMessageFilterClosing( | 75 void MessagePortService::OnMessagePortMessageFilterClosing( |
77 MessagePortMessageFilter* filter) { | 76 MessagePortHandler* filter) { |
78 // Check if the (possibly) crashed process had any message ports. | 77 // Check if the (possibly) crashed process had any message ports. |
79 for (MessagePorts::iterator iter = message_ports_.begin(); | 78 for (MessagePorts::iterator iter = message_ports_.begin(); |
80 iter != message_ports_.end();) { | 79 iter != message_ports_.end();) { |
81 MessagePorts::iterator cur_item = iter++; | 80 MessagePorts::iterator cur_item = iter++; |
82 if (cur_item->second.filter == filter) { | 81 if (cur_item->second.filter == filter) { |
83 Erase(cur_item->first); | 82 Erase(cur_item->first); |
84 } | 83 } |
85 } | 84 } |
86 } | 85 } |
87 | 86 |
88 void MessagePortService::Create(int route_id, | 87 void MessagePortService::Create(int route_id, |
89 MessagePortMessageFilter* filter, | 88 MessagePortHandler* filter, |
90 int* message_port_id) { | 89 int* message_port_id) { |
91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
92 *message_port_id = ++next_message_port_id_; | 91 *message_port_id = ++next_message_port_id_; |
93 | 92 |
94 MessagePort port; | 93 MessagePort port; |
95 port.filter = filter; | 94 port.filter = filter; |
96 port.route_id = route_id; | 95 port.route_id = route_id; |
97 port.message_port_id = *message_port_id; | 96 port.message_port_id = *message_port_id; |
98 port.entangled_message_port_id = MSG_ROUTING_NONE; | 97 port.entangled_message_port_id = MSG_ROUTING_NONE; |
99 port.queue_for_inflight_messages = false; | 98 port.queue_for_inflight_messages = false; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 entangled_port.queued_messages.push_back( | 180 entangled_port.queued_messages.push_back( |
182 std::make_pair(message, sent_message_port_ids)); | 181 std::make_pair(message, sent_message_port_ids)); |
183 return; | 182 return; |
184 } | 183 } |
185 | 184 |
186 if (!entangled_port.filter) { | 185 if (!entangled_port.filter) { |
187 NOTREACHED(); | 186 NOTREACHED(); |
188 return; | 187 return; |
189 } | 188 } |
190 | 189 |
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. | 190 // Now send the message to the entangled port. |
204 entangled_port.filter->Send(new MessagePortMsg_Message( | 191 entangled_port.filter->SendMessage(entangled_port.route_id, message, |
205 entangled_port.route_id, message, sent_message_port_ids, | 192 sent_message_port_ids); |
206 new_routing_ids)); | |
207 } | 193 } |
208 | 194 |
209 void MessagePortService::QueueMessages(int message_port_id) { | 195 void MessagePortService::QueueMessages(int message_port_id) { |
210 if (!message_ports_.count(message_port_id)) { | 196 if (!message_ports_.count(message_port_id)) { |
211 NOTREACHED(); | 197 NOTREACHED(); |
212 return; | 198 return; |
213 } | 199 } |
214 | 200 |
215 MessagePort& port = message_ports_[message_port_id]; | 201 MessagePort& port = message_ports_[message_port_id]; |
216 if (port.filter) { | 202 if (port.filter) { |
217 port.filter->Send(new MessagePortMsg_MessagesQueued(port.route_id)); | 203 port.filter->SendMessagesQueued(port.route_id); |
218 port.queue_for_inflight_messages = true; | 204 port.queue_for_inflight_messages = true; |
219 port.filter = NULL; | 205 port.filter = NULL; |
220 } | 206 } |
221 } | 207 } |
222 | 208 |
223 void MessagePortService::SendQueuedMessages( | 209 void MessagePortService::SendQueuedMessages( |
224 int message_port_id, | 210 int message_port_id, |
225 const QueuedMessages& queued_messages) { | 211 const QueuedMessages& queued_messages) { |
226 if (!message_ports_.count(message_port_id)) { | 212 if (!message_ports_.count(message_port_id)) { |
227 NOTREACHED(); | 213 NOTREACHED(); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 // Do the disentanglement (and be paranoid about the other side existing | 306 // Do the disentanglement (and be paranoid about the other side existing |
321 // just in case something unusual happened during entanglement). | 307 // just in case something unusual happened during entanglement). |
322 if (message_ports_.count(entangled_id)) { | 308 if (message_ports_.count(entangled_id)) { |
323 message_ports_[entangled_id].entangled_message_port_id = MSG_ROUTING_NONE; | 309 message_ports_[entangled_id].entangled_message_port_id = MSG_ROUTING_NONE; |
324 } | 310 } |
325 } | 311 } |
326 message_ports_.erase(erase_item); | 312 message_ports_.erase(erase_item); |
327 } | 313 } |
328 | 314 |
329 } // namespace content | 315 } // namespace content |
OLD | NEW |