Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: content/browser/message_port_service.cc

Issue 785133006: Enable messaging over a navigator.connect initiated channel. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@navigator-connect_serviceside
Patch Set: comments Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698