Files
platform-external-webrtc/webrtc/modules/rtp_rtcp/source/dtmf_queue.cc
pbos@webrtc.org 7c4d20fd6c Remove potential deadlock in RTPSenderAudio.
Removes lock-order inversion formed by RTPSenderAudio->RTPSender calls
by doing a lot shorter locking which fetches a current state of
RTPSenderAudio variables before sending.

Thread annotates locked variables and removes one lock in
RTPSenderAudio, bonus fixes data races reported in voe_auto_test
--automated under TSan (DTMF data race).

Also includes some bonus cleanup of RTPSenderVideo which removes the
send critsect completely as all methods using it was always called
from RTPSender under its send_critsect.

R=henrik.lundin@webrtc.org, stefan@webrtc.org, tommi@webrtc.org
BUG=3001, chromium:454654

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

Cr-Commit-Position: refs/heads/master@{#8348}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8348 4adac7df-926f-26a2-2b94-8c16560cd09d
2015-02-12 12:20:50 +00:00

70 lines
1.9 KiB
C++

/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/modules/rtp_rtcp/source/dtmf_queue.h"
#include <string.h> //memset
namespace webrtc {
DTMFqueue::DTMFqueue()
: dtmf_critsect_(CriticalSectionWrapper::CreateCriticalSection()),
next_empty_index_(0) {
memset(dtmf_key_, 0, sizeof(dtmf_key_));
memset(dtmf_length, 0, sizeof(dtmf_length));
memset(dtmf_level_, 0, sizeof(dtmf_level_));
}
DTMFqueue::~DTMFqueue() { delete dtmf_critsect_; }
int32_t DTMFqueue::AddDTMF(uint8_t key, uint16_t len, uint8_t level) {
CriticalSectionScoped lock(dtmf_critsect_);
if (next_empty_index_ >= DTMF_OUTBAND_MAX) {
return -1;
}
int32_t index = next_empty_index_;
dtmf_key_[index] = key;
dtmf_length[index] = len;
dtmf_level_[index] = level;
next_empty_index_++;
return 0;
}
int8_t DTMFqueue::NextDTMF(uint8_t* dtmf_key, uint16_t* len, uint8_t* level) {
CriticalSectionScoped lock(dtmf_critsect_);
if (next_empty_index_ == 0)
return -1;
*dtmf_key = dtmf_key_[0];
*len = dtmf_length[0];
*level = dtmf_level_[0];
memmove(&(dtmf_key_[0]), &(dtmf_key_[1]),
next_empty_index_ * sizeof(uint8_t));
memmove(&(dtmf_length[0]), &(dtmf_length[1]),
next_empty_index_ * sizeof(uint16_t));
memmove(&(dtmf_level_[0]), &(dtmf_level_[1]),
next_empty_index_ * sizeof(uint8_t));
next_empty_index_--;
return 0;
}
bool DTMFqueue::PendingDTMF() {
CriticalSectionScoped lock(dtmf_critsect_);
return next_empty_index_ > 0;
}
void DTMFqueue::ResetDTMF() {
CriticalSectionScoped lock(dtmf_critsect_);
next_empty_index_ = 0;
}
} // namespace webrtc