From 35dbc1a90c5110fbf6ab18e98c43463d1b4ea4f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arsen=20Arsenovi=C4=87?= <arsen@aarsen.me>
Date: Tue, 8 Mar 2022 23:38:49 +0100
Subject: [PATCH] mixer,output: prevent setting volume before outputs are
 really enabled

Previous versions of MPD would call SetVolume on enabled outputs before
they are ready, causing all of MPD to crash. Checking the really_enabled
flag prevents this, though it also prevents setting volume before the
player starts.

Before (with the PipeWire output):
  [i] ~$ mpc clear
  volume: 81%   repeat: off   random: off   single: off   consume: off
  [i] ~$ systemctl --user restart mpd.service
  [i] ~$ mpc volume 100
  MPD error: Connection closed by the server
  [i] ~ 1 $

After:
  [i] ~$ # mpd is freshly started w/o anything in the queue
  [i] ~$ mpc
  volume:100%   repeat: off   random: off   single: off   consume: off
  [i] ~$ mpc volume 80
  MPD error: problems setting volume
  [i] ~ 1 $ mpc
  volume:100%   repeat: off   random: off   single: off   consume: off
  [i] ~$
---
 src/mixer/MixerAll.cxx | 2 +-
 src/output/Control.hxx | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/mixer/MixerAll.cxx b/src/mixer/MixerAll.cxx
index da96f93f3..2d9c9080e 100644
--- a/src/mixer/MixerAll.cxx
+++ b/src/mixer/MixerAll.cxx
@@ -84,7 +84,7 @@ output_mixer_set_volume(AudioOutputControl &ao, unsigned volume) noexcept
 
 	/* software mixers are always updated, even if they are
 	   disabled */
-	if (!ao.IsEnabled() && !mixer->IsPlugin(software_mixer_plugin))
+	if (!ao.IsReallyEnabled() && !mixer->IsPlugin(software_mixer_plugin))
 		return false;
 
 	try {
diff --git a/src/output/Control.hxx b/src/output/Control.hxx
index fa1dfbece..8f3b5fa6e 100644
--- a/src/output/Control.hxx
+++ b/src/output/Control.hxx
@@ -288,6 +288,13 @@ public:
 		return !output;
 	}
 
+	/**
+	 * Caller must lock the mutex.
+	 */
+	bool IsReallyEnabled() const noexcept {
+		return really_enabled;
+	}
+
 	/**
 	 * Caller must lock the mutex.
 	 */