summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <PromyLOPh@lavabit.com>2010-03-16 15:14:51 +0100
committerLars-Dominik Braun <PromyLOPh@lavabit.com>2010-03-16 15:14:51 +0100
commit13bd3c8253a5c2998ce85a084a854f7a3d0ba7f5 (patch)
treec25b8b8e5042de6dc1dae102a5067c3732468fea
parentc7690562ee0963e6cd3af973e34c388347e24190 (diff)
downloadpianobar-windows-13bd3c8253a5c2998ce85a084a854f7a3d0ba7f5.tar.gz
pianobar-windows-13bd3c8253a5c2998ce85a084a854f7a3d0ba7f5.tar.bz2
pianobar-windows-13bd3c8253a5c2998ce85a084a854f7a3d0ba7f5.zip
Fix player race condition
Pressing any key before the player thread set mode to PLAYER_INITIALIZED lead to a song skip and spawning of another player thread. The two player threads were operating on the same variables/memory area, resulting in a crash. Adding a new player state (PLAYER_STARTING) and setting it _before_ invoking pthread_start should resolve this, 'cause the "if PLAYER_FREED-branch" is not taken any more, ergo no second player thread is started.
-rw-r--r--src/main.c3
-rw-r--r--src/player.h15
2 files changed, 14 insertions, 4 deletions
diff --git a/src/main.c b/src/main.c
index 82ed674..5428653 100644
--- a/src/main.c
+++ b/src/main.c
@@ -248,6 +248,9 @@ int main (int argc, char **argv) {
BarUiStartEventCmd (&settings, "songstart", curStation,
playlist, &player, PIANO_RET_OK);
+ /* prevent race condition, mode must _not_ be FREED if
+ * thread has been started */
+ player.mode = PLAYER_STARTING;
/* start player */
pthread_create (&playerThread, NULL, BarPlayerThread,
&player);
diff --git a/src/player.h b/src/player.h
index 82a6cd5..249fc6f 100644
--- a/src/player.h
+++ b/src/player.h
@@ -49,10 +49,17 @@ struct audioPlayer {
size_t bufferRead;
size_t bytesReceived;
- enum {PLAYER_FREED = 0, PLAYER_INITIALIZED, PLAYER_FOUND_ESDS,
- PLAYER_AUDIO_INITIALIZED, PLAYER_FOUND_STSZ,
- PLAYER_SAMPLESIZE_INITIALIZED, PLAYER_RECV_DATA,
- PLAYER_FINISHED_PLAYBACK} mode;
+ enum {
+ PLAYER_FREED = 0, /* thread is not running */
+ PLAYER_STARTING, /* thread is starting */
+ PLAYER_INITIALIZED, /* decoder/waitress initialized */
+ PLAYER_FOUND_ESDS,
+ PLAYER_AUDIO_INITIALIZED, /* audio device opened */
+ PLAYER_FOUND_STSZ,
+ PLAYER_SAMPLESIZE_INITIALIZED,
+ PLAYER_RECV_DATA, /* playing track */
+ PLAYER_FINISHED_PLAYBACK
+ } mode;
PianoAudioFormat_t audioFormat;