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

Side by Side Diff: mojo/edk/system/node_controller.cc

Issue 2738853002: Connections now take a ConnectionParams instead of a pipe handle. (Closed)
Patch Set: Fix Win release build. Created 3 years, 9 months 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
« no previous file with comments | « mojo/edk/system/node_controller.h ('k') | mojo/edk/test/multiprocess_test_helper.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "mojo/edk/system/node_controller.h" 5 #include "mojo/edk/system/node_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 void NodeController::SetIOTaskRunner( 158 void NodeController::SetIOTaskRunner(
159 scoped_refptr<base::TaskRunner> task_runner) { 159 scoped_refptr<base::TaskRunner> task_runner) {
160 io_task_runner_ = task_runner; 160 io_task_runner_ = task_runner;
161 ThreadDestructionObserver::Create( 161 ThreadDestructionObserver::Create(
162 io_task_runner_, 162 io_task_runner_,
163 base::Bind(&NodeController::DropAllPeers, base::Unretained(this))); 163 base::Bind(&NodeController::DropAllPeers, base::Unretained(this)));
164 } 164 }
165 165
166 void NodeController::ConnectToChild( 166 void NodeController::ConnectToChild(
167 base::ProcessHandle process_handle, 167 base::ProcessHandle process_handle,
168 ScopedPlatformHandle platform_handle, 168 ConnectionParams connection_params,
169 const std::string& child_token, 169 const std::string& child_token,
170 const ProcessErrorCallback& process_error_callback) { 170 const ProcessErrorCallback& process_error_callback) {
171 // Generate the temporary remote node name here so that it can be associated 171 // Generate the temporary remote node name here so that it can be associated
172 // with the embedder's child_token. If an error occurs in the child process 172 // with the embedder's child_token. If an error occurs in the child process
173 // after it is launched, but before any reserved ports are connected, this can 173 // after it is launched, but before any reserved ports are connected, this can
174 // be used to clean up any dangling ports. 174 // be used to clean up any dangling ports.
175 ports::NodeName node_name; 175 ports::NodeName node_name;
176 GenerateRandomName(&node_name); 176 GenerateRandomName(&node_name);
177 177
178 { 178 {
(...skipping 10 matching lines...) Expand all
189 HANDLE dup_handle = INVALID_HANDLE_VALUE; 189 HANDLE dup_handle = INVALID_HANDLE_VALUE;
190 BOOL ok = ::DuplicateHandle( 190 BOOL ok = ::DuplicateHandle(
191 base::GetCurrentProcessHandle(), process_handle, 191 base::GetCurrentProcessHandle(), process_handle,
192 base::GetCurrentProcessHandle(), &dup_handle, 192 base::GetCurrentProcessHandle(), &dup_handle,
193 0, FALSE, DUPLICATE_SAME_ACCESS); 193 0, FALSE, DUPLICATE_SAME_ACCESS);
194 DPCHECK(ok); 194 DPCHECK(ok);
195 process_handle = dup_handle; 195 process_handle = dup_handle;
196 #endif 196 #endif
197 197
198 io_task_runner_->PostTask( 198 io_task_runner_->PostTask(
199 FROM_HERE, 199 FROM_HERE, base::Bind(&NodeController::ConnectToChildOnIOThread,
200 base::Bind(&NodeController::ConnectToChildOnIOThread, 200 base::Unretained(this), process_handle,
201 base::Unretained(this), 201 base::Passed(&connection_params), node_name,
202 process_handle, 202 process_error_callback));
203 base::Passed(&platform_handle),
204 node_name,
205 process_error_callback));
206 } 203 }
207 204
208 void NodeController::CloseChildPorts(const std::string& child_token) { 205 void NodeController::CloseChildPorts(const std::string& child_token) {
209 std::vector<ports::PortRef> ports_to_close; 206 std::vector<ports::PortRef> ports_to_close;
210 { 207 {
211 std::vector<std::string> port_tokens; 208 std::vector<std::string> port_tokens;
212 base::AutoLock lock(reserved_ports_lock_); 209 base::AutoLock lock(reserved_ports_lock_);
213 for (const auto& port : reserved_ports_) { 210 for (const auto& port : reserved_ports_) {
214 if (port.second.child_token == child_token) { 211 if (port.second.child_token == child_token) {
215 DVLOG(1) << "Closing reserved port " << port.second.port.name(); 212 DVLOG(1) << "Closing reserved port " << port.second.port.name();
(...skipping 12 matching lines...) Expand all
228 // Ensure local port closure messages are processed. 225 // Ensure local port closure messages are processed.
229 AcceptIncomingMessages(); 226 AcceptIncomingMessages();
230 } 227 }
231 228
232 void NodeController::ClosePeerConnection(const std::string& peer_token) { 229 void NodeController::ClosePeerConnection(const std::string& peer_token) {
233 io_task_runner_->PostTask( 230 io_task_runner_->PostTask(
234 FROM_HERE, base::Bind(&NodeController::ClosePeerConnectionOnIOThread, 231 FROM_HERE, base::Bind(&NodeController::ClosePeerConnectionOnIOThread,
235 base::Unretained(this), peer_token)); 232 base::Unretained(this), peer_token));
236 } 233 }
237 234
238 void NodeController::ConnectToParent(ScopedPlatformHandle platform_handle) { 235 void NodeController::ConnectToParent(ConnectionParams connection_params) {
239 #if !defined(OS_MACOSX) && !defined(OS_NACL_SFI) 236 #if !defined(OS_MACOSX) && !defined(OS_NACL_SFI)
240 // Use the bootstrap channel for the broker and receive the node's channel 237 // Use the bootstrap channel for the broker and receive the node's channel
241 // synchronously as the first message from the broker. 238 // synchronously as the first message from the broker.
242 base::ElapsedTimer timer; 239 base::ElapsedTimer timer;
243 broker_.reset(new Broker(std::move(platform_handle))); 240 broker_.reset(new Broker(connection_params.TakeChannelHandle()));
244 platform_handle = broker_->GetParentPlatformHandle(); 241 ScopedPlatformHandle platform_handle = broker_->GetParentPlatformHandle();
245 UMA_HISTOGRAM_TIMES("Mojo.System.GetParentPlatformHandleSyncTime", 242 UMA_HISTOGRAM_TIMES("Mojo.System.GetParentPlatformHandleSyncTime",
246 timer.Elapsed()); 243 timer.Elapsed());
247 244
248 if (!platform_handle.is_valid()) { 245 if (!platform_handle.is_valid()) {
249 // Most likely the browser side of the channel has already been closed and 246 // Most likely the browser side of the channel has already been closed and
250 // the broker was unable to negotiate a NodeChannel pipe. In this case we 247 // the broker was unable to negotiate a NodeChannel pipe. In this case we
251 // can cancel parent connection. 248 // can cancel parent connection.
252 DVLOG(1) << "Cannot connect to invalid parent channel."; 249 DVLOG(1) << "Cannot connect to invalid parent channel.";
253 CancelPendingPortMerges(); 250 CancelPendingPortMerges();
254 return; 251 return;
255 } 252 }
253 connection_params = ConnectionParams(std::move(platform_handle));
256 #endif 254 #endif
257 255
258 io_task_runner_->PostTask( 256 io_task_runner_->PostTask(
259 FROM_HERE, 257 FROM_HERE,
260 base::Bind(&NodeController::ConnectToParentOnIOThread, 258 base::Bind(&NodeController::ConnectToParentOnIOThread,
261 base::Unretained(this), 259 base::Unretained(this), base::Passed(&connection_params)));
262 base::Passed(&platform_handle)));
263 } 260 }
264 261
265 void NodeController::ConnectToPeer(ScopedPlatformHandle handle, 262 void NodeController::ConnectToPeer(ConnectionParams connection_params,
266 const ports::PortRef& port, 263 const ports::PortRef& port,
267 const std::string& peer_token) { 264 const std::string& peer_token) {
268 ports::NodeName node_name; 265 ports::NodeName node_name;
269 GenerateRandomName(&node_name); 266 GenerateRandomName(&node_name);
270 io_task_runner_->PostTask( 267 io_task_runner_->PostTask(
271 FROM_HERE, base::Bind(&NodeController::ConnectToPeerOnIOThread, 268 FROM_HERE,
272 base::Unretained(this), base::Passed(&handle), 269 base::Bind(&NodeController::ConnectToPeerOnIOThread,
273 node_name, port, peer_token)); 270 base::Unretained(this), base::Passed(&connection_params),
271 node_name, port, peer_token));
274 } 272 }
275 273
276 void NodeController::SetPortObserver(const ports::PortRef& port, 274 void NodeController::SetPortObserver(const ports::PortRef& port,
277 scoped_refptr<PortObserver> observer) { 275 scoped_refptr<PortObserver> observer) {
278 node_->SetUserData(port, std::move(observer)); 276 node_->SetUserData(port, std::move(observer));
279 } 277 }
280 278
281 void NodeController::ClosePort(const ports::PortRef& port) { 279 void NodeController::ClosePort(const ports::PortRef& port) {
282 SetPortObserver(port, nullptr); 280 SetPortObserver(port, nullptr);
283 int rv = node_->ClosePort(port); 281 int rv = node_->ClosePort(port);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 385
388 void NodeController::NotifyBadMessageFrom(const ports::NodeName& source_node, 386 void NodeController::NotifyBadMessageFrom(const ports::NodeName& source_node,
389 const std::string& error) { 387 const std::string& error) {
390 scoped_refptr<NodeChannel> peer = GetPeerChannel(source_node); 388 scoped_refptr<NodeChannel> peer = GetPeerChannel(source_node);
391 if (peer) 389 if (peer)
392 peer->NotifyBadMessage(error); 390 peer->NotifyBadMessage(error);
393 } 391 }
394 392
395 void NodeController::ConnectToChildOnIOThread( 393 void NodeController::ConnectToChildOnIOThread(
396 base::ProcessHandle process_handle, 394 base::ProcessHandle process_handle,
397 ScopedPlatformHandle platform_handle, 395 ConnectionParams connection_params,
398 ports::NodeName token, 396 ports::NodeName token,
399 const ProcessErrorCallback& process_error_callback) { 397 const ProcessErrorCallback& process_error_callback) {
400 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 398 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
401 399
402 #if !defined(OS_MACOSX) && !defined(OS_NACL) 400 #if !defined(OS_MACOSX) && !defined(OS_NACL)
403 PlatformChannelPair node_channel; 401 PlatformChannelPair node_channel;
404 ScopedPlatformHandle server_handle = node_channel.PassServerHandle(); 402 ScopedPlatformHandle server_handle = node_channel.PassServerHandle();
405 // BrokerHost owns itself. 403 // BrokerHost owns itself.
406 BrokerHost* broker_host = 404 BrokerHost* broker_host =
407 new BrokerHost(process_handle, std::move(platform_handle)); 405 new BrokerHost(process_handle, connection_params.TakeChannelHandle());
408 bool channel_ok = broker_host->SendChannel(node_channel.PassClientHandle()); 406 bool channel_ok = broker_host->SendChannel(node_channel.PassClientHandle());
409 407
410 #if defined(OS_WIN) 408 #if defined(OS_WIN)
411 if (!channel_ok) { 409 if (!channel_ok) {
412 // On Windows the above operation may fail if the channel is crossing a 410 // On Windows the above operation may fail if the channel is crossing a
413 // session boundary. In that case we fall back to a named pipe. 411 // session boundary. In that case we fall back to a named pipe.
414 NamedPlatformChannelPair named_channel; 412 NamedPlatformChannelPair named_channel;
415 server_handle = named_channel.PassServerHandle(); 413 server_handle = named_channel.PassServerHandle();
416 broker_host->SendNamedChannel(named_channel.handle().name); 414 broker_host->SendNamedChannel(named_channel.handle().name);
417 } 415 }
418 #else 416 #else
419 CHECK(channel_ok); 417 CHECK(channel_ok);
420 #endif // defined(OS_WIN) 418 #endif // defined(OS_WIN)
421 419
422 scoped_refptr<NodeChannel> channel = NodeChannel::Create( 420 scoped_refptr<NodeChannel> channel =
423 this, std::move(server_handle), io_task_runner_, process_error_callback); 421 NodeChannel::Create(this, ConnectionParams(std::move(server_handle)),
422 io_task_runner_, process_error_callback);
424 423
425 #else // !defined(OS_MACOSX) && !defined(OS_NACL) 424 #else // !defined(OS_MACOSX) && !defined(OS_NACL)
426 scoped_refptr<NodeChannel> channel = 425 scoped_refptr<NodeChannel> channel =
427 NodeChannel::Create(this, std::move(platform_handle), io_task_runner_, 426 NodeChannel::Create(this, std::move(connection_params), io_task_runner_,
428 process_error_callback); 427 process_error_callback);
429 #endif // !defined(OS_MACOSX) && !defined(OS_NACL) 428 #endif // !defined(OS_MACOSX) && !defined(OS_NACL)
430 429
431 // We set up the child channel with a temporary name so it can be identified 430 // We set up the child channel with a temporary name so it can be identified
432 // as a pending child if it writes any messages to the channel. We may start 431 // as a pending child if it writes any messages to the channel. We may start
433 // receiving messages from it (though we shouldn't) as soon as Start() is 432 // receiving messages from it (though we shouldn't) as soon as Start() is
434 // called below. 433 // called below.
435 434
436 pending_children_.insert(std::make_pair(token, channel)); 435 pending_children_.insert(std::make_pair(token, channel));
437 RecordPendingChildCount(pending_children_.size()); 436 RecordPendingChildCount(pending_children_.size());
438 437
439 channel->SetRemoteNodeName(token); 438 channel->SetRemoteNodeName(token);
440 channel->SetRemoteProcessHandle(process_handle); 439 channel->SetRemoteProcessHandle(process_handle);
441 channel->Start(); 440 channel->Start();
442 441
443 channel->AcceptChild(name_, token); 442 channel->AcceptChild(name_, token);
444 } 443 }
445 444
446 void NodeController::ConnectToParentOnIOThread( 445 void NodeController::ConnectToParentOnIOThread(
447 ScopedPlatformHandle platform_handle) { 446 ConnectionParams connection_params) {
448 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 447 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
449 448
450 { 449 {
451 base::AutoLock lock(parent_lock_); 450 base::AutoLock lock(parent_lock_);
452 DCHECK(parent_name_ == ports::kInvalidNodeName); 451 DCHECK(parent_name_ == ports::kInvalidNodeName);
453 452
454 // At this point we don't know the parent's name, so we can't yet insert it 453 // At this point we don't know the parent's name, so we can't yet insert it
455 // into our |peers_| map. That will happen as soon as we receive an 454 // into our |peers_| map. That will happen as soon as we receive an
456 // AcceptChild message from them. 455 // AcceptChild message from them.
457 bootstrap_parent_channel_ = 456 bootstrap_parent_channel_ =
458 NodeChannel::Create(this, std::move(platform_handle), io_task_runner_, 457 NodeChannel::Create(this, std::move(connection_params), io_task_runner_,
459 ProcessErrorCallback()); 458 ProcessErrorCallback());
460 // Prevent the parent pipe handle from being closed on shutdown. Pipe 459 // Prevent the parent pipe handle from being closed on shutdown. Pipe
461 // closure is used by the parent to detect the child process has exited. 460 // closure is used by the parent to detect the child process has exited.
462 // Relying on message pipes to be closed is not enough because the parent 461 // Relying on message pipes to be closed is not enough because the parent
463 // may see the message pipe closure before the child is dead, causing the 462 // may see the message pipe closure before the child is dead, causing the
464 // child process to be unexpectedly SIGKILL'd. 463 // child process to be unexpectedly SIGKILL'd.
465 bootstrap_parent_channel_->LeakHandleOnShutdown(); 464 bootstrap_parent_channel_->LeakHandleOnShutdown();
466 } 465 }
467 bootstrap_parent_channel_->Start(); 466 bootstrap_parent_channel_->Start();
468 } 467 }
469 468
470 void NodeController::ConnectToPeerOnIOThread(ScopedPlatformHandle handle, 469 void NodeController::ConnectToPeerOnIOThread(ConnectionParams connection_params,
471 ports::NodeName token, 470 ports::NodeName token,
472 ports::PortRef port, 471 ports::PortRef port,
473 const std::string& peer_token) { 472 const std::string& peer_token) {
474 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 473 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
475 474
476 scoped_refptr<NodeChannel> channel = 475 scoped_refptr<NodeChannel> channel = NodeChannel::Create(
477 NodeChannel::Create(this, std::move(handle), io_task_runner_, {}); 476 this, std::move(connection_params), io_task_runner_, {});
478 peer_connections_.insert( 477 peer_connections_.insert(
479 {token, PeerConnection{channel, port, peer_token}}); 478 {token, PeerConnection{channel, port, peer_token}});
480 peers_by_token_.insert({peer_token, token}); 479 peers_by_token_.insert({peer_token, token});
481 480
482 channel->SetRemoteNodeName(token); 481 channel->SetRemoteNodeName(token);
483 channel->Start(); 482 channel->Start();
484 483
485 channel->AcceptPeer(name_, token, port.name()); 484 channel->AcceptPeer(name_, token, port.name());
486 } 485 }
487 486
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 return; 986 return;
988 } 987 }
989 988
990 if (GetPeerChannel(client_name)) { 989 if (GetPeerChannel(client_name)) {
991 DLOG(ERROR) << "Ignoring AddBrokerClient for known client."; 990 DLOG(ERROR) << "Ignoring AddBrokerClient for known client.";
992 DropPeer(from_node, nullptr); 991 DropPeer(from_node, nullptr);
993 return; 992 return;
994 } 993 }
995 994
996 PlatformChannelPair broker_channel; 995 PlatformChannelPair broker_channel;
997 scoped_refptr<NodeChannel> client = NodeChannel::Create( 996 ConnectionParams connection_params(broker_channel.PassServerHandle());
998 this, broker_channel.PassServerHandle(), io_task_runner_, 997 scoped_refptr<NodeChannel> client =
999 ProcessErrorCallback()); 998 NodeChannel::Create(this, std::move(connection_params), io_task_runner_,
999 ProcessErrorCallback());
1000 1000
1001 #if defined(OS_WIN) 1001 #if defined(OS_WIN)
1002 // The broker must have a working handle to the client process in order to 1002 // The broker must have a working handle to the client process in order to
1003 // properly copy other handles to and from the client. 1003 // properly copy other handles to and from the client.
1004 if (!scoped_process_handle.is_valid()) { 1004 if (!scoped_process_handle.is_valid()) {
1005 DLOG(ERROR) << "Broker rejecting client with invalid process handle."; 1005 DLOG(ERROR) << "Broker rejecting client with invalid process handle.";
1006 return; 1006 return;
1007 } 1007 }
1008 client->SetRemoteProcessHandle(scoped_process_handle.release().handle); 1008 client->SetRemoteProcessHandle(scoped_process_handle.release().handle);
1009 #else 1009 #else
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 DCHECK(broker_name != ports::kInvalidNodeName); 1065 DCHECK(broker_name != ports::kInvalidNodeName);
1066 1066
1067 // It's now possible to add both the broker and the parent as peers. 1067 // It's now possible to add both the broker and the parent as peers.
1068 // Note that the broker and parent may be the same node. 1068 // Note that the broker and parent may be the same node.
1069 scoped_refptr<NodeChannel> broker; 1069 scoped_refptr<NodeChannel> broker;
1070 if (broker_name == parent_name) { 1070 if (broker_name == parent_name) {
1071 DCHECK(!broker_channel.is_valid()); 1071 DCHECK(!broker_channel.is_valid());
1072 broker = parent; 1072 broker = parent;
1073 } else { 1073 } else {
1074 DCHECK(broker_channel.is_valid()); 1074 DCHECK(broker_channel.is_valid());
1075 broker = NodeChannel::Create(this, std::move(broker_channel), 1075 broker =
1076 io_task_runner_, ProcessErrorCallback()); 1076 NodeChannel::Create(this, ConnectionParams(std::move(broker_channel)),
1077 io_task_runner_, ProcessErrorCallback());
1077 AddPeer(broker_name, broker, true /* start_channel */); 1078 AddPeer(broker_name, broker, true /* start_channel */);
1078 } 1079 }
1079 1080
1080 AddPeer(parent_name, parent, false /* start_channel */); 1081 AddPeer(parent_name, parent, false /* start_channel */);
1081 1082
1082 { 1083 {
1083 // Complete any port merge requests we have waiting for the parent. 1084 // Complete any port merge requests we have waiting for the parent.
1084 base::AutoLock lock(pending_port_merges_lock_); 1085 base::AutoLock lock(pending_port_merges_lock_);
1085 for (const auto& request : pending_port_merges_) 1086 for (const auto& request : pending_port_merges_)
1086 parent->RequestPortMerge(request.second.name(), request.first); 1087 parent->RequestPortMerge(request.second.name(), request.first);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 if (!channel_handle.is_valid()) { 1195 if (!channel_handle.is_valid()) {
1195 node_->LostConnectionToNode(name); 1196 node_->LostConnectionToNode(name);
1196 1197
1197 DVLOG(1) << "Could not be introduced to peer " << name; 1198 DVLOG(1) << "Could not be introduced to peer " << name;
1198 base::AutoLock lock(peers_lock_); 1199 base::AutoLock lock(peers_lock_);
1199 pending_peer_messages_.erase(name); 1200 pending_peer_messages_.erase(name);
1200 return; 1201 return;
1201 } 1202 }
1202 1203
1203 scoped_refptr<NodeChannel> channel = 1204 scoped_refptr<NodeChannel> channel =
1204 NodeChannel::Create(this, std::move(channel_handle), io_task_runner_, 1205 NodeChannel::Create(this, ConnectionParams(std::move(channel_handle)),
1205 ProcessErrorCallback()); 1206 io_task_runner_, ProcessErrorCallback());
1206 1207
1207 DVLOG(1) << "Adding new peer " << name << " via parent introduction."; 1208 DVLOG(1) << "Adding new peer " << name << " via parent introduction.";
1208 AddPeer(name, channel, true /* start_channel */); 1209 AddPeer(name, channel, true /* start_channel */);
1209 } 1210 }
1210 1211
1211 void NodeController::OnBroadcast(const ports::NodeName& from_node, 1212 void NodeController::OnBroadcast(const ports::NodeName& from_node,
1212 Channel::MessagePtr message) { 1213 Channel::MessagePtr message) {
1213 DCHECK(!message->has_handles()); 1214 DCHECK(!message->has_handles());
1214 1215
1215 void* data; 1216 void* data;
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 NodeController::PeerConnection::~PeerConnection() = default; 1450 NodeController::PeerConnection::~PeerConnection() = default;
1450 1451
1451 NodeController::PeerConnection& NodeController::PeerConnection:: 1452 NodeController::PeerConnection& NodeController::PeerConnection::
1452 operator=(const PeerConnection& other) = default; 1453 operator=(const PeerConnection& other) = default;
1453 1454
1454 NodeController::PeerConnection& NodeController::PeerConnection:: 1455 NodeController::PeerConnection& NodeController::PeerConnection::
1455 operator=(PeerConnection&& other) = default; 1456 operator=(PeerConnection&& other) = default;
1456 1457
1457 } // namespace edk 1458 } // namespace edk
1458 } // namespace mojo 1459 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/node_controller.h ('k') | mojo/edk/test/multiprocess_test_helper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698