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 "mojo/edk/system/channel.h" | 5 #include "mojo/edk/system/channel.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 : platform_support_(platform_support), | 32 : platform_support_(platform_support), |
33 is_running_(false), | 33 is_running_(false), |
34 is_shutting_down_(false), | 34 is_shutting_down_(false), |
35 channel_manager_(nullptr) { | 35 channel_manager_(nullptr) { |
36 } | 36 } |
37 | 37 |
38 void Channel::Init(scoped_ptr<RawChannel> raw_channel) { | 38 void Channel::Init(scoped_ptr<RawChannel> raw_channel) { |
39 DCHECK(creation_thread_checker_.CalledOnValidThread()); | 39 DCHECK(creation_thread_checker_.CalledOnValidThread()); |
40 DCHECK(raw_channel); | 40 DCHECK(raw_channel); |
41 | 41 |
42 // No need to take |lock_|, since this must be called before this object | 42 // No need to take |mutex_|, since this must be called before this object |
43 // becomes thread-safe. | 43 // becomes thread-safe. |
44 DCHECK(!is_running_); | 44 DCHECK(!is_running_); |
45 raw_channel_ = raw_channel.Pass(); | 45 raw_channel_ = raw_channel.Pass(); |
46 raw_channel_->Init(this); | 46 raw_channel_->Init(this); |
47 is_running_ = true; | 47 is_running_ = true; |
48 } | 48 } |
49 | 49 |
50 void Channel::SetChannelManager(ChannelManager* channel_manager) { | 50 void Channel::SetChannelManager(ChannelManager* channel_manager) { |
51 DCHECK(channel_manager); | 51 DCHECK(channel_manager); |
52 | 52 |
53 base::AutoLock locker(lock_); | 53 MutexLocker locker(&mutex_); |
54 DCHECK(!is_shutting_down_); | 54 DCHECK(!is_shutting_down_); |
55 DCHECK(!channel_manager_); | 55 DCHECK(!channel_manager_); |
56 channel_manager_ = channel_manager; | 56 channel_manager_ = channel_manager; |
57 } | 57 } |
58 | 58 |
59 void Channel::Shutdown() { | 59 void Channel::Shutdown() { |
60 DCHECK(creation_thread_checker_.CalledOnValidThread()); | 60 DCHECK(creation_thread_checker_.CalledOnValidThread()); |
61 | 61 |
62 IdToEndpointMap to_destroy; | 62 IdToEndpointMap to_destroy; |
63 { | 63 { |
64 base::AutoLock locker(lock_); | 64 MutexLocker locker(&mutex_); |
65 if (!is_running_) | 65 if (!is_running_) |
66 return; | 66 return; |
67 | 67 |
68 // Note: Don't reset |raw_channel_|, in case we're being called from within | 68 // Note: Don't reset |raw_channel_|, in case we're being called from within |
69 // |OnReadMessage()| or |OnError()|. | 69 // |OnReadMessage()| or |OnError()|. |
70 raw_channel_->Shutdown(); | 70 raw_channel_->Shutdown(); |
71 is_running_ = false; | 71 is_running_ = false; |
72 | 72 |
73 // We need to deal with it outside the lock. | 73 // We need to deal with it outside the lock. |
74 std::swap(to_destroy, local_id_to_endpoint_map_); | 74 std::swap(to_destroy, local_id_to_endpoint_map_); |
75 } | 75 } |
76 | 76 |
77 size_t num_live = 0; | 77 size_t num_live = 0; |
78 size_t num_zombies = 0; | 78 size_t num_zombies = 0; |
79 for (IdToEndpointMap::iterator it = to_destroy.begin(); | 79 for (IdToEndpointMap::iterator it = to_destroy.begin(); |
80 it != to_destroy.end(); ++it) { | 80 it != to_destroy.end(); ++it) { |
81 if (it->second) { | 81 if (it->second) { |
82 num_live++; | 82 num_live++; |
83 it->second->DetachFromChannel(); | 83 it->second->DetachFromChannel(); |
84 } else { | 84 } else { |
85 num_zombies++; | 85 num_zombies++; |
86 } | 86 } |
87 } | 87 } |
88 DVLOG_IF(2, num_live || num_zombies) << "Shut down Channel with " << num_live | 88 DVLOG_IF(2, num_live || num_zombies) << "Shut down Channel with " << num_live |
89 << " live endpoints and " << num_zombies | 89 << " live endpoints and " << num_zombies |
90 << " zombies"; | 90 << " zombies"; |
91 } | 91 } |
92 | 92 |
93 void Channel::WillShutdownSoon() { | 93 void Channel::WillShutdownSoon() { |
94 base::AutoLock locker(lock_); | 94 MutexLocker locker(&mutex_); |
95 is_shutting_down_ = true; | 95 is_shutting_down_ = true; |
96 channel_manager_ = nullptr; | 96 channel_manager_ = nullptr; |
97 } | 97 } |
98 | 98 |
99 void Channel::SetBootstrapEndpoint(scoped_refptr<ChannelEndpoint> endpoint) { | 99 void Channel::SetBootstrapEndpoint(scoped_refptr<ChannelEndpoint> endpoint) { |
100 // Used for both local and remote IDs. | 100 // Used for both local and remote IDs. |
101 ChannelEndpointId bootstrap_id = ChannelEndpointId::GetBootstrap(); | 101 ChannelEndpointId bootstrap_id = ChannelEndpointId::GetBootstrap(); |
102 SetBootstrapEndpointWithIds(endpoint.Pass(), bootstrap_id, bootstrap_id); | 102 SetBootstrapEndpointWithIds(endpoint.Pass(), bootstrap_id, bootstrap_id); |
103 } | 103 } |
104 | 104 |
105 void Channel::SetBootstrapEndpointWithIds( | 105 void Channel::SetBootstrapEndpointWithIds( |
106 scoped_refptr<ChannelEndpoint> endpoint, | 106 scoped_refptr<ChannelEndpoint> endpoint, |
107 ChannelEndpointId local_id, | 107 ChannelEndpointId local_id, |
108 ChannelEndpointId remote_id) { | 108 ChannelEndpointId remote_id) { |
109 DCHECK(endpoint); | 109 DCHECK(endpoint); |
110 | 110 |
111 { | 111 { |
112 base::AutoLock locker(lock_); | 112 MutexLocker locker(&mutex_); |
113 | 113 |
114 DLOG_IF(WARNING, is_shutting_down_) | 114 DLOG_IF(WARNING, is_shutting_down_) |
115 << "SetBootstrapEndpoint() while shutting down"; | 115 << "SetBootstrapEndpoint() while shutting down"; |
116 | 116 |
117 // There must not be an endpoint with that ID already. | 117 // There must not be an endpoint with that ID already. |
118 DCHECK(local_id_to_endpoint_map_.find(local_id) == | 118 DCHECK(local_id_to_endpoint_map_.find(local_id) == |
119 local_id_to_endpoint_map_.end()); | 119 local_id_to_endpoint_map_.end()); |
120 | 120 |
121 local_id_to_endpoint_map_[local_id] = endpoint; | 121 local_id_to_endpoint_map_[local_id] = endpoint; |
122 } | 122 } |
123 | 123 |
124 endpoint->AttachAndRun(this, local_id, remote_id); | 124 endpoint->AttachAndRun(this, local_id, remote_id); |
125 } | 125 } |
126 | 126 |
127 bool Channel::WriteMessage(scoped_ptr<MessageInTransit> message) { | 127 bool Channel::WriteMessage(scoped_ptr<MessageInTransit> message) { |
128 base::AutoLock locker(lock_); | 128 MutexLocker locker(&mutex_); |
129 if (!is_running_) { | 129 if (!is_running_) { |
130 // TODO(vtl): I think this is probably not an error condition, but I should | 130 // TODO(vtl): I think this is probably not an error condition, but I should |
131 // think about it (and the shutdown sequence) more carefully. | 131 // think about it (and the shutdown sequence) more carefully. |
132 LOG(WARNING) << "WriteMessage() after shutdown"; | 132 LOG(WARNING) << "WriteMessage() after shutdown"; |
133 return false; | 133 return false; |
134 } | 134 } |
135 | 135 |
136 DLOG_IF(WARNING, is_shutting_down_) << "WriteMessage() while shutting down"; | 136 DLOG_IF(WARNING, is_shutting_down_) << "WriteMessage() while shutting down"; |
137 return raw_channel_->WriteMessage(message.Pass()); | 137 return raw_channel_->WriteMessage(message.Pass()); |
138 } | 138 } |
139 | 139 |
140 bool Channel::IsWriteBufferEmpty() { | 140 bool Channel::IsWriteBufferEmpty() { |
141 base::AutoLock locker(lock_); | 141 MutexLocker locker(&mutex_); |
142 if (!is_running_) | 142 if (!is_running_) |
143 return true; | 143 return true; |
144 return raw_channel_->IsWriteBufferEmpty(); | 144 return raw_channel_->IsWriteBufferEmpty(); |
145 } | 145 } |
146 | 146 |
147 void Channel::DetachEndpoint(ChannelEndpoint* endpoint, | 147 void Channel::DetachEndpoint(ChannelEndpoint* endpoint, |
148 ChannelEndpointId local_id, | 148 ChannelEndpointId local_id, |
149 ChannelEndpointId remote_id) { | 149 ChannelEndpointId remote_id) { |
150 DCHECK(endpoint); | 150 DCHECK(endpoint); |
151 DCHECK(local_id.is_valid()); | 151 DCHECK(local_id.is_valid()); |
152 | 152 |
153 if (!remote_id.is_valid()) | 153 if (!remote_id.is_valid()) |
154 return; // Nothing to do. | 154 return; // Nothing to do. |
155 | 155 |
156 { | 156 { |
157 base::AutoLock locker_(lock_); | 157 MutexLocker locker_(&mutex_); |
158 if (!is_running_) | 158 if (!is_running_) |
159 return; | 159 return; |
160 | 160 |
161 IdToEndpointMap::iterator it = local_id_to_endpoint_map_.find(local_id); | 161 IdToEndpointMap::iterator it = local_id_to_endpoint_map_.find(local_id); |
162 // We detach immediately if we receive a remove message, so it's possible | 162 // We detach immediately if we receive a remove message, so it's possible |
163 // that the local ID is no longer in |local_id_to_endpoint_map_|, or even | 163 // that the local ID is no longer in |local_id_to_endpoint_map_|, or even |
164 // that it's since been reused for another endpoint. In both cases, there's | 164 // that it's since been reused for another endpoint. In both cases, there's |
165 // nothing more to do. | 165 // nothing more to do. |
166 if (it == local_id_to_endpoint_map_.end() || it->second.get() != endpoint) | 166 if (it == local_id_to_endpoint_map_.end() || it->second.get() != endpoint) |
167 return; | 167 return; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 | 240 |
241 scoped_refptr<IncomingEndpoint> Channel::DeserializeEndpoint( | 241 scoped_refptr<IncomingEndpoint> Channel::DeserializeEndpoint( |
242 const void* source) { | 242 const void* source) { |
243 const SerializedEndpoint* s = static_cast<const SerializedEndpoint*>(source); | 243 const SerializedEndpoint* s = static_cast<const SerializedEndpoint*>(source); |
244 ChannelEndpointId local_id = s->receiver_endpoint_id; | 244 ChannelEndpointId local_id = s->receiver_endpoint_id; |
245 // No need to check the validity of |local_id| -- if it's not valid, it simply | 245 // No need to check the validity of |local_id| -- if it's not valid, it simply |
246 // won't be in |incoming_endpoints_|. | 246 // won't be in |incoming_endpoints_|. |
247 DVLOG_IF(2, !local_id.is_valid() || !local_id.is_remote()) | 247 DVLOG_IF(2, !local_id.is_valid() || !local_id.is_remote()) |
248 << "Attempt to get incoming endpoint for invalid ID " << local_id; | 248 << "Attempt to get incoming endpoint for invalid ID " << local_id; |
249 | 249 |
250 base::AutoLock locker(lock_); | 250 MutexLocker locker(&mutex_); |
251 | 251 |
252 auto it = incoming_endpoints_.find(local_id); | 252 auto it = incoming_endpoints_.find(local_id); |
253 if (it == incoming_endpoints_.end()) { | 253 if (it == incoming_endpoints_.end()) { |
254 LOG(ERROR) << "Failed to deserialize endpoint (ID = " << local_id << ")"; | 254 LOG(ERROR) << "Failed to deserialize endpoint (ID = " << local_id << ")"; |
255 return nullptr; | 255 return nullptr; |
256 } | 256 } |
257 | 257 |
258 DVLOG(2) << "Deserializing endpoint (new local ID = " << local_id << ")"; | 258 DVLOG(2) << "Deserializing endpoint (new local ID = " << local_id << ")"; |
259 | 259 |
260 scoped_refptr<IncomingEndpoint> rv; | 260 scoped_refptr<IncomingEndpoint> rv; |
261 rv.swap(it->second); | 261 rv.swap(it->second); |
262 incoming_endpoints_.erase(it); | 262 incoming_endpoints_.erase(it); |
263 return rv; | 263 return rv; |
264 } | 264 } |
265 | 265 |
266 size_t Channel::GetSerializedPlatformHandleSize() const { | 266 size_t Channel::GetSerializedPlatformHandleSize() const { |
| 267 // TODO(vtl): Having to lock |mutex_| here is a bit unfortunate. Maybe we |
| 268 // should get the size in |Init()| and cache it? |
| 269 MutexLocker locker(&mutex_); |
267 return raw_channel_->GetSerializedPlatformHandleSize(); | 270 return raw_channel_->GetSerializedPlatformHandleSize(); |
268 } | 271 } |
269 | 272 |
270 Channel::~Channel() { | 273 Channel::~Channel() { |
271 // The channel should have been shut down first. | 274 // The channel should have been shut down first. |
272 DCHECK(!is_running_); | 275 DCHECK(!is_running_); |
273 } | 276 } |
274 | 277 |
275 void Channel::OnReadMessage( | 278 void Channel::OnReadMessage( |
276 const MessageInTransit::View& message_view, | 279 const MessageInTransit::View& message_view, |
(...skipping 19 matching lines...) Expand all Loading... |
296 | 299 |
297 void Channel::OnError(Error error) { | 300 void Channel::OnError(Error error) { |
298 DCHECK(creation_thread_checker_.CalledOnValidThread()); | 301 DCHECK(creation_thread_checker_.CalledOnValidThread()); |
299 | 302 |
300 switch (error) { | 303 switch (error) { |
301 case ERROR_READ_SHUTDOWN: | 304 case ERROR_READ_SHUTDOWN: |
302 // The other side was cleanly closed, so this isn't actually an error. | 305 // The other side was cleanly closed, so this isn't actually an error. |
303 DVLOG(1) << "RawChannel read error (shutdown)"; | 306 DVLOG(1) << "RawChannel read error (shutdown)"; |
304 break; | 307 break; |
305 case ERROR_READ_BROKEN: { | 308 case ERROR_READ_BROKEN: { |
306 base::AutoLock locker(lock_); | 309 MutexLocker locker(&mutex_); |
307 LOG_IF(ERROR, !is_shutting_down_) | 310 LOG_IF(ERROR, !is_shutting_down_) |
308 << "RawChannel read error (connection broken)"; | 311 << "RawChannel read error (connection broken)"; |
309 break; | 312 break; |
310 } | 313 } |
311 case ERROR_READ_BAD_MESSAGE: | 314 case ERROR_READ_BAD_MESSAGE: |
312 // Receiving a bad message means either a bug, data corruption, or | 315 // Receiving a bad message means either a bug, data corruption, or |
313 // malicious attack (probably due to some other bug). | 316 // malicious attack (probably due to some other bug). |
314 LOG(ERROR) << "RawChannel read error (received bad message)"; | 317 LOG(ERROR) << "RawChannel read error (received bad message)"; |
315 break; | 318 break; |
316 case ERROR_READ_UNKNOWN: | 319 case ERROR_READ_UNKNOWN: |
(...skipping 16 matching lines...) Expand all Loading... |
333 message_view.type() == MessageInTransit::Type::ENDPOINT); | 336 message_view.type() == MessageInTransit::Type::ENDPOINT); |
334 | 337 |
335 ChannelEndpointId local_id = message_view.destination_id(); | 338 ChannelEndpointId local_id = message_view.destination_id(); |
336 if (!local_id.is_valid()) { | 339 if (!local_id.is_valid()) { |
337 HandleRemoteError("Received message with no destination ID"); | 340 HandleRemoteError("Received message with no destination ID"); |
338 return; | 341 return; |
339 } | 342 } |
340 | 343 |
341 scoped_refptr<ChannelEndpoint> endpoint; | 344 scoped_refptr<ChannelEndpoint> endpoint; |
342 { | 345 { |
343 base::AutoLock locker(lock_); | 346 MutexLocker locker(&mutex_); |
344 | 347 |
345 // Since we own |raw_channel_|, and this method and |Shutdown()| should only | 348 // Since we own |raw_channel_|, and this method and |Shutdown()| should only |
346 // be called from the creation thread, |raw_channel_| should never be null | 349 // be called from the creation thread, |raw_channel_| should never be null |
347 // here. | 350 // here. |
348 DCHECK(is_running_); | 351 DCHECK(is_running_); |
349 | 352 |
350 IdToEndpointMap::const_iterator it = | 353 IdToEndpointMap::const_iterator it = |
351 local_id_to_endpoint_map_.find(local_id); | 354 local_id_to_endpoint_map_.find(local_id); |
352 if (it != local_id_to_endpoint_map_.end()) { | 355 if (it != local_id_to_endpoint_map_.end()) { |
353 // Ignore messages for zombie endpoints (not an error). | 356 // Ignore messages for zombie endpoints (not an error). |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 return false; | 455 return false; |
453 } | 456 } |
454 | 457 |
455 // Create/initialize an |IncomingEndpoint| and thus an endpoint (outside the | 458 // Create/initialize an |IncomingEndpoint| and thus an endpoint (outside the |
456 // lock). | 459 // lock). |
457 scoped_refptr<IncomingEndpoint> incoming_endpoint(new IncomingEndpoint()); | 460 scoped_refptr<IncomingEndpoint> incoming_endpoint(new IncomingEndpoint()); |
458 scoped_refptr<ChannelEndpoint> endpoint = incoming_endpoint->Init(); | 461 scoped_refptr<ChannelEndpoint> endpoint = incoming_endpoint->Init(); |
459 | 462 |
460 bool success = true; | 463 bool success = true; |
461 { | 464 { |
462 base::AutoLock locker(lock_); | 465 MutexLocker locker(&mutex_); |
463 | 466 |
464 if (local_id_to_endpoint_map_.find(local_id) == | 467 if (local_id_to_endpoint_map_.find(local_id) == |
465 local_id_to_endpoint_map_.end()) { | 468 local_id_to_endpoint_map_.end()) { |
466 DCHECK(incoming_endpoints_.find(local_id) == incoming_endpoints_.end()); | 469 DCHECK(incoming_endpoints_.find(local_id) == incoming_endpoints_.end()); |
467 | 470 |
468 // TODO(vtl): Use emplace when we move to C++11 unordered_maps. (It'll | 471 // TODO(vtl): Use emplace when we move to C++11 unordered_maps. (It'll |
469 // avoid some refcount churn.) | 472 // avoid some refcount churn.) |
470 local_id_to_endpoint_map_[local_id] = endpoint; | 473 local_id_to_endpoint_map_[local_id] = endpoint; |
471 incoming_endpoints_[local_id] = incoming_endpoint; | 474 incoming_endpoints_[local_id] = incoming_endpoint; |
472 } else { | 475 } else { |
(...skipping 10 matching lines...) Expand all Loading... |
483 endpoint->AttachAndRun(this, local_id, remote_id); | 486 endpoint->AttachAndRun(this, local_id, remote_id); |
484 return true; | 487 return true; |
485 } | 488 } |
486 | 489 |
487 bool Channel::OnRemoveEndpoint(ChannelEndpointId local_id, | 490 bool Channel::OnRemoveEndpoint(ChannelEndpointId local_id, |
488 ChannelEndpointId remote_id) { | 491 ChannelEndpointId remote_id) { |
489 DCHECK(creation_thread_checker_.CalledOnValidThread()); | 492 DCHECK(creation_thread_checker_.CalledOnValidThread()); |
490 | 493 |
491 scoped_refptr<ChannelEndpoint> endpoint; | 494 scoped_refptr<ChannelEndpoint> endpoint; |
492 { | 495 { |
493 base::AutoLock locker(lock_); | 496 MutexLocker locker(&mutex_); |
494 | 497 |
495 IdToEndpointMap::iterator it = local_id_to_endpoint_map_.find(local_id); | 498 IdToEndpointMap::iterator it = local_id_to_endpoint_map_.find(local_id); |
496 if (it == local_id_to_endpoint_map_.end()) { | 499 if (it == local_id_to_endpoint_map_.end()) { |
497 DVLOG(2) << "Remove endpoint error: not found"; | 500 DVLOG(2) << "Remove endpoint error: not found"; |
498 return false; | 501 return false; |
499 } | 502 } |
500 | 503 |
501 if (!it->second) { | 504 if (!it->second) { |
502 // Remove messages "crossed"; we have to wait for the ack. | 505 // Remove messages "crossed"; we have to wait for the ack. |
503 return true; | 506 return true; |
(...skipping 15 matching lines...) Expand all Loading... |
519 static_cast<unsigned>(local_id.value()), | 522 static_cast<unsigned>(local_id.value()), |
520 static_cast<unsigned>(remote_id.value())).c_str()); | 523 static_cast<unsigned>(remote_id.value())).c_str()); |
521 } | 524 } |
522 | 525 |
523 return true; | 526 return true; |
524 } | 527 } |
525 | 528 |
526 bool Channel::OnRemoveEndpointAck(ChannelEndpointId local_id) { | 529 bool Channel::OnRemoveEndpointAck(ChannelEndpointId local_id) { |
527 DCHECK(creation_thread_checker_.CalledOnValidThread()); | 530 DCHECK(creation_thread_checker_.CalledOnValidThread()); |
528 | 531 |
529 base::AutoLock locker(lock_); | 532 MutexLocker locker(&mutex_); |
530 | 533 |
531 IdToEndpointMap::iterator it = local_id_to_endpoint_map_.find(local_id); | 534 IdToEndpointMap::iterator it = local_id_to_endpoint_map_.find(local_id); |
532 if (it == local_id_to_endpoint_map_.end()) { | 535 if (it == local_id_to_endpoint_map_.end()) { |
533 DVLOG(2) << "Remove endpoint ack error: not found"; | 536 DVLOG(2) << "Remove endpoint ack error: not found"; |
534 return false; | 537 return false; |
535 } | 538 } |
536 | 539 |
537 if (it->second) { | 540 if (it->second) { |
538 DVLOG(2) << "Remove endpoint ack error: wrong state"; | 541 DVLOG(2) << "Remove endpoint ack error: wrong state"; |
539 return false; | 542 return false; |
(...skipping 22 matching lines...) Expand all Loading... |
562 // keeps the endpoint alive even after the lock is released. Otherwise, there's | 565 // keeps the endpoint alive even after the lock is released. Otherwise, there's |
563 // the temptation to simply pass the result of |new ChannelEndpoint(...)| | 566 // the temptation to simply pass the result of |new ChannelEndpoint(...)| |
564 // directly to this function, which wouldn't be sufficient for safety. | 567 // directly to this function, which wouldn't be sufficient for safety. |
565 ChannelEndpointId Channel::AttachAndRunEndpoint( | 568 ChannelEndpointId Channel::AttachAndRunEndpoint( |
566 scoped_refptr<ChannelEndpoint> endpoint) { | 569 scoped_refptr<ChannelEndpoint> endpoint) { |
567 DCHECK(endpoint); | 570 DCHECK(endpoint); |
568 | 571 |
569 ChannelEndpointId local_id; | 572 ChannelEndpointId local_id; |
570 ChannelEndpointId remote_id; | 573 ChannelEndpointId remote_id; |
571 { | 574 { |
572 base::AutoLock locker(lock_); | 575 MutexLocker locker(&mutex_); |
573 | 576 |
574 DLOG_IF(WARNING, is_shutting_down_) | 577 DLOG_IF(WARNING, is_shutting_down_) |
575 << "AttachAndRunEndpoint() while shutting down"; | 578 << "AttachAndRunEndpoint() while shutting down"; |
576 | 579 |
577 do { | 580 do { |
578 local_id = local_id_generator_.GetNext(); | 581 local_id = local_id_generator_.GetNext(); |
579 } while (local_id_to_endpoint_map_.find(local_id) != | 582 } while (local_id_to_endpoint_map_.find(local_id) != |
580 local_id_to_endpoint_map_.end()); | 583 local_id_to_endpoint_map_.end()); |
581 | 584 |
582 // TODO(vtl): We also need to check for collisions of remote IDs here. | 585 // TODO(vtl): We also need to check for collisions of remote IDs here. |
(...skipping 24 matching lines...) Expand all Loading... |
607 << ", local ID " << local_id << ", remote ID " << remote_id; | 610 << ", local ID " << local_id << ", remote ID " << remote_id; |
608 scoped_ptr<MessageInTransit> message(new MessageInTransit( | 611 scoped_ptr<MessageInTransit> message(new MessageInTransit( |
609 MessageInTransit::Type::CHANNEL, subtype, 0, nullptr)); | 612 MessageInTransit::Type::CHANNEL, subtype, 0, nullptr)); |
610 message->set_source_id(local_id); | 613 message->set_source_id(local_id); |
611 message->set_destination_id(remote_id); | 614 message->set_destination_id(remote_id); |
612 return WriteMessage(message.Pass()); | 615 return WriteMessage(message.Pass()); |
613 } | 616 } |
614 | 617 |
615 } // namespace system | 618 } // namespace system |
616 } // namespace mojo | 619 } // namespace mojo |
OLD | NEW |