Fix a data race in AudioEncoderMutableImpl and derived classes
Before this change, it could happen that a caller would get a pointer to the encoder_ but not use it before another thread called the Reconstruct method, changing the pointer. This of course resulted in bad access crashes. With this change, each use of the pointer acquired from the encoder() method is protected by the same lock that is required to update the pointer. Note that this fix is probably too aggressive, since it also affects the Opus implementation; the crash has so far only been seen for iSAC. Also adding a test to trigger the problem. The test did not trigger the problem deterministically, but out would typically find it in less than 1000 runs. BUG=chromium:499468 R=jmarusic@webrtc.org, kwiberg@webrtc.org Review URL: https://codereview.webrtc.org/1176303004. Cr-Commit-Position: refs/heads/master@{#9436}
This commit is contained in:
@ -67,6 +67,7 @@ int AudioEncoderDecoderMutableIsacFix::Decode(const uint8_t* encoded,
|
||||
size_t max_decoded_bytes,
|
||||
int16_t* decoded,
|
||||
SpeechType* speech_type) {
|
||||
CriticalSectionScoped cs(encoder_lock_.get());
|
||||
return encoder()->Decode(encoded, encoded_len, sample_rate_hz,
|
||||
max_decoded_bytes, decoded, speech_type);
|
||||
}
|
||||
@ -78,20 +79,24 @@ int AudioEncoderDecoderMutableIsacFix::DecodeRedundant(
|
||||
size_t max_decoded_bytes,
|
||||
int16_t* decoded,
|
||||
SpeechType* speech_type) {
|
||||
CriticalSectionScoped cs(encoder_lock_.get());
|
||||
return encoder()->DecodeRedundant(encoded, encoded_len, sample_rate_hz,
|
||||
max_decoded_bytes, decoded, speech_type);
|
||||
}
|
||||
|
||||
bool AudioEncoderDecoderMutableIsacFix::HasDecodePlc() const {
|
||||
CriticalSectionScoped cs(encoder_lock_.get());
|
||||
return encoder()->HasDecodePlc();
|
||||
}
|
||||
|
||||
int AudioEncoderDecoderMutableIsacFix::DecodePlc(int num_frames,
|
||||
int16_t* decoded) {
|
||||
CriticalSectionScoped cs(encoder_lock_.get());
|
||||
return encoder()->DecodePlc(num_frames, decoded);
|
||||
}
|
||||
|
||||
int AudioEncoderDecoderMutableIsacFix::Init() {
|
||||
CriticalSectionScoped cs(encoder_lock_.get());
|
||||
return encoder()->Init();
|
||||
}
|
||||
|
||||
@ -101,32 +106,38 @@ int AudioEncoderDecoderMutableIsacFix::IncomingPacket(
|
||||
uint16_t rtp_sequence_number,
|
||||
uint32_t rtp_timestamp,
|
||||
uint32_t arrival_timestamp) {
|
||||
CriticalSectionScoped cs(encoder_lock_.get());
|
||||
return encoder()->IncomingPacket(payload, payload_len, rtp_sequence_number,
|
||||
rtp_timestamp, arrival_timestamp);
|
||||
}
|
||||
|
||||
int AudioEncoderDecoderMutableIsacFix::ErrorCode() {
|
||||
CriticalSectionScoped cs(encoder_lock_.get());
|
||||
return encoder()->ErrorCode();
|
||||
}
|
||||
|
||||
int AudioEncoderDecoderMutableIsacFix::PacketDuration(
|
||||
const uint8_t* encoded,
|
||||
size_t encoded_len) const {
|
||||
CriticalSectionScoped cs(encoder_lock_.get());
|
||||
return encoder()->PacketDuration(encoded, encoded_len);
|
||||
}
|
||||
|
||||
int AudioEncoderDecoderMutableIsacFix::PacketDurationRedundant(
|
||||
const uint8_t* encoded,
|
||||
size_t encoded_len) const {
|
||||
CriticalSectionScoped cs(encoder_lock_.get());
|
||||
return encoder()->PacketDurationRedundant(encoded, encoded_len);
|
||||
}
|
||||
|
||||
bool AudioEncoderDecoderMutableIsacFix::PacketHasFec(const uint8_t* encoded,
|
||||
size_t encoded_len) const {
|
||||
CriticalSectionScoped cs(encoder_lock_.get());
|
||||
return encoder()->PacketHasFec(encoded, encoded_len);
|
||||
}
|
||||
|
||||
size_t AudioEncoderDecoderMutableIsacFix::Channels() const {
|
||||
CriticalSectionScoped cs(encoder_lock_.get());
|
||||
return encoder()->Channels();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user