Fix possible race between the stats collector and transport controller

Previously, it would be possible for the RTCStatsCollector to start
an async network task to gather stats that would be run after the
PeerConnection was closed when the transport controller was set to
null.

Bug: chromium:829238
Change-Id: I22fb4ce603caf2614814780b95b62127cee28284
Reviewed-on: https://webrtc-review.googlesource.com/72525
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23046}
This commit is contained in:
Steve Anton
2018-04-26 11:44:00 -07:00
parent e782abab19
commit 25cfeb9ef1
2 changed files with 23 additions and 1 deletions

View File

@ -3210,6 +3210,15 @@ void PeerConnection::Close() {
for (auto transceiver : transceivers_) {
transceiver->Stop();
}
// Ensure that all asynchronous stats requests are completed before destroying
// the transport controller below.
if (stats_collector_) {
stats_collector_->WaitForPendingRequest();
}
// Don't destroy BaseChannels until after stats has been cleaned up so that
// the last stats request can still read from the channels.
DestroyAllChannels();
// The event log is used in the transport controller, which must be outlived

View File

@ -826,7 +826,20 @@ TEST_F(RTCStatsIntegrationTest, GetsStatsWhileDestroyingPeerConnections) {
caller_ = nullptr;
// Any pending stats requests should have completed in the act of destroying
// the peer connection.
EXPECT_TRUE(stats_obtainer->report());
ASSERT_TRUE(stats_obtainer->report());
EXPECT_EQ(stats_obtainer->report()->ToJson(),
RTCStatsReportTraceListener::last_trace());
}
TEST_F(RTCStatsIntegrationTest, GetsStatsWhileClosingPeerConnection) {
StartCall();
rtc::scoped_refptr<RTCStatsObtainer> stats_obtainer =
RTCStatsObtainer::Create();
caller_->pc()->GetStats(stats_obtainer);
caller_->pc()->Close();
ASSERT_TRUE(stats_obtainer->report());
EXPECT_EQ(stats_obtainer->report()->ToJson(),
RTCStatsReportTraceListener::last_trace());
}