aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-01-04 22:42:05 +0100
committerMax Kellermann <max@duempel.org>2013-01-05 02:43:00 +0100
commitd536944beb783ec098aa6215fc94d8e60cfd310d (patch)
treeb86702e5d0142cfe3c8bb22a9a4f8ea2034cb51b
parent1a8ef3cdab39234e91fe9d91dad2ae004e4537dc (diff)
downloadmpd-d536944beb783ec098aa6215fc94d8e60cfd310d.tar.gz
mpd-d536944beb783ec098aa6215fc94d8e60cfd310d.tar.xz
mpd-d536944beb783ec098aa6215fc94d8e60cfd310d.zip
Partition: new class, container for Playlist and PlayerControl
This is the beginning of multi-player support. There will be support for multiple Partition objects in one MPD process.
-rw-r--r--Makefile.am1
-rw-r--r--src/Listen.cxx4
-rw-r--r--src/Main.cxx34
-rw-r--r--src/Main.hxx2
-rw-r--r--src/Partition.hxx47
-rw-r--r--src/Playlist.hxx8
-rw-r--r--src/PlaylistGlobal.cxx18
-rw-r--r--src/StateFile.cxx34
-rw-r--r--src/StateFile.hxx6
-rw-r--r--src/UpdateGlue.cxx4
-rw-r--r--src/UpdateRemove.cxx5
11 files changed, 103 insertions, 60 deletions
diff --git a/Makefile.am b/Makefile.am
index ebb7fdf2d..d4761c950 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -262,6 +262,7 @@ src_mpd_SOURCES = \
src/path.c \
src/Mapper.cxx src/Mapper.hxx \
src/page.c \
+ src/Partition.hxx \
src/Permission.cxx src/Permission.hxx \
src/PlayerThread.cxx src/PlayerThread.hxx \
src/PlayerControl.cxx src/PlayerControl.hxx \
diff --git a/src/Listen.cxx b/src/Listen.cxx
index 8741da9c2..3ea9bae9a 100644
--- a/src/Listen.cxx
+++ b/src/Listen.cxx
@@ -20,7 +20,7 @@
#include "config.h"
#include "Listen.hxx"
#include "Main.hxx"
-#include "Playlist.hxx"
+#include "Partition.hxx"
#include "Client.hxx"
extern "C" {
@@ -47,7 +47,7 @@ static void
listen_callback(int fd, const struct sockaddr *address,
size_t address_length, int uid, G_GNUC_UNUSED void *ctx)
{
- client_new(g_playlist, global_player_control,
+ client_new(global_partition->playlist, &global_partition->pc,
fd, address, address_length, uid);
}
diff --git a/src/Main.cxx b/src/Main.cxx
index a8f6d55ee..371602247 100644
--- a/src/Main.cxx
+++ b/src/Main.cxx
@@ -20,9 +20,7 @@
#include "config.h"
#include "Main.hxx"
#include "CommandLine.hxx"
-#include "Playlist.hxx"
#include "PlaylistFile.hxx"
-#include "PlayerControl.hxx"
#include "UpdateGlue.hxx"
#include "MusicChunk.hxx"
#include "StateFile.hxx"
@@ -35,6 +33,7 @@
#include "ClientIdle.hxx"
#include "Client.hxx"
#include "AllCommands.hxx"
+#include "Partition.hxx"
extern "C" {
#include "daemon.h"
@@ -100,7 +99,7 @@ GMainLoop *main_loop;
GCond *main_cond;
-struct player_control *global_player_control;
+Partition *global_partition;
static bool
glue_daemonize_init(const struct options *options, GError **error_r)
@@ -231,7 +230,7 @@ glue_state_file_init(GError **error_r)
return false;
}
- state_file_init(path, global_player_control);
+ state_file_init(path, *global_partition);
g_free(path);
return true;
@@ -306,8 +305,13 @@ initialize_decoder_and_player(void)
if (buffered_before_play > buffered_chunks)
buffered_before_play = buffered_chunks;
- global_player_control = new player_control(buffered_chunks,
- buffered_before_play);
+ const unsigned max_length =
+ config_get_positive(CONF_MAX_PLAYLIST_LENGTH,
+ DEFAULT_PLAYLIST_MAX_LENGTH);
+
+ global_partition = new Partition(max_length,
+ buffered_chunks,
+ buffered_before_play);
}
/**
@@ -414,8 +418,7 @@ int mpd_main(int argc, char *argv[])
}
initPermissions();
- playlist_global_init(config_get_positive(CONF_MAX_PLAYLIST_LENGTH,
- DEFAULT_PLAYLIST_MAX_LENGTH));
+ playlist_global_init();
spl_global_init();
#ifdef ENABLE_ARCHIVE
archive_plugin_init_all();
@@ -438,7 +441,7 @@ int mpd_main(int argc, char *argv[])
initialize_decoder_and_player();
volume_init();
initAudioConfig();
- audio_output_all_init(global_player_control);
+ audio_output_all_init(&global_partition->pc);
client_manager_init();
replay_gain_global_init();
@@ -464,7 +467,7 @@ int mpd_main(int argc, char *argv[])
initZeroconf();
- player_create(global_player_control);
+ player_create(&global_partition->pc);
if (create_db) {
/* the database failed to load: recreate the
@@ -480,7 +483,7 @@ int mpd_main(int argc, char *argv[])
return EXIT_FAILURE;
}
- audio_output_all_set_replay_gain_mode(replay_gain_get_real_mode(g_playlist.queue.random));
+ audio_output_all_set_replay_gain_mode(replay_gain_get_real_mode(global_partition->playlist.queue.random));
success = config_get_bool(CONF_AUTO_UPDATE, false);
#ifdef ENABLE_INOTIFY
@@ -496,7 +499,7 @@ int mpd_main(int argc, char *argv[])
/* enable all audio outputs (if not already done by
playlist_state_restore() */
- pc_update_audio(global_player_control);
+ pc_update_audio(&global_partition->pc);
#ifdef WIN32
win32_app_started();
@@ -517,12 +520,11 @@ int mpd_main(int argc, char *argv[])
mpd_inotify_finish();
#endif
- state_file_finish(global_player_control);
- pc_kill(global_player_control);
+ state_file_finish(*global_partition);
+ pc_kill(&global_partition->pc);
finishZeroconf();
client_manager_deinit();
listen_global_finish();
- playlist_global_finish();
start = clock();
DatabaseGlobalDeinit();
@@ -542,7 +544,7 @@ int mpd_main(int argc, char *argv[])
volume_finish();
mapper_finish();
path_global_finish();
- delete global_player_control;
+ delete global_partition;
command_finish();
update_global_finish();
decoder_plugin_deinit_all();
diff --git a/src/Main.hxx b/src/Main.hxx
index 54916ff4b..6d61843a8 100644
--- a/src/Main.hxx
+++ b/src/Main.hxx
@@ -28,7 +28,7 @@ extern GMainLoop *main_loop;
extern GCond *main_cond;
-extern struct player_control *global_player_control;
+extern struct Partition *global_partition;
/**
* A entry point for application.
diff --git a/src/Partition.hxx b/src/Partition.hxx
new file mode 100644
index 000000000..b91a4b6f9
--- /dev/null
+++ b/src/Partition.hxx
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_PARTITION_HXX
+#define MPD_PARTITION_HXX
+
+#include "Playlist.hxx"
+#include "PlayerControl.hxx"
+
+/**
+ * A partition of the Music Player Daemon. It is a separate unit with
+ * a playlist, a player, outputs etc.
+ */
+struct Partition {
+ struct playlist playlist;
+
+ player_control pc;
+
+ Partition(unsigned max_length,
+ unsigned buffer_chunks,
+ unsigned buffered_before_play)
+ :pc(buffer_chunks, buffered_before_play) {
+ playlist_init(&playlist, max_length);
+ }
+
+ ~Partition() {
+ playlist_finish(&playlist);
+ }
+};
+
+#endif
diff --git a/src/Playlist.hxx b/src/Playlist.hxx
index 3256f6422..163d17afe 100644
--- a/src/Playlist.hxx
+++ b/src/Playlist.hxx
@@ -70,14 +70,8 @@ struct playlist {
int queued;
};
-/** the global playlist object */
-extern struct playlist g_playlist;
-
-void
-playlist_global_init(unsigned max_length);
-
void
-playlist_global_finish(void);
+playlist_global_init();
void
playlist_init(struct playlist *playlist, unsigned max_length);
diff --git a/src/PlaylistGlobal.cxx b/src/PlaylistGlobal.cxx
index d9685a2be..92572cde9 100644
--- a/src/PlaylistGlobal.cxx
+++ b/src/PlaylistGlobal.cxx
@@ -25,36 +25,28 @@
#include "config.h"
#include "Playlist.hxx"
#include "Main.hxx"
+#include "Partition.hxx"
extern "C" {
#include "event_pipe.h"
}
-struct playlist g_playlist;
-
static void
playlist_tag_event(void)
{
- playlist_tag_changed(&g_playlist);
+ playlist_tag_changed(&global_partition->playlist);
}
static void
playlist_event(void)
{
- playlist_sync(&g_playlist, global_player_control);
+ playlist_sync(&global_partition->playlist,
+ &global_partition->pc);
}
void
-playlist_global_init(unsigned max_length)
+playlist_global_init()
{
- playlist_init(&g_playlist, max_length);
-
event_pipe_register(PIPE_EVENT_TAG, playlist_tag_event);
event_pipe_register(PIPE_EVENT_PLAYLIST, playlist_event);
}
-
-void
-playlist_global_finish(void)
-{
- playlist_finish(&g_playlist);
-}
diff --git a/src/StateFile.cxx b/src/StateFile.cxx
index db6635025..1d77b77de 100644
--- a/src/StateFile.cxx
+++ b/src/StateFile.cxx
@@ -20,9 +20,9 @@
#include "config.h"
#include "StateFile.hxx"
#include "OutputState.hxx"
-#include "Playlist.hxx"
#include "PlaylistState.hxx"
#include "TextFile.hxx"
+#include "Partition.hxx"
extern "C" {
#include "volume.h"
@@ -49,7 +49,7 @@ static unsigned prev_volume_version, prev_output_version,
prev_playlist_version;
static void
-state_file_write(struct player_control *pc)
+state_file_write(Partition &partition)
{
FILE *fp;
@@ -66,17 +66,18 @@ state_file_write(struct player_control *pc)
save_sw_volume_state(fp);
audio_output_state_save(fp);
- playlist_state_save(fp, &g_playlist, pc);
+ playlist_state_save(fp, &partition.playlist, &partition.pc);
fclose(fp);
prev_volume_version = sw_volume_state_get_hash();
prev_output_version = audio_output_state_get_version();
- prev_playlist_version = playlist_state_get_hash(&g_playlist, pc);
+ prev_playlist_version = playlist_state_get_hash(&partition.playlist,
+ &partition.pc);
}
static void
-state_file_read(struct player_control *pc)
+state_file_read(Partition &partition)
{
bool success;
@@ -95,14 +96,16 @@ state_file_read(struct player_control *pc)
while ((line = file.ReadLine()) != NULL) {
success = read_sw_volume_state(line) ||
audio_output_state_read(line) ||
- playlist_state_restore(line, file, &g_playlist, pc);
+ playlist_state_restore(line, file, &partition.playlist,
+ &partition.pc);
if (!success)
g_warning("Unrecognized line in state file: %s", line);
}
prev_volume_version = sw_volume_state_get_hash();
prev_output_version = audio_output_state_get_version();
- prev_playlist_version = playlist_state_get_hash(&g_playlist, pc);
+ prev_playlist_version = playlist_state_get_hash(&partition.playlist,
+ &partition.pc);
}
/**
@@ -112,21 +115,22 @@ state_file_read(struct player_control *pc)
static gboolean
timer_save_state_file(gpointer data)
{
- struct player_control *pc = (struct player_control *)data;
+ Partition &partition = *(Partition *)data;
if (prev_volume_version == sw_volume_state_get_hash() &&
prev_output_version == audio_output_state_get_version() &&
- prev_playlist_version == playlist_state_get_hash(&g_playlist, pc))
+ prev_playlist_version == playlist_state_get_hash(&partition.playlist,
+ &partition.pc))
/* nothing has changed - don't save the state file,
don't spin up the hard disk */
return true;
- state_file_write(pc);
+ state_file_write(partition);
return true;
}
void
-state_file_init(const char *path, struct player_control *pc)
+state_file_init(const char *path, Partition &partition)
{
assert(state_file_path == NULL);
@@ -134,15 +138,15 @@ state_file_init(const char *path, struct player_control *pc)
return;
state_file_path = g_strdup(path);
- state_file_read(pc);
+ state_file_read(partition);
save_state_source_id = g_timeout_add_seconds(5 * 60,
timer_save_state_file,
- pc);
+ &partition);
}
void
-state_file_finish(struct player_control *pc)
+state_file_finish(Partition &partition)
{
if (state_file_path == NULL)
/* no state file configured, no cleanup required */
@@ -151,7 +155,7 @@ state_file_finish(struct player_control *pc)
if (save_state_source_id != 0)
g_source_remove(save_state_source_id);
- state_file_write(pc);
+ state_file_write(partition);
g_free(state_file_path);
}
diff --git a/src/StateFile.hxx b/src/StateFile.hxx
index 77629aba9..35269fe40 100644
--- a/src/StateFile.hxx
+++ b/src/StateFile.hxx
@@ -20,13 +20,13 @@
#ifndef MPD_STATE_FILE_HXX
#define MPD_STATE_FILE_HXX
-struct player_control;
+struct Partition;
void
-state_file_init(const char *path, struct player_control *pc);
+state_file_init(const char *path, Partition &partition);
void
-state_file_finish(struct player_control *pc);
+state_file_finish(Partition &partition);
void write_state_file(void);
diff --git a/src/UpdateGlue.cxx b/src/UpdateGlue.cxx
index cb1600d4f..2edd19cc2 100644
--- a/src/UpdateGlue.cxx
+++ b/src/UpdateGlue.cxx
@@ -24,7 +24,6 @@
#include "UpdateRemove.hxx"
#include "Mapper.hxx"
#include "DatabaseSimple.hxx"
-#include "Playlist.hxx"
extern "C" {
#include "event_pipe.h"
@@ -33,6 +32,7 @@ extern "C" {
}
#include "Main.hxx"
+#include "Partition.hxx"
#include "mpd_error.h"
#include <glib.h>
@@ -155,7 +155,7 @@ static void update_finished_event(void)
if (modified) {
/* send "idle" events */
- playlist_increment_version_all(&g_playlist);
+ playlist_increment_version_all(&global_partition->playlist);
idle_add(IDLE_DATABASE);
}
diff --git a/src/UpdateRemove.cxx b/src/UpdateRemove.cxx
index 814c803b2..c1a0cd32b 100644
--- a/src/UpdateRemove.cxx
+++ b/src/UpdateRemove.cxx
@@ -20,6 +20,7 @@
#include "config.h" /* must be first for large file support */
#include "UpdateRemove.hxx"
#include "Playlist.hxx"
+#include "Partition.hxx"
extern "C" {
#include "event_pipe.h"
@@ -63,7 +64,9 @@ song_remove_event(void)
sticker_song_delete(removed_song);
#endif
- playlist_delete_song(&g_playlist, global_player_control, removed_song);
+ playlist_delete_song(&global_partition->playlist,
+ &global_partition->pc,
+ removed_song);
/* clear "removed_song" and send signal to update thread */
g_mutex_lock(remove_mutex);