diff options
Diffstat (limited to 'src/Main.cxx')
-rw-r--r-- | src/Main.cxx | 145 |
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 |