From d1cc73775fe96a3c42108a01aad00056060df564 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Sun, 16 Feb 2020 20:38:56 +0100
Subject: [PATCH] Instance: flush input cache on SIGHUP

---
 doc/user.rst                |  9 ++++++++-
 src/Instance.cxx            |  7 +++++++
 src/Instance.hxx            |  2 ++
 src/unix/SignalHandlers.cxx | 10 +++++++---
 4 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/doc/user.rst b/doc/user.rst
index 8e303bd87..67bf3b2e8 100644
--- a/doc/user.rst
+++ b/doc/user.rst
@@ -295,6 +295,8 @@ The following table lists the input options valid for all plugins:
 
 More information can be found in the :ref:`input_plugins` reference.
 
+.. _input_cache:
+
 Configuring the Input Cache
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -327,6 +329,9 @@ configuration file:
 This allocates a cache of 1 GB.  If the cache grows larger than that,
 older files will be evicted.
 
+You flush the cache at any time by sending ``SIGHUP`` to the
+:program:`MPD` process, see :ref:`signals`.
+
 
 Configuring decoder plugins
 ---------------------------
@@ -878,6 +883,7 @@ To auto-start :program:`MPD` upon login, type:
 
     systemctl --user enable mpd
 
+.. _signals:
 
 Signals
 -------
@@ -885,7 +891,8 @@ Signals
 :program:`MPD` understands the following UNIX signals:
 
 - ``SIGTERM``, ``SIGINT``: shut down MPD
-- ``SIGHUP``: reopen log files (send this after log rotation)
+- ``SIGHUP``: reopen log files (send this after log rotation) and
+  flush caches (see :ref:`input_cache`)
 
 
 The client
diff --git a/src/Instance.cxx b/src/Instance.cxx
index 2d8003f42..cf25ca201 100644
--- a/src/Instance.cxx
+++ b/src/Instance.cxx
@@ -198,3 +198,10 @@ Instance::OnIdle(unsigned flags) noexcept
 	for (auto &partition : partitions)
 		partition.EmitIdle(flags);
 }
+
+void
+Instance::FlushCaches() noexcept
+{
+	if (input_cache)
+		input_cache->Flush();
+}
diff --git a/src/Instance.hxx b/src/Instance.hxx
index 0baebcc26..509610d2a 100644
--- a/src/Instance.hxx
+++ b/src/Instance.hxx
@@ -209,6 +209,8 @@ struct Instance final
 	}
 #endif
 
+	void FlushCaches() noexcept;
+
 private:
 #ifdef ENABLE_DATABASE
 	/* virtual methods from class DatabaseListener */
diff --git a/src/unix/SignalHandlers.cxx b/src/unix/SignalHandlers.cxx
index 873025ec0..5dbb47778 100644
--- a/src/unix/SignalHandlers.cxx
+++ b/src/unix/SignalHandlers.cxx
@@ -47,10 +47,14 @@ x_sigaction(int signum, const struct sigaction *act)
 }
 
 static void
-handle_reload_event(void *) noexcept
+handle_reload_event(void *ctx) noexcept
 {
-	LogDebug(signal_handlers_domain, "got SIGHUP, reopening log files");
+	auto &instance = *(Instance *)ctx;
+
+	LogDebug(signal_handlers_domain, "got SIGHUP, reopening log files and flushing caches");
 	cycle_log_files();
+
+	instance.FlushCaches();
 }
 
 #endif
@@ -73,7 +77,7 @@ SignalHandlersInit(Instance &instance)
 	SignalMonitorRegister(SIGINT, {&loop, HandleShutdownSignal});
 	SignalMonitorRegister(SIGTERM, {&loop, HandleShutdownSignal});
 
-	SignalMonitorRegister(SIGHUP, {nullptr, handle_reload_event});
+	SignalMonitorRegister(SIGHUP, {&instance, handle_reload_event});
 #endif
 }