From 548385ac6cc0bc344762e19117f94258e7ea2251 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 19 Aug 2008 03:31:25 -0700 Subject: fix output buffer deadlock when daemonizing We spawned the output buffer thread before daemonizing in initPlayerData(), which is ultra bad because daemonizes forks and threads are not preserved on exit. Since playerData has been stripped bare by this core-rewrite anyways, move this code into the outputBuffer_* group and drop playerData.[ch] completely I completely forgot to test this :< --- src/Makefile.am | 3 +- src/audio.c | 1 - src/decode.c | 1 - src/inputPlugin.h | 1 - src/inputPlugins/audiofile_plugin.c | 1 - src/inputPlugins/mod_plugin.c | 1 - src/inputPlugins/wavpack_plugin.c | 1 - src/main.c | 4 +- src/outputBuffer.c | 23 +--------- src/outputBuffer.h | 7 +-- src/outputBuffer_config_init.h | 87 +++++++++++++++++++++++++++++++++++++ src/playerData.c | 73 ------------------------------- src/playerData.h | 29 ------------- 13 files changed, 95 insertions(+), 137 deletions(-) create mode 100644 src/outputBuffer_config_init.h delete mode 100644 src/playerData.c delete mode 100644 src/playerData.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 93943db23..6c52dde1e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -61,6 +61,7 @@ mpd_headers = \ compress.h \ os_compat.h \ outputBuffer.h \ + outputBuffer_config_init.h \ outputBuffer_accessors.h \ outputBuffer_audio.h \ outputBuffer_ob_send.h \ @@ -69,7 +70,6 @@ mpd_headers = \ pcm_utils.h \ permission.h \ player_error.h \ - playerData.h \ playlist.h \ replayGain.h \ ringbuf.h \ @@ -126,7 +126,6 @@ mpd_SOURCES = \ pcm_utils.c \ permission.c \ player_error.c \ - playerData.c \ playlist.c \ replayGain.c \ ringbuf.c \ diff --git a/src/audio.c b/src/audio.c index 9f6bedc33..34b74e6e1 100644 --- a/src/audio.c +++ b/src/audio.c @@ -20,7 +20,6 @@ #include "audioOutput.h" #include "log.h" #include "command.h" -#include "playerData.h" #include "path.h" #include "ack.h" #include "myfprintf.h" diff --git a/src/decode.c b/src/decode.c index 12c1b8746..150a0a58b 100644 --- a/src/decode.c +++ b/src/decode.c @@ -20,7 +20,6 @@ #include "outputBuffer.h" #include "player_error.h" #include "playlist.h" -#include "playerData.h" #include "pcm_utils.h" #include "path.h" #include "log.h" diff --git a/src/inputPlugin.h b/src/inputPlugin.h index 169781931..61cef9bef 100644 --- a/src/inputPlugin.h +++ b/src/inputPlugin.h @@ -21,7 +21,6 @@ #include "inputStream.h" #include "outputBuffer.h" -#include "playerData.h" /* valid values for streamTypes in the InputPlugin struct: */ #define INPUT_PLUGIN_STREAM_FILE 0x01 diff --git a/src/inputPlugins/audiofile_plugin.c b/src/inputPlugins/audiofile_plugin.c index 8178972ff..114a87786 100644 --- a/src/inputPlugins/audiofile_plugin.c +++ b/src/inputPlugins/audiofile_plugin.c @@ -26,7 +26,6 @@ #include "../audio.h" #include "../log.h" #include "../pcm_utils.h" -#include "../playerData.h" #include "../os_compat.h" #include diff --git a/src/inputPlugins/mod_plugin.c b/src/inputPlugins/mod_plugin.c index cfa7d6e3d..9f9da6273 100644 --- a/src/inputPlugins/mod_plugin.c +++ b/src/inputPlugins/mod_plugin.c @@ -24,7 +24,6 @@ #include "../audio.h" #include "../log.h" #include "../pcm_utils.h" -#include "../playerData.h" #include "../os_compat.h" #include diff --git a/src/inputPlugins/wavpack_plugin.c b/src/inputPlugins/wavpack_plugin.c index ef02712d7..2538be326 100644 --- a/src/inputPlugins/wavpack_plugin.c +++ b/src/inputPlugins/wavpack_plugin.c @@ -26,7 +26,6 @@ #include "../audio.h" #include "../log.h" #include "../pcm_utils.h" -#include "../playerData.h" #include "../outputBuffer.h" #include "../os_compat.h" #include "../path.h" diff --git a/src/main.c b/src/main.c index e02085294..239296501 100644 --- a/src/main.c +++ b/src/main.c @@ -23,7 +23,6 @@ #include "listen.h" #include "conf.h" #include "path.h" -#include "playerData.h" #include "stats.h" #include "sig_handlers.h" #include "audio.h" @@ -412,7 +411,7 @@ int main(int argc, char *argv[]) openDB(&options, argv[0]); initCommands(); - initPlayerData(); + config_output_buffer(); initAudioConfig(); initAudioDriver(); initVolume(); @@ -424,6 +423,7 @@ int main(int argc, char *argv[]) daemonize(&options); init_main_notify(); + init_output_buffer(); setup_log_output(options.stdOutput); initSigHandlers(); diff --git a/src/outputBuffer.c b/src/outputBuffer.c index 26e6077f2..26d31b2cd 100644 --- a/src/outputBuffer.c +++ b/src/outputBuffer.c @@ -78,12 +78,6 @@ static struct output_buffer ob; #include "outputBuffer_xfade.h" #include "outputBuffer_accessors.h" -static void ob_free(void) -{ - free(ob.chunks); - ringbuf_free(ob.index); -} - static enum action_status ob_do_stop(void); static void stop_playback(void) { @@ -497,22 +491,7 @@ out: return NULL; } -void ob_init(size_t size) -{ - pthread_attr_t attr; - assert(size > 0 && !ob.index && !ob.chunks); - ob.index = ringbuf_create(size); - ob.chunks = xcalloc(ob.index->size, sizeof(struct ob_chunk)); - ob.preseek_len = xmalloc(ob.index->size * sizeof(ob.chunks[0].len)); - ob.nr_bpp = 1; - ob.state = OB_STATE_STOP; - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - if (pthread_create(&ob.thread, &attr, ob_task, NULL)) - FATAL("Failed to spawn player task: %s\n", strerror(errno)); - atexit(ob_free); -} +#include "outputBuffer_config_init.h" void ob_seek_start(void) { diff --git a/src/outputBuffer.h b/src/outputBuffer.h index 833a29e77..187846ef3 100644 --- a/src/outputBuffer.h +++ b/src/outputBuffer.h @@ -47,7 +47,7 @@ enum ob_action { /* 1020 bytes since its divisible for 8, 16, 24, and 32-bit audio */ #define CHUNK_SIZE 1020 -void ob_init(size_t size); +void ob_flush(void); enum ob_drop_type { OB_DROP_DECODED, OB_DROP_PLAYING }; void ob_drop_audio(enum ob_drop_type type); @@ -101,8 +101,9 @@ AudioFormat *ob_audio_format(void); void ob_advance_sequence(void); -void ob_wait_sync(void); - void ob_flush(void); +void config_output_buffer(void); +void init_output_buffer(void); + #endif diff --git a/src/outputBuffer_config_init.h b/src/outputBuffer_config_init.h new file mode 100644 index 000000000..ba5b7f137 --- /dev/null +++ b/src/outputBuffer_config_init.h @@ -0,0 +1,87 @@ +/* the Music Player Daemon (MPD) + * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) + * This project's homepage is: 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "conf.h" +#include "log.h" +#include "utils.h" + +#define DEFAULT_BUFFER_SIZE 2048 +#define DEFAULT_BUFFER_BEFORE_PLAY 10 + + +void config_output_buffer(void) +{ + float perc = DEFAULT_BUFFER_BEFORE_PLAY; + char *test; + size_t buffer_size = DEFAULT_BUFFER_SIZE; + ConfigParam *param; + unsigned int buffered_before_play; + unsigned int buffered_chunks; + + if ((param = getConfigParam(CONF_AUDIO_BUFFER_SIZE))) { + buffer_size = strtol(param->value, &test, 10); + if (*test != '\0' || buffer_size <= 0) + FATAL(CONF_AUDIO_BUFFER_SIZE + " \"%s\" is not a positive integer, " + "line %i\n", param->value, param->line); + } + + buffer_size *= 1024; + buffered_chunks = buffer_size / CHUNK_SIZE; + + if (buffered_chunks >= 1 << 15) + FATAL("buffer size \"%li\" is too big\n", (long)buffer_size); + + if ((param = getConfigParam(CONF_BUFFER_BEFORE_PLAY))) { + perc = strtod(param->value, &test); + if (*test != '%' || perc < 0 || perc > 100) + FATAL(CONF_BUFFER_BEFORE_PLAY + " \"%s\" is not a positive " + "percentage and less than 100 percent, line %i" + "\n", param->value, param->line); + } + + buffered_before_play = (perc / 100) * buffered_chunks; + if (buffered_before_play > buffered_chunks) + buffered_before_play = buffered_chunks; + ob.nr_bpp = buffered_before_play; + + assert(buffered_chunks > 0 && !ob.index && !ob.chunks); + ob.index = ringbuf_create(buffered_chunks); + ob.chunks = xcalloc(ob.index->size, sizeof(struct ob_chunk)); + ob.preseek_len = xmalloc(ob.index->size * sizeof(ob.chunks[0].len)); + ob.state = OB_STATE_STOP; +} + +static void ob_free(void) +{ + free(ob.chunks); + ringbuf_free(ob.index); +} + +void init_output_buffer(void) +{ + pthread_attr_t attr; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (pthread_create(&ob.thread, &attr, ob_task, NULL)) + FATAL("Failed to spawn player task: %s\n", strerror(errno)); + + atexit(ob_free); +} diff --git a/src/playerData.c b/src/playerData.c deleted file mode 100644 index 113a71f35..000000000 --- a/src/playerData.c +++ /dev/null @@ -1,73 +0,0 @@ -/* the Music Player Daemon (MPD) - * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) - * This project's homepage is: 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "playerData.h" -#include "conf.h" -#include "log.h" -#include "utils.h" - -#define DEFAULT_BUFFER_SIZE 2048 -#define DEFAULT_BUFFER_BEFORE_PLAY 10 - -void initPlayerData(void) -{ - float perc = DEFAULT_BUFFER_BEFORE_PLAY; - char *test; - size_t bufferSize = DEFAULT_BUFFER_SIZE; - unsigned int buffered_chunks; - ConfigParam *param; - unsigned int buffered_before_play; - - param = getConfigParam(CONF_AUDIO_BUFFER_SIZE); - - if (param) { - bufferSize = strtol(param->value, &test, 10); - if (*test != '\0' || bufferSize <= 0) { - FATAL("buffer size \"%s\" is not a positive integer, " - "line %i\n", param->value, param->line); - } - } - - bufferSize *= 1024; - - buffered_chunks = bufferSize / CHUNK_SIZE; - - if (buffered_chunks >= 1 << 15) { - FATAL("buffer size \"%li\" is too big\n", (long)bufferSize); - } - - param = getConfigParam(CONF_BUFFER_BEFORE_PLAY); - - if (param) { - perc = strtod(param->value, &test); - if (*test != '%' || perc < 0 || perc > 100) { - FATAL("buffered before play \"%s\" is not a positive " - "percentage and less than 100 percent, line %i" - "\n", param->value, param->line); - } - } - - buffered_before_play = (perc / 100) * buffered_chunks; - if (buffered_before_play > buffered_chunks) { - buffered_before_play = buffered_chunks; - } - - ob_init(buffered_chunks); -} - - diff --git a/src/playerData.h b/src/playerData.h deleted file mode 100644 index ea8ea13e8..000000000 --- a/src/playerData.h +++ /dev/null @@ -1,29 +0,0 @@ -/* the Music Player Daemon (MPD) - * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) - * This project's homepage is: 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef PLAYER_DATA_H -#define PLAYER_DATA_H - -#include "audio.h" -#include "decode.h" -#include "mpd_types.h" -#include "outputBuffer.h" - -void initPlayerData(void); - -#endif -- cgit v1.2.3