diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc index fa2ba7c91e..b7fe2e3ad3 100644 --- a/pc/peerconnection.cc +++ b/pc/peerconnection.cc @@ -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 diff --git a/pc/rtcstats_integrationtest.cc b/pc/rtcstats_integrationtest.cc index cdc46d7d81..627a05bb9a 100644 --- a/pc/rtcstats_integrationtest.cc +++ b/pc/rtcstats_integrationtest.cc @@ -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 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()); }