Fix crash that occurs if GetStats is called from within OnStatsDelivered
This was resulting in the currently executing stats callback to be
invoked *again*, possibly ad infinitum, resulting in stack overflow.
Bug: webrtc:8973
Change-Id: Ib3bcc8e6bdd991728214fa242dda2010efc919a7
Reviewed-on: https://webrtc-review.googlesource.com/59464
Commit-Queue: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22313}
diff --git a/pc/rtcstatscollector_unittest.cc b/pc/rtcstatscollector_unittest.cc
index f180471..5240e62 100644
--- a/pc/rtcstatscollector_unittest.cc
+++ b/pc/rtcstatscollector_unittest.cc
@@ -1910,6 +1910,37 @@
EXPECT_EQ(1, track_stats.size());
}
+// Used for test below, to test calling GetStatsReport during a callback.
+class ReentrantCallback : public RTCStatsCollectorCallback {
+ public:
+ explicit ReentrantCallback(RTCStatsCollectorWrapper* stats) : stats_(stats) {}
+
+ void OnStatsDelivered(
+ const rtc::scoped_refptr<const RTCStatsReport>& report) override {
+ stats_->GetStatsReport();
+ called_ = true;
+ }
+
+ bool called() const { return called_; }
+
+ private:
+ RTCStatsCollectorWrapper* stats_;
+ bool called_ = false;
+};
+
+// Test that nothing bad happens if a callback causes GetStatsReport to be
+// called again recursively. Regression test for crbug.com/webrtc/8973.
+TEST_F(RTCStatsCollectorTest, DoNotCrashOnReentrantInvocation) {
+ rtc::scoped_refptr<ReentrantCallback> callback1(
+ new rtc::RefCountedObject<ReentrantCallback>(stats_.get()));
+ rtc::scoped_refptr<ReentrantCallback> callback2(
+ new rtc::RefCountedObject<ReentrantCallback>(stats_.get()));
+ stats_->stats_collector()->GetStatsReport(callback1);
+ stats_->stats_collector()->GetStatsReport(callback2);
+ EXPECT_TRUE_WAIT(callback1->called(), kGetStatsReportTimeoutMs);
+ EXPECT_TRUE_WAIT(callback2->called(), kGetStatsReportTimeoutMs);
+}
+
class RTCTestStats : public RTCStats {
public:
WEBRTC_RTCSTATS_DECL();