From 16a953756570cda5e8e42cb170b7ecbe79ddabde Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Thu, 15 Jul 2021 10:54:21 +0200
Subject: [PATCH] pulselayer: cleanup, fix deadlock

Fixing a deadlock that can occur with this path:
startStream -> waitForDevices (blocks with mutex locked) -> hardwareFormatAvailable (deadlock on mutex)

Change-Id: I808513e62618986b9a4217d3e70f57cb91cef595
---
 src/media/audio/pulseaudio/pulselayer.cpp | 8 ++++----
 src/media/audio/pulseaudio/pulselayer.h   | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/media/audio/pulseaudio/pulselayer.cpp b/src/media/audio/pulseaudio/pulselayer.cpp
index a1cfbb4161..1f583e8c7c 100644
--- a/src/media/audio/pulseaudio/pulselayer.cpp
+++ b/src/media/audio/pulseaudio/pulselayer.cpp
@@ -419,7 +419,6 @@ PulseLayer::disconnectAudioStream()
 void
 PulseLayer::startStream(AudioDeviceType type)
 {
-    std::lock_guard<std::mutex> lk(mutex_);
     waitForDevices();
     PulseMainLoopLock lock(mainloop_.get());
 
@@ -446,6 +445,7 @@ PulseLayer::startStream(AudioDeviceType type)
     }
     pa_threaded_mainloop_signal(mainloop_.get(), 0);
 
+    std::lock_guard<std::mutex> lk(mutex_);
     status_ = Status::Started;
     startedCv_.notify_all();
 }
@@ -453,7 +453,6 @@ PulseLayer::startStream(AudioDeviceType type)
 void
 PulseLayer::stopStream(AudioDeviceType type)
 {
-    std::lock_guard<std::mutex> lk(mutex_);
     waitForDevices();
     PulseMainLoopLock lock(mainloop_.get());
     auto& stream(getStream(type));
@@ -465,6 +464,7 @@ PulseLayer::stopStream(AudioDeviceType type)
     stream->stop();
     stream.reset();
 
+    std::lock_guard<std::mutex> lk(mutex_);
     if (not playback_ and not ringtone_ and not record_) {
         pendingStreams = 0;
         status_ = Status::Idle;
@@ -736,7 +736,7 @@ PulseLayer::source_input_info_callback(pa_context* c UNUSED,
              i->flags & PA_SOURCE_HARDWARE ? "HARDWARE" : "");
 #endif
     if (not context->inSourceList(i->name)) {
-        context->sourceList_.push_back(*i);
+        context->sourceList_.emplace_back(*i);
     }
 }
 
@@ -782,7 +782,7 @@ PulseLayer::sink_input_info_callback(pa_context* c UNUSED,
              i->flags & PA_SINK_HARDWARE ? "HARDWARE" : "");
 #endif
     if (not context->inSinkList(i->name)) {
-        context->sinkList_.push_back(*i);
+        context->sinkList_.emplace_back(*i);
     }
 }
 
diff --git a/src/media/audio/pulseaudio/pulselayer.h b/src/media/audio/pulseaudio/pulselayer.h
index 0664ef1773..7ae673c807 100644
--- a/src/media/audio/pulseaudio/pulselayer.h
+++ b/src/media/audio/pulseaudio/pulselayer.h
@@ -54,7 +54,7 @@ struct PaDeviceInfos
     pa_channel_map channel_map {};
     uint32_t monitor_of {PA_INVALID_INDEX};
 
-    PaDeviceInfos() {};
+    PaDeviceInfos() {}
 
     PaDeviceInfos(const pa_source_info& source)
         : index(source.index)
-- 
GitLab