From 71a5c8b8196ad8c09d74f0cbc55cc127f401a242 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 29 May 2019 21:22:25 +0200 Subject: [PATCH] Main: allocate Instance on the stack --- src/Idle.cxx | 2 +- src/Main.cxx | 159 ++++++++++++++++++++-------------------- src/Main.hxx | 2 +- src/Mapper.cxx | 8 +- src/win32/Win32Main.cxx | 4 +- 5 files changed, 89 insertions(+), 86 deletions(-) diff --git a/src/Idle.cxx b/src/Idle.cxx index 14f2b396c..a1c7b3203 100644 --- a/src/Idle.cxx +++ b/src/Idle.cxx @@ -33,5 +33,5 @@ idle_add(unsigned flags) { assert(flags != 0); - instance->EmitIdle(flags); + global_instance->EmitIdle(flags); } diff --git a/src/Main.cxx b/src/Main.cxx index 13bb756c9..cf212fb45 100644 --- a/src/Main.cxx +++ b/src/Main.cxx @@ -129,7 +129,7 @@ Context *context; LogListener *logListener; #endif -Instance *instance; +Instance *global_instance; struct Config { ReplayGainConfig replay_gain; @@ -166,14 +166,15 @@ glue_mapper_init(const ConfigData &config) #ifdef ENABLE_DATABASE static void -InitStorage(const ConfigData &config, EventLoop &event_loop) +InitStorage(Instance &instance, EventLoop &event_loop, + const ConfigData &config) { auto storage = CreateConfiguredStorage(config, event_loop); if (storage == nullptr) return; CompositeStorage *composite = new CompositeStorage(); - instance->storage = composite; + instance.storage = composite; composite->Mount("", std::move(storage)); } @@ -183,18 +184,19 @@ InitStorage(const ConfigData &config, EventLoop &event_loop) * process has been daemonized. */ static bool -glue_db_init_and_load(const ConfigData &config) +glue_db_init_and_load(Instance &instance, const ConfigData &config) { - auto db = CreateConfiguredDatabase(config, instance->event_loop, - instance->io_thread.GetEventLoop(), - *instance); + auto db = CreateConfiguredDatabase(config, instance.event_loop, + instance.io_thread.GetEventLoop(), + instance); if (!db) return true; if (db->GetPlugin().RequireStorage()) { - InitStorage(config, instance->io_thread.GetEventLoop()); + InitStorage(instance, instance.io_thread.GetEventLoop(), + config); - if (instance->storage == nullptr) { + if (instance.storage == nullptr) { LogDefault(config_domain, "Found database setting without " "music_directory - disabling database"); @@ -213,25 +215,25 @@ glue_db_init_and_load(const ConfigData &config) std::throw_with_nested(std::runtime_error("Failed to open database plugin")); } - instance->database = std::move(db); + instance.database = std::move(db); - auto *sdb = dynamic_cast(instance->database.get()); + auto *sdb = dynamic_cast(instance.database.get()); if (sdb == nullptr) return true; - instance->update = new UpdateService(config, - instance->event_loop, *sdb, - static_cast(*instance->storage), - *instance); + instance.update = new UpdateService(config, + instance.event_loop, *sdb, + static_cast(*instance.storage), + instance); /* run database update after daemonization? */ return sdb->FileExists(); } static bool -InitDatabaseAndStorage(const ConfigData &config) +InitDatabaseAndStorage(Instance &instance, const ConfigData &config) { - const bool create_db = !glue_db_init_and_load(config); + const bool create_db = !glue_db_init_and_load(instance, config); return create_db; } @@ -255,23 +257,24 @@ LoadStickerDatabase(const ConfigData &config) #endif static void -glue_state_file_init(const ConfigData &raw_config) +glue_state_file_init(Instance &instance, const ConfigData &raw_config) { StateFileConfig config(raw_config); if (!config.IsEnabled()) return; - instance->state_file = new StateFile(std::move(config), - instance->partitions.front(), - instance->event_loop); - instance->state_file->Read(); + instance.state_file = new StateFile(std::move(config), + instance.partitions.front(), + instance.event_loop); + instance.state_file->Read(); } /** * Initialize the decoder and player core, including the music pipe. */ static void -initialize_decoder_and_player(const ConfigData &config, +initialize_decoder_and_player(Instance &instance, + const ConfigData &config, const ReplayGainConfig &replay_gain_config) { const ConfigParam *param; @@ -318,13 +321,13 @@ initialize_decoder_and_player(const ConfigData &config, } } - instance->partitions.emplace_back(*instance, - "default", - max_length, - buffered_chunks, - configured_audio_format, - replay_gain_config); - auto &partition = instance->partitions.back(); + instance.partitions.emplace_back(instance, + "default", + max_length, + buffered_chunks, + configured_audio_format, + replay_gain_config); + auto &partition = instance.partitions.back(); try { param = config.GetParam(ConfigOption::REPLAYGAIN); @@ -386,7 +389,8 @@ main(int argc, char *argv[]) noexcept #endif static void -mpd_main_after_fork(const ConfigData &raw_config, +mpd_main_after_fork(Instance &instance, + const ConfigData &raw_config, const Config &config); static inline void @@ -422,29 +426,27 @@ MainConfigured(const struct options &options, const ConfigData &raw_config) log_init(raw_config, options.verbose, options.log_stderr); - instance = new Instance(); - AtScopeExit() { - delete instance; - instance = nullptr; - }; + Instance instance; + global_instance = &instance; #ifdef ENABLE_NEIGHBOR_PLUGINS - instance->neighbors = std::make_unique(); - instance->neighbors->Init(raw_config, - instance->io_thread.GetEventLoop(), - *instance); + instance.neighbors = std::make_unique(); + instance.neighbors->Init(raw_config, + instance.io_thread.GetEventLoop(), + instance); - if (instance->neighbors->IsEmpty()) - instance->neighbors.reset(); + if (instance.neighbors->IsEmpty()) + instance.neighbors.reset(); #endif const unsigned max_clients = raw_config.GetPositive(ConfigOption::MAX_CONN, 10); - instance->client_list = new ClientList(max_clients); + instance.client_list = new ClientList(max_clients); - initialize_decoder_and_player(raw_config, config.replay_gain); + initialize_decoder_and_player(instance, + raw_config, config.replay_gain); - listen_global_init(raw_config, *instance->partitions.front().listener); + listen_global_init(raw_config, *instance.partitions.front().listener); #ifdef ENABLE_DAEMON daemonize_set_user(); @@ -452,7 +454,7 @@ MainConfigured(const struct options &options, const ConfigData &raw_config) AtScopeExit() { daemonize_finish(); }; #endif - mpd_main_after_fork(raw_config, config); + mpd_main_after_fork(instance, raw_config, config); } #ifndef ANDROID @@ -484,7 +486,8 @@ int mpd_main(int argc, char *argv[]) noexcept #endif /* !ANDROID */ static void -mpd_main_after_fork(const ConfigData &raw_config, const Config &config) +mpd_main_after_fork(Instance &instance, + const ConfigData &raw_config, const Config &config) { ConfigureFS(raw_config); AtScopeExit() { DeinitFS(); }; @@ -502,17 +505,17 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config) const ScopeDecoderPluginsInit decoder_plugins_init(raw_config); #ifdef ENABLE_DATABASE - const bool create_db = InitDatabaseAndStorage(raw_config); + const bool create_db = InitDatabaseAndStorage(instance, raw_config); #endif #ifdef ENABLE_SQLITE - instance->sticker_database = LoadStickerDatabase(raw_config); + instance.sticker_database = LoadStickerDatabase(raw_config); #endif command_init(); - for (auto &partition : instance->partitions) { - partition.outputs.Configure(instance->rtio_thread.GetEventLoop(), + for (auto &partition : instance.partitions) { + partition.outputs.Configure(instance.rtio_thread.GetEventLoop(), raw_config, config.replay_gain, partition.pc); @@ -521,7 +524,7 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config) client_manager_init(raw_config); const ScopeInputPluginsInit input_plugins_init(raw_config, - instance->io_thread.GetEventLoop()); + instance.io_thread.GetEventLoop()); const ScopePlaylistPluginsInit playlist_plugins_init(raw_config); #ifdef ENABLE_DAEMON @@ -531,42 +534,42 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config) #ifndef ANDROID setup_log_output(); - const ScopeSignalHandlersInit signal_handlers_init(instance->event_loop); + const ScopeSignalHandlersInit signal_handlers_init(instance.event_loop); #endif - instance->io_thread.Start(); - instance->rtio_thread.Start(); + instance.io_thread.Start(); + instance.rtio_thread.Start(); #ifdef ENABLE_NEIGHBOR_PLUGINS - if (instance->neighbors != nullptr) - instance->neighbors->Open(); + if (instance.neighbors != nullptr) + instance.neighbors->Open(); - AtScopeExit() { - if (instance->neighbors != nullptr) - instance->neighbors->Close(); + AtScopeExit(&instance) { + if (instance.neighbors != nullptr) + instance.neighbors->Close(); }; #endif - ZeroconfInit(raw_config, instance->event_loop); + ZeroconfInit(raw_config, instance.event_loop); #ifdef ENABLE_DATABASE if (create_db) { /* the database failed to load: recreate the database */ - instance->update->Enqueue("", true); + instance.update->Enqueue("", true); } #endif - glue_state_file_init(raw_config); + glue_state_file_init(instance, raw_config); #ifdef ENABLE_DATABASE if (raw_config.GetBool(ConfigOption::AUTO_UPDATE, false)) { #ifdef ENABLE_INOTIFY - if (instance->storage != nullptr && - instance->update != nullptr) - mpd_inotify_init(instance->event_loop, - *instance->storage, - *instance->update, + if (instance.storage != nullptr && + instance.update != nullptr) + mpd_inotify_init(instance.event_loop, + *instance.storage, + *instance.update, raw_config.GetUnsigned(ConfigOption::AUTO_UPDATE_DEPTH, INT_MAX)); #else @@ -580,7 +583,7 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config) /* enable all audio outputs (if not already done by playlist_state_restore() */ - for (auto &partition : instance->partitions) + for (auto &partition : instance.partitions) partition.pc.LockUpdateAudio(); #ifdef _WIN32 @@ -596,7 +599,7 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config) #endif /* run the main loop */ - instance->event_loop.Run(); + instance.event_loop.Run(); #ifdef _WIN32 win32_app_stopping(); @@ -604,18 +607,18 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config) /* cleanup */ - instance->BeginShutdownUpdate(); + instance.BeginShutdownUpdate(); - if (instance->state_file != nullptr) { - instance->state_file->Write(); - delete instance->state_file; + if (instance.state_file != nullptr) { + instance.state_file->Write(); + delete instance.state_file; } ZeroconfDeinit(); - instance->BeginShutdownPartitions(); + instance.BeginShutdownPartitions(); - delete instance->client_list; + delete instance.client_list; } #ifdef ANDROID @@ -665,8 +668,8 @@ gcc_visibility_default JNIEXPORT void JNICALL Java_org_musicpd_Bridge_shutdown(JNIEnv *, jclass) { - if (instance != nullptr) - instance->Break(); + if (global_instance != nullptr) + global_instance->Break(); } #endif diff --git a/src/Main.hxx b/src/Main.hxx index 53efafe0f..9d4c544e2 100644 --- a/src/Main.hxx +++ b/src/Main.hxx @@ -31,7 +31,7 @@ extern Context *context; extern LogListener *logListener; #endif -extern Instance *instance; +extern Instance *global_instance; #ifndef ANDROID diff --git a/src/Mapper.cxx b/src/Mapper.cxx index c5c3076d0..61a068352 100644 --- a/src/Mapper.cxx +++ b/src/Mapper.cxx @@ -66,10 +66,10 @@ map_uri_fs(const char *uri) noexcept assert(uri != nullptr); assert(*uri != '/'); - if (instance->storage == nullptr) + if (global_instance->storage == nullptr) return nullptr; - const auto music_dir_fs = instance->storage->MapFS(""); + const auto music_dir_fs = global_instance->storage->MapFS(""); if (music_dir_fs.IsNull()) return nullptr; @@ -84,10 +84,10 @@ std::string map_fs_to_utf8(Path path_fs) noexcept { if (path_fs.IsAbsolute()) { - if (instance->storage == nullptr) + if (global_instance->storage == nullptr) return std::string(); - const auto music_dir_fs = instance->storage->MapFS(""); + const auto music_dir_fs = global_instance->storage->MapFS(""); if (music_dir_fs.IsNull()) return std::string(); diff --git a/src/win32/Win32Main.cxx b/src/win32/Win32Main.cxx index 4f66ecb53..b7a57b268 100644 --- a/src/win32/Win32Main.cxx +++ b/src/win32/Win32Main.cxx @@ -70,7 +70,7 @@ service_dispatcher(gcc_unused DWORD control, gcc_unused DWORD event_type, switch (control) { case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_STOP: - instance->Break(); + global_instance->Break(); return NO_ERROR; default: return NO_ERROR; @@ -106,7 +106,7 @@ console_handler(DWORD event) // regardless our thread is still active. // If this did not happen within 3 seconds // let's shutdown anyway. - instance->Break(); + global_instance->Break(); // Under debugger it's better to wait indefinitely // to allow debugging of shutdown code. Sleep(IsDebuggerPresent() ? INFINITE : 3000);