From 412282acf9a979b51808d50b27c3c7333ced05d2 Mon Sep 17 00:00:00 2001 From: Yves Gerey Date: Mon, 22 Jul 2019 21:15:22 +0200 Subject: [PATCH] [tsan] Guard audio_device_pulse_linux members from concurrent access. This CL also fixes data races caused by tests themselves. TBR= henrika@webrtc.org Bug: webrtc:9751 Change-Id: Ie7c785b27142fd465f5b4dc9fb0628bd7274f1d2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146600 Reviewed-by: Henrik Andreassson Commit-Queue: Yves Gerey Cr-Commit-Position: refs/heads/master@{#28829} --- modules/audio_device/audio_device_unittest.cc | 7 +++++-- .../audio_device/linux/audio_device_pulse_linux.cc | 14 ++++++++++---- .../audio_device/linux/audio_device_pulse_linux.h | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/modules/audio_device/audio_device_unittest.cc b/modules/audio_device/audio_device_unittest.cc index 8e966f7943..e6c13db3a8 100644 --- a/modules/audio_device/audio_device_unittest.cc +++ b/modules/audio_device/audio_device_unittest.cc @@ -1010,6 +1010,7 @@ TEST_P(MAYBE_AudioDeviceTest, StartPlayoutVerifyCallbacks) { StartPlayout(); event()->Wait(kTestTimeOutInMilliseconds); StopPlayout(); + PreTearDown(); } // Start recording and verify that the native audio layer starts providing real @@ -1080,13 +1081,14 @@ TEST_P(MAYBE_AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) { std::max(kTestTimeOutInMilliseconds, 1000 * kFullDuplexTimeInSec))); StopRecording(); StopPlayout(); + // Avoid concurrent access to audio_stream. + PreTearDown(); // This thresholds is set rather high to accommodate differences in hardware // in several devices. The main idea is to capture cases where a very large // latency is built up. See http://bugs.webrtc.org/7744 for examples on // bots where relatively large average latencies can happen. EXPECT_LE(audio_stream.average_size(), 25u); PRINT("\n"); - PreTearDown(); } // Runs audio in full duplex until user hits Enter. Intended as a manual test @@ -1145,13 +1147,14 @@ TEST_P(MAYBE_AudioDeviceTest, DISABLED_MeasureLoopbackLatency) { std::max(kTestTimeOutInMilliseconds, 1000 * kMeasureLatencyTimeInSec))); StopRecording(); StopPlayout(); + // Avoid concurrent access to audio_stream. + PreTearDown(); // Verify that a sufficient number of transmitted impulses are detected. EXPECT_GE(audio_stream.num_latency_values(), static_cast( kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 2)); // Print out min, max and average delay values for debugging purposes. audio_stream.PrintResults(); - PreTearDown(); } #ifdef WEBRTC_WIN diff --git a/modules/audio_device/linux/audio_device_pulse_linux.cc b/modules/audio_device/linux/audio_device_pulse_linux.cc index ff385118c2..9faff1d021 100644 --- a/modules/audio_device/linux/audio_device_pulse_linux.cc +++ b/modules/audio_device/linux/audio_device_pulse_linux.cc @@ -871,8 +871,11 @@ int32_t AudioDeviceLinuxPulse::InitPlayout() { playSampleSpec.rate = sample_rate_hz_; // Create a new play stream - _playStream = - LATE(pa_stream_new)(_paContext, "playStream", &playSampleSpec, NULL); + { + rtc::CritScope lock(&_critSect); + _playStream = + LATE(pa_stream_new)(_paContext, "playStream", &playSampleSpec, NULL); + } if (!_playStream) { RTC_LOG(LS_ERROR) << "failed to create play stream, err=" @@ -941,8 +944,11 @@ int32_t AudioDeviceLinuxPulse::InitPlayout() { LATE(pa_stream_set_state_callback)(_playStream, PaStreamStateCallback, this); // Mark playout side as initialized - _playIsInitialized = true; - _sndCardPlayDelay = 0; + { + rtc::CritScope lock(&_critSect); + _playIsInitialized = true; + _sndCardPlayDelay = 0; + } return 0; } diff --git a/modules/audio_device/linux/audio_device_pulse_linux.h b/modules/audio_device/linux/audio_device_pulse_linux.h index a2b8166cc3..830f15f706 100644 --- a/modules/audio_device/linux/audio_device_pulse_linux.h +++ b/modules/audio_device/linux/audio_device_pulse_linux.h @@ -298,7 +298,7 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric { bool update_speaker_volume_at_startup_; bool quit_ RTC_GUARDED_BY(&_critSect); - uint32_t _sndCardPlayDelay; + uint32_t _sndCardPlayDelay RTC_GUARDED_BY(&_critSect); int32_t _writeErrors;