Index: webrtc/p2p/client/basicportallocator.cc |
diff --git a/webrtc/p2p/client/basicportallocator.cc b/webrtc/p2p/client/basicportallocator.cc |
index e94feb4d15b0e9aa8305ae03f46b7fe625b46d29..dba68f177e5120a496a39d603d622971ac776ac4 100644 |
--- a/webrtc/p2p/client/basicportallocator.cc |
+++ b/webrtc/p2p/client/basicportallocator.cc |
@@ -314,7 +314,12 @@ void BasicPortAllocatorSession::RegatherOnFailedNetworks() { |
} |
// Remove ports from being used locally and send signaling to remove |
// the candidates on the remote side. |
- RemovePortsAndCandidates(failed_networks); |
+ std::vector<PortData*> ports_to_prune = GetUnprunedPorts(failed_networks); |
+ if (!ports_to_prune.empty()) { |
+ LOG(LS_INFO) << "Prune " << ports_to_prune.size() |
+ << " ports because their networks failed"; |
+ PrunePortsAndRemoveCandidates(ports_to_prune); |
+ } |
if (allocation_started_ && network_manager_started_) { |
DoAllocate(); |
@@ -615,7 +620,12 @@ void BasicPortAllocatorSession::OnNetworksChanged() { |
failed_networks.push_back(sequence->network()); |
} |
} |
- RemovePortsAndCandidates(failed_networks); |
+ std::vector<PortData*> ports_to_prune = GetUnprunedPorts(failed_networks); |
+ if (!ports_to_prune.empty()) { |
+ LOG(LS_INFO) << "Prune " << ports_to_prune.size() |
+ << " ports because their networks were gone"; |
+ PrunePortsAndRemoveCandidates(ports_to_prune); |
+ } |
if (!network_manager_started_) { |
LOG(LS_INFO) << "Network manager is started"; |
@@ -757,29 +767,32 @@ bool BasicPortAllocatorSession::PruneTurnPorts(Port* newly_pairable_turn_port) { |
RTC_CHECK(best_turn_port != nullptr); |
bool pruned = false; |
- std::vector<PortInterface*> pruned_ports; |
+ std::vector<PortData*> ports_to_prune; |
for (PortData& data : ports_) { |
if (data.port()->Network()->name() == network_name && |
data.port()->Type() == RELAY_PORT_TYPE && !data.pruned() && |
ComparePort(data.port(), best_turn_port) < 0) { |
- data.set_pruned(); |
pruned = true; |
- data.port()->Prune(); |
if (data.port() != newly_pairable_turn_port) { |
- pruned_ports.push_back(data.port()); |
+ // These ports will be pruned in PrunePortsAndRemoveCandidates. |
+ ports_to_prune.push_back(&data); |
+ } else { |
+ data.Prune(); |
} |
} |
} |
- if (!pruned_ports.empty()) { |
- LOG(LS_INFO) << "Pruned " << pruned_ports.size() << " ports"; |
- SignalPortsPruned(this, pruned_ports); |
+ |
+ if (!ports_to_prune.empty()) { |
+ LOG(LS_INFO) << "Prune " << ports_to_prune.size() |
+ << " low-priority TURN ports"; |
+ PrunePortsAndRemoveCandidates(ports_to_prune); |
} |
return pruned; |
} |
void BasicPortAllocatorSession::PruneAllPorts() { |
for (PortData& data : ports_) { |
- data.port()->Prune(); |
+ data.Prune(); |
} |
} |
@@ -942,32 +955,41 @@ BasicPortAllocatorSession::PortData* BasicPortAllocatorSession::FindPort( |
return NULL; |
} |
-// Removes ports and candidates created on a given list of networks. |
-void BasicPortAllocatorSession::RemovePortsAndCandidates( |
+std::vector<BasicPortAllocatorSession::PortData*> |
+BasicPortAllocatorSession::GetUnprunedPorts( |
const std::vector<rtc::Network*>& networks) { |
- std::vector<PortInterface*> ports_to_remove; |
- std::vector<Candidate> candidates_to_remove; |
- for (PortData& data : ports_) { |
- if (std::find(networks.begin(), networks.end(), |
- data.sequence()->network()) == networks.end()) { |
- continue; |
+ std::vector<PortData*> unpruned_ports; |
+ for (PortData& port : ports_) { |
+ if (!port.pruned() && |
+ std::find(networks.begin(), networks.end(), |
+ port.sequence()->network()) != networks.end()) { |
+ unpruned_ports.push_back(&port); |
} |
+ } |
+ return unpruned_ports; |
+} |
+ |
+void BasicPortAllocatorSession::PrunePortsAndRemoveCandidates( |
+ const std::vector<PortData*>& port_data_list) { |
+ std::vector<PortInterface*> pruned_ports; |
+ std::vector<Candidate> removed_candidates; |
+ for (PortData* data : port_data_list) { |
// Prune the port so that it may be destroyed. |
- data.port()->Prune(); |
- ports_to_remove.push_back(data.port()); |
- if (data.has_pairable_candidate()) { |
- GetCandidatesFromPort(data, &candidates_to_remove); |
+ data->Prune(); |
+ pruned_ports.push_back(data->port()); |
+ if (data->has_pairable_candidate()) { |
+ GetCandidatesFromPort(*data, &removed_candidates); |
// Mark the port as having no pairable candidates so that its candidates |
// won't be removed multiple times. |
- data.set_has_pairable_candidate(false); |
+ data->set_has_pairable_candidate(false); |
} |
} |
- if (!ports_to_remove.empty()) { |
- LOG(LS_INFO) << "Removed " << ports_to_remove.size() << " ports"; |
- SignalPortsPruned(this, ports_to_remove); |
+ if (!pruned_ports.empty()) { |
+ SignalPortsPruned(this, pruned_ports); |
} |
- if (!candidates_to_remove.empty()) { |
- SignalCandidatesRemoved(this, candidates_to_remove); |
+ if (!removed_candidates.empty()) { |
+ LOG(LS_INFO) << "Removed " << removed_candidates.size() << " candidates"; |
+ SignalCandidatesRemoved(this, removed_candidates); |
} |
} |