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

Side by Side Diff: webrtc/p2p/base/transportcontroller.cc

Issue 1380563002: Thinning out the Transport class. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Moving channel ref-counting from Transport to TransportController. Created 5 years, 2 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
OLDNEW
1 /* 1 /*
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/p2p/base/transportcontroller.h" 11 #include "webrtc/p2p/base/transportcontroller.h"
12 12
13 #include <algorithm>
14
13 #include "webrtc/base/bind.h" 15 #include "webrtc/base/bind.h"
14 #include "webrtc/base/checks.h" 16 #include "webrtc/base/checks.h"
15 #include "webrtc/base/thread.h" 17 #include "webrtc/base/thread.h"
16 #include "webrtc/p2p/base/dtlstransport.h" 18 #include "webrtc/p2p/base/dtlstransport.h"
17 #include "webrtc/p2p/base/p2ptransport.h" 19 #include "webrtc/p2p/base/p2ptransport.h"
20 #include "webrtc/p2p/base/port.h"
18 21
19 namespace cricket { 22 namespace cricket {
20 23
21 enum { 24 enum {
22 MSG_ICECONNECTIONSTATE, 25 MSG_ICECONNECTIONSTATE,
23 MSG_RECEIVING, 26 MSG_RECEIVING,
24 MSG_ICEGATHERINGSTATE, 27 MSG_ICEGATHERINGSTATE,
25 MSG_CANDIDATESGATHERED, 28 MSG_CANDIDATESGATHERED,
26 }; 29 };
27 30
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 TransportStats* stats) { 136 TransportStats* stats) {
134 return worker_thread_->Invoke<bool>( 137 return worker_thread_->Invoke<bool>(
135 rtc::Bind(&TransportController::GetStats_w, this, transport_name, stats)); 138 rtc::Bind(&TransportController::GetStats_w, this, transport_name, stats));
136 } 139 }
137 140
138 TransportChannel* TransportController::CreateTransportChannel_w( 141 TransportChannel* TransportController::CreateTransportChannel_w(
139 const std::string& transport_name, 142 const std::string& transport_name,
140 int component) { 143 int component) {
141 RTC_DCHECK(worker_thread_->IsCurrent()); 144 RTC_DCHECK(worker_thread_->IsCurrent());
142 145
143 Transport* transport = GetOrCreateTransport_w(transport_name); 146 auto it = FindChannel_w(transport_name, component);
144 return transport->CreateChannel(component); 147 if (it == channels_.end()) {
148 // Need to create a new channel.
149 Transport* transport = GetOrCreateTransport_w(transport_name);
150 TransportChannelImpl* channel = transport->CreateChannel(component);
151 channel->SignalWritableState.connect(
152 this, &TransportController::OnChannelWritableState_w);
153 channel->SignalReceivingState.connect(
154 this, &TransportController::OnChannelReceivingState_w);
155 channel->SignalGatheringState.connect(
156 this, &TransportController::OnChannelGatheringState_w);
157 channel->SignalCandidateGathered.connect(
158 this, &TransportController::OnChannelCandidateGathered_w);
159 channel->SignalRoleConflict.connect(
160 this, &TransportController::OnChannelRoleConflict_w);
161 channel->SignalConnectionRemoved.connect(
162 this, &TransportController::OnChannelConnectionRemoved_w);
163 channels_.insert(channels_.end(), RefCountedChannel(channel))->AddRef();
164 // Adding a channel could cause aggregate state to change.
165 UpdateAggregateStates_w();
166 return channel;
167 }
168 // Channel already exists; increment reference count and return.
169 it->AddRef();
170 return it->get();
pthatcher1 2015/09/29 23:50:58 Might be easier to read the other way around: if
Taylor Brandstetter 2015/09/30 01:01:20 Done.
145 } 171 }
146 172
147 void TransportController::DestroyTransportChannel_w( 173 void TransportController::DestroyTransportChannel_w(
148 const std::string& transport_name, 174 const std::string& transport_name,
149 int component) { 175 int component) {
150 RTC_DCHECK(worker_thread_->IsCurrent()); 176 RTC_DCHECK(worker_thread_->IsCurrent());
151 177
152 Transport* transport = GetTransport_w(transport_name); 178 auto it = FindChannel_w(transport_name, component);
153 if (!transport) { 179 if (it == channels_.end()) {
154 ASSERT(false); 180 LOG(LS_WARNING) << "Attempting to delete " << transport_name
181 << " TransportChannel " << component
182 << ", which doesn't exist.";
155 return; 183 return;
156 } 184 }
157 transport->DestroyChannel(component);
158 185
159 // Just as we create a Transport when its first channel is created, 186 it->DecRef();
160 // we delete it when its last channel is deleted. 187 if (it->ref() == 0) {
pthatcher1 2015/09/29 23:50:58 Same here: if (it->ref() > 0) { return; } chan
Taylor Brandstetter 2015/09/30 01:01:20 Done.
161 if (!transport->HasChannels()) { 188 channels_.erase(it);
162 DestroyTransport_w(transport_name); 189 Transport* transport = GetTransport_w(transport_name);
190 transport->DestroyChannel(component);
191 // Just as we create a Transport when its first channel is created,
192 // we delete it when its last channel is deleted.
193 if (!transport->HasChannels()) {
194 DestroyTransport_w(transport_name);
195 }
196 // Removing a channel could cause aggregate state to change.
197 UpdateAggregateStates_w();
163 } 198 }
164 } 199 }
165 200
166 const rtc::scoped_refptr<rtc::RTCCertificate>& 201 const rtc::scoped_refptr<rtc::RTCCertificate>&
167 TransportController::certificate_for_testing() { 202 TransportController::certificate_for_testing() {
168 return certificate_; 203 return certificate_;
169 } 204 }
170 205
171 Transport* TransportController::CreateTransport_w( 206 Transport* TransportController::CreateTransport_w(
172 const std::string& transport_name) { 207 const std::string& transport_name) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 CandidatesData* data = static_cast<CandidatesData*>(pmsg->pdata); 249 CandidatesData* data = static_cast<CandidatesData*>(pmsg->pdata);
215 SignalCandidatesGathered(data->transport_name, data->candidates); 250 SignalCandidatesGathered(data->transport_name, data->candidates);
216 delete data; 251 delete data;
217 break; 252 break;
218 } 253 }
219 default: 254 default:
220 ASSERT(false); 255 ASSERT(false);
221 } 256 }
222 } 257 }
223 258
259 std::vector<TransportController::RefCountedChannel>::iterator
260 TransportController::FindChannel_w(const std::string& transport_name,
261 int component) {
262 return std::find_if(
263 channels_.begin(), channels_.end(),
264 [transport_name, component](const RefCountedChannel& channel) {
265 return channel->transport_name() == transport_name &&
266 channel->component() == component;
267 });
268 }
269
224 Transport* TransportController::GetOrCreateTransport_w( 270 Transport* TransportController::GetOrCreateTransport_w(
225 const std::string& transport_name) { 271 const std::string& transport_name) {
226 RTC_DCHECK(worker_thread_->IsCurrent()); 272 RTC_DCHECK(worker_thread_->IsCurrent());
227 273
228 Transport* transport = GetTransport_w(transport_name); 274 Transport* transport = GetTransport_w(transport_name);
229 if (transport) { 275 if (transport) {
230 return transport; 276 return transport;
231 } 277 }
232 278
233 transport = CreateTransport_w(transport_name); 279 transport = CreateTransport_w(transport_name);
234 // The stuff below happens outside of CreateTransport_w so that unit tests 280 // The stuff below happens outside of CreateTransport_w so that unit tests
235 // can override CreateTransport_w to return a different type of transport. 281 // can override CreateTransport_w to return a different type of transport.
236 transport->SetSslMaxProtocolVersion(ssl_max_version_); 282 transport->SetSslMaxProtocolVersion(ssl_max_version_);
237 transport->SetIceConfig(ice_config_); 283 transport->SetIceConfig(ice_config_);
238 transport->SetIceRole(ice_role_); 284 transport->SetIceRole(ice_role_);
239 transport->SetIceTiebreaker(ice_tiebreaker_); 285 transport->SetIceTiebreaker(ice_tiebreaker_);
240 if (certificate_) { 286 if (certificate_) {
241 transport->SetLocalCertificate(certificate_); 287 transport->SetLocalCertificate(certificate_);
242 } 288 }
243 transport->SignalConnecting.connect(
244 this, &TransportController::OnTransportConnecting_w);
245 transport->SignalWritableState.connect(
246 this, &TransportController::OnTransportWritableState_w);
247 transport->SignalReceivingState.connect(
248 this, &TransportController::OnTransportReceivingState_w);
249 transport->SignalCompleted.connect(
250 this, &TransportController::OnTransportCompleted_w);
251 transport->SignalFailed.connect(this,
252 &TransportController::OnTransportFailed_w);
253 transport->SignalGatheringState.connect(
254 this, &TransportController::OnTransportGatheringState_w);
255 transport->SignalCandidatesGathered.connect(
256 this, &TransportController::OnTransportCandidatesGathered_w);
257 transport->SignalRoleConflict.connect(
258 this, &TransportController::OnTransportRoleConflict_w);
259 transports_[transport_name] = transport; 289 transports_[transport_name] = transport;
260 290
261 return transport; 291 return transport;
262 } 292 }
263 293
264 void TransportController::DestroyTransport_w( 294 void TransportController::DestroyTransport_w(
265 const std::string& transport_name) { 295 const std::string& transport_name) {
266 RTC_DCHECK(worker_thread_->IsCurrent()); 296 RTC_DCHECK(worker_thread_->IsCurrent());
267 297
268 auto iter = transports_.find(transport_name); 298 auto iter = transports_.find(transport_name);
269 if (iter != transports_.end()) { 299 if (iter != transports_.end()) {
270 delete iter->second; 300 delete iter->second;
271 transports_.erase(transport_name); 301 transports_.erase(transport_name);
272 } 302 }
273 // Destroying a transport may cause aggregate state to change.
274 UpdateAggregateStates_w();
275 } 303 }
276 304
277 void TransportController::DestroyAllTransports_w() { 305 void TransportController::DestroyAllTransports_w() {
278 RTC_DCHECK(worker_thread_->IsCurrent()); 306 RTC_DCHECK(worker_thread_->IsCurrent());
279 307
280 for (const auto& kv : transports_) { 308 for (const auto& kv : transports_) {
281 delete kv.second; 309 delete kv.second;
282 } 310 }
283 transports_.clear(); 311 transports_.clear();
284 } 312 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 TransportStats* stats) { 468 TransportStats* stats) {
441 RTC_DCHECK(worker_thread()->IsCurrent()); 469 RTC_DCHECK(worker_thread()->IsCurrent());
442 470
443 Transport* transport = GetTransport_w(transport_name); 471 Transport* transport = GetTransport_w(transport_name);
444 if (!transport) { 472 if (!transport) {
445 return false; 473 return false;
446 } 474 }
447 return transport->GetStats(stats); 475 return transport->GetStats(stats);
448 } 476 }
449 477
450 void TransportController::OnTransportConnecting_w(Transport* transport) { 478 void TransportController::OnChannelWritableState_w(TransportChannel* channel) {
479 RTC_DCHECK(worker_thread_->IsCurrent());
480 LOG(LS_INFO) << channel->transport_name() << " TransportChannel "
481 << channel->component() << " writability changed to "
482 << channel->writable() << ".";
483 UpdateAggregateStates_w();
484 }
485
486 void TransportController::OnChannelReceivingState_w(TransportChannel* channel) {
451 RTC_DCHECK(worker_thread_->IsCurrent()); 487 RTC_DCHECK(worker_thread_->IsCurrent());
452 UpdateAggregateStates_w(); 488 UpdateAggregateStates_w();
453 } 489 }
454 490
455 void TransportController::OnTransportWritableState_w(Transport* transport) { 491 void TransportController::OnChannelGatheringState_w(
492 TransportChannelImpl* channel) {
456 RTC_DCHECK(worker_thread_->IsCurrent()); 493 RTC_DCHECK(worker_thread_->IsCurrent());
457 UpdateAggregateStates_w(); 494 UpdateAggregateStates_w();
458 } 495 }
459 496
460 void TransportController::OnTransportReceivingState_w(Transport* transport) { 497 void TransportController::OnChannelCandidateGathered_w(
498 TransportChannelImpl* channel,
499 const Candidate& candidate) {
461 RTC_DCHECK(worker_thread_->IsCurrent()); 500 RTC_DCHECK(worker_thread_->IsCurrent());
462 UpdateAggregateStates_w();
463 }
464 501
465 void TransportController::OnTransportCompleted_w(Transport* transport) { 502 // We should never signal peer-reflexive candidates.
466 RTC_DCHECK(worker_thread_->IsCurrent()); 503 if (candidate.type() == PRFLX_PORT_TYPE) {
467 UpdateAggregateStates_w(); 504 RTC_DCHECK(false);
468 } 505 return;
469 506 }
470 void TransportController::OnTransportFailed_w(Transport* transport) { 507 std::vector<Candidate> candidates;
471 RTC_DCHECK(worker_thread_->IsCurrent()); 508 candidates.push_back(candidate);
472 UpdateAggregateStates_w(); 509 CandidatesData* data =
473 } 510 new CandidatesData(channel->transport_name(), candidates);
474
475 void TransportController::OnTransportGatheringState_w(Transport* transport) {
476 RTC_DCHECK(worker_thread_->IsCurrent());
477 UpdateAggregateStates_w();
478 }
479
480 void TransportController::OnTransportCandidatesGathered_w(
481 Transport* transport,
482 const std::vector<Candidate>& candidates) {
483 RTC_DCHECK(worker_thread_->IsCurrent());
484 CandidatesData* data = new CandidatesData(transport->name(), candidates);
485 signaling_thread_->Post(this, MSG_CANDIDATESGATHERED, data); 511 signaling_thread_->Post(this, MSG_CANDIDATESGATHERED, data);
486 } 512 }
487 513
488 void TransportController::OnTransportRoleConflict_w() { 514 void TransportController::OnChannelRoleConflict_w(
515 TransportChannelImpl* channel) {
489 RTC_DCHECK(worker_thread_->IsCurrent()); 516 RTC_DCHECK(worker_thread_->IsCurrent());
490 517
491 if (ice_role_switch_) { 518 if (ice_role_switch_) {
492 LOG(LS_WARNING) << "Repeat of role conflict signal from Transport."; 519 LOG(LS_WARNING)
520 << "Repeat of role conflict signal from TransportChannelImpl.";
493 return; 521 return;
494 } 522 }
495 523
496 ice_role_switch_ = true; 524 ice_role_switch_ = true;
497 IceRole reversed_role = (ice_role_ == ICEROLE_CONTROLLING) 525 IceRole reversed_role = (ice_role_ == ICEROLE_CONTROLLING)
498 ? ICEROLE_CONTROLLED 526 ? ICEROLE_CONTROLLED
499 : ICEROLE_CONTROLLING; 527 : ICEROLE_CONTROLLING;
500 for (const auto& kv : transports_) { 528 for (const auto& kv : transports_) {
501 kv.second->SetIceRole(reversed_role); 529 kv.second->SetIceRole(reversed_role);
502 } 530 }
503 } 531 }
504 532
533 void TransportController::OnChannelConnectionRemoved_w(
534 TransportChannelImpl* channel) {
535 RTC_DCHECK(worker_thread_->IsCurrent());
536 LOG(LS_INFO) << channel->transport_name() << " TransportChannel "
537 << channel->component()
538 << " connection removed. Check if state is complete.";
539 UpdateAggregateStates_w();
540 }
541
505 void TransportController::UpdateAggregateStates_w() { 542 void TransportController::UpdateAggregateStates_w() {
506 RTC_DCHECK(worker_thread_->IsCurrent()); 543 RTC_DCHECK(worker_thread_->IsCurrent());
507 544
508 IceConnectionState new_connection_state = kIceConnectionConnecting; 545 IceConnectionState new_connection_state = kIceConnectionConnecting;
509 IceGatheringState new_gathering_state = kIceGatheringNew; 546 IceGatheringState new_gathering_state = kIceGatheringNew;
510 bool any_receiving = false; 547 bool any_receiving = false;
511 bool any_failed = false; 548 bool any_failed = false;
512 bool all_connected = HasChannels_w(); 549 bool all_connected = !channels_.empty();
513 bool all_completed = HasChannels_w(); 550 bool all_completed = !channels_.empty();
514 bool any_gathering = false; 551 bool any_gathering = false;
515 bool all_done_gathering = HasChannels_w(); 552 bool all_done_gathering = !channels_.empty();
516 for (const auto& kv : transports_) { 553 for (const auto& channel : channels_) {
517 // Ignore transports without channels since they're about to be deleted, 554 any_receiving = any_receiving || channel->receiving();
518 // and their state is meaningless. 555 any_failed = any_failed ||
519 if (!kv.second->HasChannels()) { 556 channel->GetState() == TransportChannelState::STATE_FAILED;
520 continue; 557 all_connected = all_connected && channel->writable();
521 } 558 all_completed =
522 any_receiving = any_receiving || kv.second->any_channel_receiving(); 559 all_completed && channel->writable() &&
523 any_failed = any_failed || kv.second->AnyChannelFailed(); 560 channel->GetState() == TransportChannelState::STATE_COMPLETED &&
524 all_connected = all_connected && kv.second->all_channels_writable(); 561 channel->GetIceRole() == ICEROLE_CONTROLLING &&
525 all_completed = all_completed && kv.second->AllChannelsCompleted(); 562 channel->gathering_state() == kIceGatheringComplete;
526 any_gathering = 563 any_gathering =
527 any_gathering || kv.second->gathering_state() != kIceGatheringNew; 564 any_gathering || channel->gathering_state() != kIceGatheringNew;
528 all_done_gathering = all_done_gathering && 565 all_done_gathering = all_done_gathering &&
529 kv.second->gathering_state() == kIceGatheringComplete; 566 channel->gathering_state() == kIceGatheringComplete;
530 } 567 }
531 568
532 if (any_failed) { 569 if (any_failed) {
533 new_connection_state = kIceConnectionFailed; 570 new_connection_state = kIceConnectionFailed;
534 } else if (all_completed) { 571 } else if (all_completed) {
535 new_connection_state = kIceConnectionCompleted; 572 new_connection_state = kIceConnectionCompleted;
536 } else if (all_connected) { 573 } else if (all_connected) {
537 new_connection_state = kIceConnectionConnected; 574 new_connection_state = kIceConnectionConnected;
538 } 575 }
539 if (connection_state_ != new_connection_state) { 576 if (connection_state_ != new_connection_state) {
(...skipping 15 matching lines...) Expand all
555 new_gathering_state = kIceGatheringGathering; 592 new_gathering_state = kIceGatheringGathering;
556 } 593 }
557 if (gathering_state_ != new_gathering_state) { 594 if (gathering_state_ != new_gathering_state) {
558 gathering_state_ = new_gathering_state; 595 gathering_state_ = new_gathering_state;
559 signaling_thread_->Post( 596 signaling_thread_->Post(
560 this, MSG_ICEGATHERINGSTATE, 597 this, MSG_ICEGATHERINGSTATE,
561 new rtc::TypedMessageData<IceGatheringState>(new_gathering_state)); 598 new rtc::TypedMessageData<IceGatheringState>(new_gathering_state));
562 } 599 }
563 } 600 }
564 601
565 bool TransportController::HasChannels_w() {
566 for (const auto& kv : transports_) {
567 if (kv.second->HasChannels()) {
568 return true;
569 }
570 }
571 return false;
572 }
573
574 } // namespace cricket 602 } // namespace cricket
OLDNEW
« webrtc/p2p/base/transport.cc ('K') | « webrtc/p2p/base/transportcontroller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698