Avoid potential dead lock in StreamStatisticianImpl

Extract callbacks for rtp/rtcp data, from StreamStatisticianImpl to
ReceiveStatisticsImpl, into separate methods with guards agains having
incorrect lock order.

BUG=2856
R=andresp@webrtc.org, stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/7649004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5441 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
sprang@webrtc.org 2014-01-27 16:22:08 +00:00
parent 2a260d9fab
commit a45cac0fb7
2 changed files with 40 additions and 8 deletions

View File

@ -69,6 +69,13 @@ void StreamStatisticianImpl::ResetStatistics() {
void StreamStatisticianImpl::IncomingPacket(const RTPHeader& header,
size_t bytes,
bool retransmitted) {
UpdateCounters(header, bytes, retransmitted);
NotifyRtpCallback();
}
void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header,
size_t bytes,
bool retransmitted) {
CriticalSectionScoped cs(stream_lock_.get());
bool in_order = InOrderPacketInternal(header.sequenceNumber);
ssrc_ = header.ssrc;
@ -121,8 +128,6 @@ void StreamStatisticianImpl::IncomingPacket(const RTPHeader& header,
// Our measured overhead. Filter from RFC 5104 4.2.1.2:
// avg_OH (new) = 15/16*avg_OH (old) + 1/16*pckt_OH,
received_packet_overhead_ = (15 * received_packet_overhead_ + packet_oh) >> 4;
rtp_callback_->DataCountersUpdated(receive_counters_, ssrc_);
}
void StreamStatisticianImpl::UpdateJitter(const RTPHeader& header,
@ -166,10 +171,34 @@ void StreamStatisticianImpl::UpdateJitter(const RTPHeader& header,
}
}
void StreamStatisticianImpl::NotifyRtpCallback() {
StreamDataCounters data;
uint32_t ssrc;
{
CriticalSectionScoped cs(stream_lock_.get());
data = receive_counters_;
ssrc = ssrc_;
}
rtp_callback_->DataCountersUpdated(data, ssrc);
}
void StreamStatisticianImpl::NotifyRtcpCallback() {
RtcpStatistics data;
uint32_t ssrc;
{
CriticalSectionScoped cs(stream_lock_.get());
data = last_reported_statistics_;
ssrc = ssrc_;
}
rtcp_callback_->StatisticsUpdated(data, ssrc);
}
void StreamStatisticianImpl::FecPacketReceived() {
CriticalSectionScoped cs(stream_lock_.get());
++receive_counters_.fec_packets;
rtp_callback_->DataCountersUpdated(receive_counters_, ssrc_);
{
CriticalSectionScoped cs(stream_lock_.get());
++receive_counters_.fec_packets;
}
NotifyRtpCallback();
}
void StreamStatisticianImpl::SetMaxReorderingThreshold(
@ -180,7 +209,6 @@ void StreamStatisticianImpl::SetMaxReorderingThreshold(
bool StreamStatisticianImpl::GetStatistics(RtcpStatistics* statistics,
bool reset) {
uint32_t ssrc;
{
CriticalSectionScoped cs(stream_lock_.get());
if (received_seq_first_ == 0 && receive_counters_.bytes == 0) {
@ -199,10 +227,9 @@ bool StreamStatisticianImpl::GetStatistics(RtcpStatistics* statistics,
}
*statistics = CalculateRtcpStatistics();
ssrc = ssrc_;
}
rtcp_callback_->StatisticsUpdated(*statistics, ssrc);
NotifyRtcpCallback();
return true;
}

View File

@ -53,6 +53,11 @@ class StreamStatisticianImpl : public StreamStatistician {
void UpdateJitter(const RTPHeader& header,
uint32_t receive_time_secs,
uint32_t receive_time_frac);
void UpdateCounters(const RTPHeader& rtp_header,
size_t bytes,
bool retransmitted);
void NotifyRtpCallback() LOCKS_EXCLUDED(stream_lock_.get());
void NotifyRtcpCallback() LOCKS_EXCLUDED(stream_lock_.get());
Clock* clock_;
scoped_ptr<CriticalSectionWrapper> stream_lock_;