aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c163
1 files changed, 116 insertions, 47 deletions
diff --git a/src/main.c b/src/main.c
index a500e2934..68f19f153 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2010 The Music Player Daemon Project
+ * Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,7 +20,9 @@
#include "config.h"
#include "main.h"
#include "daemon.h"
+#include "io_thread.h"
#include "client.h"
+#include "client_idle.h"
#include "idle.h"
#include "command.h"
#include "playlist.h"
@@ -37,11 +39,12 @@
#include "player_control.h"
#include "stats.h"
#include "sig_handlers.h"
-#include "audio.h"
+#include "audio_config.h"
#include "output_all.h"
#include "volume.h"
#include "log.h"
#include "permission.h"
+#include "pcm_resample.h"
#include "replay_gain_config.h"
#include "decoder_list.h"
#include "input_init.h"
@@ -94,31 +97,56 @@ GMainLoop *main_loop;
GCond *main_cond;
-static void
-glue_daemonize_init(const struct options *options)
+struct player_control *global_player_control;
+
+static bool
+glue_daemonize_init(const struct options *options, GError **error_r)
{
+ GError *error = NULL;
+
+ char *pid_file = config_dup_path(CONF_PID_FILE, &error);
+ if (pid_file == NULL && error != NULL) {
+ g_propagate_error(error_r, error);
+ return false;
+ }
+
daemonize_init(config_get_string(CONF_USER, NULL),
config_get_string(CONF_GROUP, NULL),
- config_get_path(CONF_PID_FILE));
+ pid_file);
+ g_free(pid_file);
if (options->kill)
daemonize_kill();
+
+ return true;
}
-static void
-glue_mapper_init(void)
+static bool
+glue_mapper_init(GError **error_r)
{
- const char *music_dir, *playlist_dir;
+ GError *error = NULL;
+ char *music_dir = config_dup_path(CONF_MUSIC_DIR, &error);
+ if (music_dir == NULL && error != NULL) {
+ g_propagate_error(error_r, error);
+ return false;
+ }
+
+ char *playlist_dir = config_dup_path(CONF_PLAYLIST_DIR, &error);
+ if (playlist_dir == NULL && error != NULL) {
+ g_propagate_error(error_r, error);
+ return false;
+ }
- music_dir = config_get_path(CONF_MUSIC_DIR);
#if GLIB_CHECK_VERSION(2,14,0)
if (music_dir == NULL)
- music_dir = g_get_user_special_dir(G_USER_DIRECTORY_MUSIC);
+ music_dir = g_strdup(g_get_user_special_dir(G_USER_DIRECTORY_MUSIC));
#endif
- playlist_dir = config_get_path(CONF_PLAYLIST_DIR);
-
mapper_init(music_dir, playlist_dir);
+
+ g_free(music_dir);
+ g_free(playlist_dir);
+ return true;
}
/**
@@ -129,38 +157,31 @@ glue_mapper_init(void)
static bool
glue_db_init_and_load(void)
{
- const char *path = config_get_path(CONF_DB_FILE);
- bool ret;
+ const struct config_param *path = config_get_param(CONF_DB_FILE);
+
GError *error = NULL;
+ bool ret;
if (!mapper_has_music_directory()) {
if (path != NULL)
g_message("Found " CONF_DB_FILE " setting without "
CONF_MUSIC_DIR " - disabling database");
- db_init(NULL);
+ db_init(NULL, NULL);
return true;
}
if (path == NULL)
MPD_ERROR(CONF_DB_FILE " setting missing");
- db_init(path);
+ if (!db_init(path, &error))
+ MPD_ERROR("%s", error->message);
ret = db_load(&error);
- if (!ret) {
- g_warning("Failed to load database: %s", error->message);
- g_error_free(error);
-
- if (!db_check())
- exit(EXIT_FAILURE);
-
- db_clear();
-
- /* run database update after daemonization */
- return false;
- }
+ if (!ret)
+ MPD_ERROR("%s", error->message);
- return true;
+ /* run database update after daemonization? */
+ return db_exists();
}
/**
@@ -170,20 +191,34 @@ static void
glue_sticker_init(void)
{
#ifdef ENABLE_SQLITE
- bool success;
GError *error = NULL;
+ char *sticker_file = config_dup_path(CONF_STICKER_FILE, &error);
+ if (sticker_file == NULL && error != NULL)
+ MPD_ERROR("%s", error->message);
- success = sticker_global_init(config_get_path(CONF_STICKER_FILE),
- &error);
- if (!success)
+ if (!sticker_global_init(config_get_string(CONF_STICKER_FILE, NULL),
+ &error))
MPD_ERROR("%s", error->message);
+
+ g_free(sticker_file);
#endif
}
-static void
-glue_state_file_init(void)
+static bool
+glue_state_file_init(GError **error_r)
{
- state_file_init(config_get_path(CONF_STATE_FILE));
+ GError *error = NULL;
+
+ char *path = config_dup_path(CONF_STATE_FILE, &error);
+ if (path == NULL && error != NULL) {
+ g_propagate_error(error_r, error);
+ return false;
+ }
+
+ state_file_init(path, global_player_control);
+ g_free(path);
+
+ return true;
}
/**
@@ -254,7 +289,7 @@ initialize_decoder_and_player(void)
if (buffered_before_play > buffered_chunks)
buffered_before_play = buffered_chunks;
- pc_init(buffered_chunks, buffered_before_play);
+ global_player_control = pc_new(buffered_chunks, buffered_before_play);
}
/**
@@ -308,6 +343,7 @@ int mpd_main(int argc, char *argv[])
/* enable GLib's thread safety code */
g_thread_init(NULL);
+ io_thread_init();
winsock_init();
idle_init();
dirvec_init();
@@ -322,11 +358,20 @@ int mpd_main(int argc, char *argv[])
return EXIT_FAILURE;
}
- glue_daemonize_init(&options);
+ if (!glue_daemonize_init(&options, &error)) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ return EXIT_FAILURE;
+ }
stats_global_init();
tag_lib_init();
- log_init(options.verbose, options.log_stderr);
+
+ if (!log_init(options.verbose, options.log_stderr, &error)) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ return EXIT_FAILURE;
+ }
success = listen_global_init(&error);
if (!success) {
@@ -346,13 +391,26 @@ int mpd_main(int argc, char *argv[])
event_pipe_register(PIPE_EVENT_SHUTDOWN, shutdown_event_emitted);
path_global_init();
- glue_mapper_init();
+
+ if (!glue_mapper_init(&error)) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ return EXIT_FAILURE;
+ }
+
initPermissions();
playlist_global_init();
spl_global_init();
#ifdef ENABLE_ARCHIVE
archive_plugin_init_all();
#endif
+
+ if (!pcm_resample_global_init(&error)) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ return EXIT_FAILURE;
+ }
+
decoder_plugin_init_all();
update_global_init();
@@ -364,7 +422,7 @@ int mpd_main(int argc, char *argv[])
initialize_decoder_and_player();
volume_init();
initAudioConfig();
- audio_output_all_init();
+ audio_output_all_init(global_player_control);
client_manager_init();
replay_gain_global_init();
@@ -382,9 +440,15 @@ int mpd_main(int argc, char *argv[])
initSigHandlers();
+ if (!io_thread_start(&error)) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ return EXIT_FAILURE;
+ }
+
initZeroconf();
- player_create();
+ player_create(global_player_control);
if (create_db) {
/* the database failed to load: recreate the
@@ -394,7 +458,11 @@ int mpd_main(int argc, char *argv[])
MPD_ERROR("directory update failed");
}
- glue_state_file_init();
+ if (!glue_state_file_init(&error)) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ return EXIT_FAILURE;
+ }
success = config_get_bool(CONF_AUTO_UPDATE, false);
#ifdef ENABLE_INOTIFY
@@ -410,7 +478,7 @@ int mpd_main(int argc, char *argv[])
/* enable all audio outputs (if not already done by
playlist_state_restore() */
- pc_update_audio();
+ pc_update_audio(global_player_control);
#ifdef WIN32
win32_app_started();
@@ -431,8 +499,8 @@ int mpd_main(int argc, char *argv[])
mpd_inotify_finish();
#endif
- state_file_finish();
- pc_kill();
+ state_file_finish(global_player_control);
+ pc_kill(global_player_control);
finishZeroconf();
client_manager_deinit();
listen_global_finish();
@@ -457,7 +525,7 @@ int mpd_main(int argc, char *argv[])
mapper_finish();
path_global_finish();
finishPermissions();
- pc_deinit();
+ pc_free(global_player_control);
command_finish();
update_global_finish();
decoder_plugin_deinit_all();
@@ -470,6 +538,7 @@ int mpd_main(int argc, char *argv[])
dirvec_deinit();
idle_deinit();
stats_global_finish();
+ io_thread_deinit();
daemonize_finish();
#ifdef WIN32
WSACleanup();