From 7daed185cb8a6f64739d9697c4ffd572bddc6416 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Fri, 31 Aug 2018 18:42:28 +0100 Subject: [PATCH] cubeb_sink: Protect queue against multithreaded access --- src/audio_core/cubeb_sink.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index e679a9588..699f5b47c 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include #include #include "audio_core/audio_types.h" @@ -17,6 +18,7 @@ struct CubebSink::Impl { cubeb* ctx = nullptr; cubeb_stream* stream = nullptr; + std::mutex queue_mutex; std::vector queue; static long DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, @@ -97,6 +99,8 @@ void CubebSink::EnqueueSamples(const s16* samples, size_t sample_count) { if (!impl->ctx) return; + std::lock_guard lock{impl->queue_mutex}; + impl->queue.reserve(impl->queue.size() + sample_count * 2); std::copy(samples, samples + sample_count * 2, std::back_inserter(impl->queue)); } @@ -105,6 +109,7 @@ size_t CubebSink::SamplesInQueue() const { if (!impl->ctx) return 0; + std::lock_guard lock{impl->queue_mutex}; return impl->queue.size() / 2; } @@ -116,6 +121,8 @@ long CubebSink::Impl::DataCallback(cubeb_stream* stream, void* user_data, const if (!impl) return 0; + std::lock_guard lock{impl->queue_mutex}; + size_t frames_to_write = std::min(impl->queue.size() / 2, static_cast(num_frames)); memcpy(buffer, impl->queue.data(), frames_to_write * sizeof(s16) * 2);