Commit 71a5c8b8 authored by Max Kellermann's avatar Max Kellermann

Main: allocate Instance on the stack

parent 620a39af
...@@ -33,5 +33,5 @@ idle_add(unsigned flags) ...@@ -33,5 +33,5 @@ idle_add(unsigned flags)
{ {
assert(flags != 0); assert(flags != 0);
instance->EmitIdle(flags); global_instance->EmitIdle(flags);
} }
...@@ -129,7 +129,7 @@ Context *context; ...@@ -129,7 +129,7 @@ Context *context;
LogListener *logListener; LogListener *logListener;
#endif #endif
Instance *instance; Instance *global_instance;
struct Config { struct Config {
ReplayGainConfig replay_gain; ReplayGainConfig replay_gain;
...@@ -166,14 +166,15 @@ glue_mapper_init(const ConfigData &config) ...@@ -166,14 +166,15 @@ glue_mapper_init(const ConfigData &config)
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
static void static void
InitStorage(const ConfigData &config, EventLoop &event_loop) InitStorage(Instance &instance, EventLoop &event_loop,
const ConfigData &config)
{ {
auto storage = CreateConfiguredStorage(config, event_loop); auto storage = CreateConfiguredStorage(config, event_loop);
if (storage == nullptr) if (storage == nullptr)
return; return;
CompositeStorage *composite = new CompositeStorage(); CompositeStorage *composite = new CompositeStorage();
instance->storage = composite; instance.storage = composite;
composite->Mount("", std::move(storage)); composite->Mount("", std::move(storage));
} }
...@@ -183,18 +184,19 @@ InitStorage(const ConfigData &config, EventLoop &event_loop) ...@@ -183,18 +184,19 @@ InitStorage(const ConfigData &config, EventLoop &event_loop)
* process has been daemonized. * process has been daemonized.
*/ */
static bool 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, auto db = CreateConfiguredDatabase(config, instance.event_loop,
instance->io_thread.GetEventLoop(), instance.io_thread.GetEventLoop(),
*instance); instance);
if (!db) if (!db)
return true; return true;
if (db->GetPlugin().RequireStorage()) { 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, LogDefault(config_domain,
"Found database setting without " "Found database setting without "
"music_directory - disabling database"); "music_directory - disabling database");
...@@ -213,25 +215,25 @@ glue_db_init_and_load(const ConfigData &config) ...@@ -213,25 +215,25 @@ glue_db_init_and_load(const ConfigData &config)
std::throw_with_nested(std::runtime_error("Failed to open database plugin")); 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<SimpleDatabase *>(instance->database.get()); auto *sdb = dynamic_cast<SimpleDatabase *>(instance.database.get());
if (sdb == nullptr) if (sdb == nullptr)
return true; return true;
instance->update = new UpdateService(config, instance.update = new UpdateService(config,
instance->event_loop, *sdb, instance.event_loop, *sdb,
static_cast<CompositeStorage &>(*instance->storage), static_cast<CompositeStorage &>(*instance.storage),
*instance); instance);
/* run database update after daemonization? */ /* run database update after daemonization? */
return sdb->FileExists(); return sdb->FileExists();
} }
static bool 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; return create_db;
} }
...@@ -255,23 +257,24 @@ LoadStickerDatabase(const ConfigData &config) ...@@ -255,23 +257,24 @@ LoadStickerDatabase(const ConfigData &config)
#endif #endif
static void static void
glue_state_file_init(const ConfigData &raw_config) glue_state_file_init(Instance &instance, const ConfigData &raw_config)
{ {
StateFileConfig config(raw_config); StateFileConfig config(raw_config);
if (!config.IsEnabled()) if (!config.IsEnabled())
return; return;
instance->state_file = new StateFile(std::move(config), instance.state_file = new StateFile(std::move(config),
instance->partitions.front(), instance.partitions.front(),
instance->event_loop); instance.event_loop);
instance->state_file->Read(); instance.state_file->Read();
} }
/** /**
* Initialize the decoder and player core, including the music pipe. * Initialize the decoder and player core, including the music pipe.
*/ */
static void static void
initialize_decoder_and_player(const ConfigData &config, initialize_decoder_and_player(Instance &instance,
const ConfigData &config,
const ReplayGainConfig &replay_gain_config) const ReplayGainConfig &replay_gain_config)
{ {
const ConfigParam *param; const ConfigParam *param;
...@@ -318,13 +321,13 @@ initialize_decoder_and_player(const ConfigData &config, ...@@ -318,13 +321,13 @@ initialize_decoder_and_player(const ConfigData &config,
} }
} }
instance->partitions.emplace_back(*instance, instance.partitions.emplace_back(instance,
"default", "default",
max_length, max_length,
buffered_chunks, buffered_chunks,
configured_audio_format, configured_audio_format,
replay_gain_config); replay_gain_config);
auto &partition = instance->partitions.back(); auto &partition = instance.partitions.back();
try { try {
param = config.GetParam(ConfigOption::REPLAYGAIN); param = config.GetParam(ConfigOption::REPLAYGAIN);
...@@ -386,7 +389,8 @@ main(int argc, char *argv[]) noexcept ...@@ -386,7 +389,8 @@ main(int argc, char *argv[]) noexcept
#endif #endif
static void static void
mpd_main_after_fork(const ConfigData &raw_config, mpd_main_after_fork(Instance &instance,
const ConfigData &raw_config,
const Config &config); const Config &config);
static inline void static inline void
...@@ -422,29 +426,27 @@ MainConfigured(const struct options &options, const ConfigData &raw_config) ...@@ -422,29 +426,27 @@ MainConfigured(const struct options &options, const ConfigData &raw_config)
log_init(raw_config, options.verbose, options.log_stderr); log_init(raw_config, options.verbose, options.log_stderr);
instance = new Instance(); Instance instance;
AtScopeExit() { global_instance = &instance;
delete instance;
instance = nullptr;
};
#ifdef ENABLE_NEIGHBOR_PLUGINS #ifdef ENABLE_NEIGHBOR_PLUGINS
instance->neighbors = std::make_unique<NeighborGlue>(); instance.neighbors = std::make_unique<NeighborGlue>();
instance->neighbors->Init(raw_config, instance.neighbors->Init(raw_config,
instance->io_thread.GetEventLoop(), instance.io_thread.GetEventLoop(),
*instance); instance);
if (instance->neighbors->IsEmpty()) if (instance.neighbors->IsEmpty())
instance->neighbors.reset(); instance.neighbors.reset();
#endif #endif
const unsigned max_clients = const unsigned max_clients =
raw_config.GetPositive(ConfigOption::MAX_CONN, 10); 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 #ifdef ENABLE_DAEMON
daemonize_set_user(); daemonize_set_user();
...@@ -452,7 +454,7 @@ MainConfigured(const struct options &options, const ConfigData &raw_config) ...@@ -452,7 +454,7 @@ MainConfigured(const struct options &options, const ConfigData &raw_config)
AtScopeExit() { daemonize_finish(); }; AtScopeExit() { daemonize_finish(); };
#endif #endif
mpd_main_after_fork(raw_config, config); mpd_main_after_fork(instance, raw_config, config);
} }
#ifndef ANDROID #ifndef ANDROID
...@@ -484,7 +486,8 @@ int mpd_main(int argc, char *argv[]) noexcept ...@@ -484,7 +486,8 @@ int mpd_main(int argc, char *argv[]) noexcept
#endif /* !ANDROID */ #endif /* !ANDROID */
static void 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); ConfigureFS(raw_config);
AtScopeExit() { DeinitFS(); }; AtScopeExit() { DeinitFS(); };
...@@ -502,17 +505,17 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config) ...@@ -502,17 +505,17 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
const ScopeDecoderPluginsInit decoder_plugins_init(raw_config); const ScopeDecoderPluginsInit decoder_plugins_init(raw_config);
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
const bool create_db = InitDatabaseAndStorage(raw_config); const bool create_db = InitDatabaseAndStorage(instance, raw_config);
#endif #endif
#ifdef ENABLE_SQLITE #ifdef ENABLE_SQLITE
instance->sticker_database = LoadStickerDatabase(raw_config); instance.sticker_database = LoadStickerDatabase(raw_config);
#endif #endif
command_init(); command_init();
for (auto &partition : instance->partitions) { for (auto &partition : instance.partitions) {
partition.outputs.Configure(instance->rtio_thread.GetEventLoop(), partition.outputs.Configure(instance.rtio_thread.GetEventLoop(),
raw_config, raw_config,
config.replay_gain, config.replay_gain,
partition.pc); partition.pc);
...@@ -521,7 +524,7 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config) ...@@ -521,7 +524,7 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
client_manager_init(raw_config); client_manager_init(raw_config);
const ScopeInputPluginsInit input_plugins_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); const ScopePlaylistPluginsInit playlist_plugins_init(raw_config);
#ifdef ENABLE_DAEMON #ifdef ENABLE_DAEMON
...@@ -531,42 +534,42 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config) ...@@ -531,42 +534,42 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
#ifndef ANDROID #ifndef ANDROID
setup_log_output(); setup_log_output();
const ScopeSignalHandlersInit signal_handlers_init(instance->event_loop); const ScopeSignalHandlersInit signal_handlers_init(instance.event_loop);
#endif #endif
instance->io_thread.Start(); instance.io_thread.Start();
instance->rtio_thread.Start(); instance.rtio_thread.Start();
#ifdef ENABLE_NEIGHBOR_PLUGINS #ifdef ENABLE_NEIGHBOR_PLUGINS
if (instance->neighbors != nullptr) if (instance.neighbors != nullptr)
instance->neighbors->Open(); instance.neighbors->Open();
AtScopeExit() { AtScopeExit(&instance) {
if (instance->neighbors != nullptr) if (instance.neighbors != nullptr)
instance->neighbors->Close(); instance.neighbors->Close();
}; };
#endif #endif
ZeroconfInit(raw_config, instance->event_loop); ZeroconfInit(raw_config, instance.event_loop);
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
if (create_db) { if (create_db) {
/* the database failed to load: recreate the /* the database failed to load: recreate the
database */ database */
instance->update->Enqueue("", true); instance.update->Enqueue("", true);
} }
#endif #endif
glue_state_file_init(raw_config); glue_state_file_init(instance, raw_config);
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
if (raw_config.GetBool(ConfigOption::AUTO_UPDATE, false)) { if (raw_config.GetBool(ConfigOption::AUTO_UPDATE, false)) {
#ifdef ENABLE_INOTIFY #ifdef ENABLE_INOTIFY
if (instance->storage != nullptr && if (instance.storage != nullptr &&
instance->update != nullptr) instance.update != nullptr)
mpd_inotify_init(instance->event_loop, mpd_inotify_init(instance.event_loop,
*instance->storage, *instance.storage,
*instance->update, *instance.update,
raw_config.GetUnsigned(ConfigOption::AUTO_UPDATE_DEPTH, raw_config.GetUnsigned(ConfigOption::AUTO_UPDATE_DEPTH,
INT_MAX)); INT_MAX));
#else #else
...@@ -580,7 +583,7 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config) ...@@ -580,7 +583,7 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
/* enable all audio outputs (if not already done by /* enable all audio outputs (if not already done by
playlist_state_restore() */ playlist_state_restore() */
for (auto &partition : instance->partitions) for (auto &partition : instance.partitions)
partition.pc.LockUpdateAudio(); partition.pc.LockUpdateAudio();
#ifdef _WIN32 #ifdef _WIN32
...@@ -596,7 +599,7 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config) ...@@ -596,7 +599,7 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
#endif #endif
/* run the main loop */ /* run the main loop */
instance->event_loop.Run(); instance.event_loop.Run();
#ifdef _WIN32 #ifdef _WIN32
win32_app_stopping(); win32_app_stopping();
...@@ -604,18 +607,18 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config) ...@@ -604,18 +607,18 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
/* cleanup */ /* cleanup */
instance->BeginShutdownUpdate(); instance.BeginShutdownUpdate();
if (instance->state_file != nullptr) { if (instance.state_file != nullptr) {
instance->state_file->Write(); instance.state_file->Write();
delete instance->state_file; delete instance.state_file;
} }
ZeroconfDeinit(); ZeroconfDeinit();
instance->BeginShutdownPartitions(); instance.BeginShutdownPartitions();
delete instance->client_list; delete instance.client_list;
} }
#ifdef ANDROID #ifdef ANDROID
...@@ -665,8 +668,8 @@ gcc_visibility_default ...@@ -665,8 +668,8 @@ gcc_visibility_default
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_org_musicpd_Bridge_shutdown(JNIEnv *, jclass) Java_org_musicpd_Bridge_shutdown(JNIEnv *, jclass)
{ {
if (instance != nullptr) if (global_instance != nullptr)
instance->Break(); global_instance->Break();
} }
#endif #endif
...@@ -31,7 +31,7 @@ extern Context *context; ...@@ -31,7 +31,7 @@ extern Context *context;
extern LogListener *logListener; extern LogListener *logListener;
#endif #endif
extern Instance *instance; extern Instance *global_instance;
#ifndef ANDROID #ifndef ANDROID
......
...@@ -66,10 +66,10 @@ map_uri_fs(const char *uri) noexcept ...@@ -66,10 +66,10 @@ map_uri_fs(const char *uri) noexcept
assert(uri != nullptr); assert(uri != nullptr);
assert(*uri != '/'); assert(*uri != '/');
if (instance->storage == nullptr) if (global_instance->storage == nullptr)
return 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()) if (music_dir_fs.IsNull())
return nullptr; return nullptr;
...@@ -84,10 +84,10 @@ std::string ...@@ -84,10 +84,10 @@ std::string
map_fs_to_utf8(Path path_fs) noexcept map_fs_to_utf8(Path path_fs) noexcept
{ {
if (path_fs.IsAbsolute()) { if (path_fs.IsAbsolute()) {
if (instance->storage == nullptr) if (global_instance->storage == nullptr)
return std::string(); 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()) if (music_dir_fs.IsNull())
return std::string(); return std::string();
......
...@@ -70,7 +70,7 @@ service_dispatcher(gcc_unused DWORD control, gcc_unused DWORD event_type, ...@@ -70,7 +70,7 @@ service_dispatcher(gcc_unused DWORD control, gcc_unused DWORD event_type,
switch (control) { switch (control) {
case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_STOP:
instance->Break(); global_instance->Break();
return NO_ERROR; return NO_ERROR;
default: default:
return NO_ERROR; return NO_ERROR;
...@@ -106,7 +106,7 @@ console_handler(DWORD event) ...@@ -106,7 +106,7 @@ console_handler(DWORD event)
// regardless our thread is still active. // regardless our thread is still active.
// If this did not happen within 3 seconds // If this did not happen within 3 seconds
// let's shutdown anyway. // let's shutdown anyway.
instance->Break(); global_instance->Break();
// Under debugger it's better to wait indefinitely // Under debugger it's better to wait indefinitely
// to allow debugging of shutdown code. // to allow debugging of shutdown code.
Sleep(IsDebuggerPresent() ? INFINITE : 3000); Sleep(IsDebuggerPresent() ? INFINITE : 3000);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment