summaryrefslogtreecommitdiff
path: root/src/Main.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/Main.cxx')
-rw-r--r--src/Main.cxx145
1 files changed, 96 insertions, 49 deletions
diff --git a/src/Main.cxx b/src/Main.cxx
index 31c4d9fbd..19b18f7a4 100644
--- a/src/Main.cxx
+++ b/src/Main.cxx
@@ -28,18 +28,18 @@
#include "Mapper.hxx"
#include "Permission.hxx"
#include "Listen.hxx"
+#include "client/Listener.hxx"
#include "client/Client.hxx"
#include "client/ClientList.hxx"
#include "command/AllCommands.hxx"
#include "Partition.hxx"
-#include "tag/TagConfig.hxx"
+#include "tag/Config.hxx"
#include "ReplayGainGlobal.hxx"
#include "Idle.hxx"
#include "Log.hxx"
#include "LogInit.hxx"
#include "input/Init.hxx"
#include "event/Loop.hxx"
-#include "IOThread.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/Config.hxx"
#include "playlist/PlaylistRegistry.hxx"
@@ -166,15 +166,15 @@ glue_mapper_init()
#ifdef ENABLE_DATABASE
static void
-InitStorage()
+InitStorage(EventLoop &event_loop)
{
- Storage *storage = CreateConfiguredStorage(io_thread_get());
+ auto storage = CreateConfiguredStorage(event_loop);
if (storage == nullptr)
return;
CompositeStorage *composite = new CompositeStorage();
instance->storage = composite;
- composite->Mount("", storage);
+ composite->Mount("", std::move(storage));
}
/**
@@ -186,12 +186,14 @@ static bool
glue_db_init_and_load(void)
{
instance->database =
- CreateConfiguredDatabase(instance->event_loop, *instance);
+ CreateConfiguredDatabase(instance->event_loop,
+ instance->io_thread.GetEventLoop(),
+ *instance);
if (instance->database == nullptr)
return true;
if (instance->database->GetPlugin().flags & DatabasePlugin::FLAG_REQUIRE_STORAGE) {
- InitStorage();
+ InitStorage(instance->io_thread.GetEventLoop());
if (instance->storage == nullptr) {
delete instance->database;
@@ -271,7 +273,7 @@ glue_state_file_init()
StateFile::DEFAULT_INTERVAL);
instance->state_file = new StateFile(std::move(path_fs), interval,
- *instance->partition,
+ instance->partitions.front(),
instance->event_loop);
instance->state_file->Read();
}
@@ -351,23 +353,25 @@ initialize_decoder_and_player(const ReplayGainConfig &replay_gain_config)
try {
configured_audio_format = ParseAudioFormat(param->value.c_str(),
true);
- } catch (const std::runtime_error &) {
+ } catch (...) {
std::throw_with_nested(FormatRuntimeError("error parsing line %i",
param->line));
}
}
- instance->partition = new Partition(*instance,
- max_length,
- buffered_chunks,
- buffered_before_play,
- configured_audio_format,
- replay_gain_config);
+ instance->partitions.emplace_back(*instance,
+ "default",
+ max_length,
+ buffered_chunks,
+ buffered_before_play,
+ configured_audio_format,
+ replay_gain_config);
+ auto &partition = instance->partitions.back();
try {
param = config_get_param(ConfigOption::REPLAYGAIN);
if (param != nullptr)
- instance->partition->replay_gain_mode =
+ partition.replay_gain_mode =
FromString(param->value.c_str());
} catch (...) {
std::throw_with_nested(FormatRuntimeError("Failed to parse line %i",
@@ -375,6 +379,55 @@ initialize_decoder_and_player(const ReplayGainConfig &replay_gain_config)
}
}
+inline void
+Instance::BeginShutdownUpdate() noexcept
+{
+#ifdef ENABLE_DATABASE
+#ifdef ENABLE_INOTIFY
+ mpd_inotify_finish();
+#endif
+
+ if (update != nullptr)
+ update->CancelAllAsync();
+#endif
+}
+
+inline void
+Instance::FinishShutdownUpdate() noexcept
+{
+#ifdef ENABLE_DATABASE
+ delete update;
+#endif
+}
+
+inline void
+Instance::ShutdownDatabase() noexcept
+{
+#ifdef ENABLE_DATABASE
+ if (instance->database != nullptr) {
+ instance->database->Close();
+ delete instance->database;
+ }
+
+ delete instance->storage;
+#endif
+}
+
+inline void
+Instance::BeginShutdownPartitions() noexcept
+{
+ for (auto &partition : partitions) {
+ partition.pc.Kill();
+ partition.listener.reset();
+ }
+}
+
+inline void
+Instance::FinishShutdownPartitions() noexcept
+{
+ partitions.clear();
+}
+
void
Instance::OnIdle(unsigned flags)
{
@@ -426,7 +479,6 @@ try {
const ScopeNetInit net_init;
- io_thread_init();
config_global_init();
#ifdef ANDROID
@@ -441,7 +493,7 @@ try {
ReadConfigFile(config_path);
}
#else
- ParseCommandLine(argc, argv, &options);
+ ParseCommandLine(argc, argv, options);
#endif
const auto config = LoadConfig();
@@ -458,7 +510,8 @@ try {
#ifdef ENABLE_NEIGHBOR_PLUGINS
instance->neighbors = new NeighborGlue();
- instance->neighbors->Init(io_thread_get(), *instance);
+ instance->neighbors->Init(instance->io_thread.GetEventLoop(),
+ *instance);
if (instance->neighbors->IsEmpty()) {
delete instance->neighbors;
@@ -472,7 +525,7 @@ try {
initialize_decoder_and_player(config.replay_gain);
- listen_global_init(instance->event_loop, *instance->partition);
+ listen_global_init(*instance->partitions.front().listener);
#ifdef ENABLE_DAEMON
daemonize_set_user();
@@ -511,13 +564,15 @@ try {
command_init();
- instance->partition->outputs.Configure(instance->event_loop,
- config.replay_gain,
- instance->partition->pc);
- instance->partition->UpdateEffectiveReplayGainMode();
+ for (auto &partition : instance->partitions) {
+ partition.outputs.Configure(instance->rtio_thread.GetEventLoop(),
+ config.replay_gain,
+ partition.pc);
+ partition.UpdateEffectiveReplayGainMode();
+ }
client_manager_init();
- input_stream_global_init();
+ input_stream_global_init(instance->io_thread.GetEventLoop());
playlist_list_global_init();
#ifdef ENABLE_DAEMON
@@ -530,7 +585,8 @@ try {
SignalHandlersInit(instance->event_loop);
#endif
- io_thread_start();
+ instance->io_thread.Start();
+ instance->rtio_thread.Start();
#ifdef ENABLE_NEIGHBOR_PLUGINS
if (instance->neighbors != nullptr)
@@ -539,7 +595,8 @@ try {
ZeroconfInit(instance->event_loop);
- StartPlayerThread(instance->partition->pc);
+ for (auto &partition : instance->partitions)
+ StartPlayerThread(partition.pc);
#ifdef ENABLE_DATABASE
if (create_db) {
@@ -574,7 +631,8 @@ try {
/* enable all audio outputs (if not already done by
playlist_state_restore() */
- instance->partition->pc.LockUpdateAudio();
+ for (auto &partition : instance->partitions)
+ partition.pc.LockUpdateAudio();
#ifdef _WIN32
win32_app_started();
@@ -597,21 +655,17 @@ try {
/* cleanup */
-#if defined(ENABLE_DATABASE) && defined(ENABLE_INOTIFY)
- mpd_inotify_finish();
-
- if (instance->update != nullptr)
- instance->update->CancelAllAsync();
-#endif
+ instance->BeginShutdownUpdate();
if (instance->state_file != nullptr) {
instance->state_file->Write();
delete instance->state_file;
}
- instance->partition->pc.Kill();
ZeroconfDeinit();
- listen_global_finish();
+
+ instance->BeginShutdownPartitions();
+
delete instance->client_list;
#ifdef ENABLE_NEIGHBOR_PLUGINS
@@ -621,16 +675,8 @@ try {
}
#endif
-#ifdef ENABLE_DATABASE
- delete instance->update;
-
- if (instance->database != nullptr) {
- instance->database->Close();
- delete instance->database;
- }
-
- delete instance->storage;
-#endif
+ instance->FinishShutdownUpdate();
+ instance->ShutdownDatabase();
#ifdef ENABLE_SQLITE
sticker_global_finish();
@@ -645,14 +691,15 @@ try {
DeinitFS();
- delete instance->partition;
+ instance->FinishShutdownPartitions();
command_finish();
decoder_plugin_deinit_all();
#ifdef ENABLE_ARCHIVE
archive_plugin_deinit_all();
#endif
config_global_finish();
- io_thread_deinit();
+ instance->rtio_thread.Stop();
+ instance->io_thread.Stop();
#ifndef ANDROID
SignalHandlersFinish();
#endif
@@ -695,7 +742,7 @@ JNIEXPORT void JNICALL
Java_org_musicpd_Bridge_shutdown(JNIEnv *, jclass)
{
if (instance != nullptr)
- instance->Shutdown();
+ instance->Break();
}
#endif