From 3830748de5d44b5f895c3ebadd576a915737fba8 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 13 Nov 2018 20:23:22 +0100
Subject: [PATCH] output/alsa: clear the `period_buffer` in LockCaughtError()

The method Cancel() assumes that the `period_buffer` must be empty
when `active==false`, but that is not the case when Play() fails.

Of course the assertion in Cancel() is not 100% correct, but I decided
to rather fix this in LockCaughtError() because the `period_buffer`
should only be accessed from within the RTIO thread, and this is the
only code path where `active` can be set to `false` with a non-empty
`period_buffer`.

Fixes #423
---
 NEWS                                    | 2 ++
 src/output/plugins/AlsaOutputPlugin.cxx | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/NEWS b/NEWS
index 8560c1187..2cfd2c025 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,6 @@
 ver 0.21.3 (not yet released)
+* output
+  - alsa: fix crash bug
 
 ver 0.21.2 (2018/11/12)
 * protocol
diff --git a/src/output/plugins/AlsaOutputPlugin.cxx b/src/output/plugins/AlsaOutputPlugin.cxx
index 8b505db7d..c72cf4ea2 100644
--- a/src/output/plugins/AlsaOutputPlugin.cxx
+++ b/src/output/plugins/AlsaOutputPlugin.cxx
@@ -306,6 +306,8 @@ private:
 	}
 
 	void LockCaughtError() noexcept {
+		period_buffer.Clear();
+
 		const std::lock_guard<Mutex> lock(mutex);
 		error = std::current_exception();
 		active = false;