From eb2f0cdd984307cec1df7ab3821f8af2248211df Mon Sep 17 00:00:00 2001
From: Scott Murray <scott.murray@konsulko.com>
Date: Sun, 19 Feb 2023 17:39:28 -0500
Subject: mediaplayer: Improve MPD failure handling

Changes:
- Avoid crashing in the MPD event handler code when our connection
  times out because it has hung.  Additionally, attempt to update
  the front end UI to a sane state with respect to metadata when
  this happens.
- Lower the MPD connection timeout and keepalive timeouts to try to
  catch MPD failures faster.  There are still problems in this area
  with respect to the front end UI getting stuck if it does an
  operation that would attempt to use the MPD API while it is hung.
  Fixing that completely would require a significant refactoring to
  move all the MPD API code to a separate thread so that the QML
  rendering thread does not get stuck.  It's unclear at present if
  such a refactoring is justified, as the MPD hang in this case is
  fixed by changes in MPD 0.23.8.

Bug-AGL: SPEC-4661

Signed-off-by: Scott Murray <scott.murray@konsulko.com>
Change-Id: Ia5e74d00acdc6b3b28cdf87b26486dbddfa02a98
(cherry picked from commit 2cbbf914242d0766ff4e97ee3c0d02505d13e422)
---
 mediaplayer/MpdEventHandler.cpp | 13 +++++++++++++
 1 file changed, 13 insertions(+)

(limited to 'mediaplayer/MpdEventHandler.cpp')

diff --git a/mediaplayer/MpdEventHandler.cpp b/mediaplayer/MpdEventHandler.cpp
index 56a4612..977f96c 100644
--- a/mediaplayer/MpdEventHandler.cpp
+++ b/mediaplayer/MpdEventHandler.cpp
@@ -16,6 +16,7 @@
 
 #include <QDebug>
 #include <QFileInfo>
+#include <QThread>
 #include "MpdEventHandler.h"
 
 MpdEventHandler::MpdEventHandler(QObject *parent) :
@@ -62,9 +63,13 @@ void MpdEventHandler::handleEvents(void)
 		else if (events & MPD_IDLE_PLAYER) {
 			handlePlayerEvent();
 		}
+		if (mpd_connection_get_error(m_mpd_conn) != MPD_ERROR_SUCCESS) {
+			done = true;
+		}
 	}
 
 	qDebug() << "MpdEventHandler::handleEvents: exit";
+	QThread::currentThread()->quit();
 }
 
 void MpdEventHandler::handleDatabaseEvent(void)
@@ -176,6 +181,14 @@ void MpdEventHandler::handlePlayerEvent(void)
 	// corking in WirePlumber...
 
 	struct mpd_status *status = mpd_run_status(m_mpd_conn);
+	if (!status) {
+		// mpd has gone away, attempt to get the UI into a good state
+		metadata["position"] = 0;
+		metadata["status"] = QString("stopped");
+		emit metadataUpdate(metadata);
+		emit playbackStateUpdate(pos, 0, false);
+		return;
+	}
 
 	int elapsed_ms = mpd_status_get_elapsed_ms(status);
 	metadata["position"] = elapsed_ms;
-- 
cgit