Commit 7f803494 authored by Max Kellermann's avatar Max Kellermann

player_control: hold mutex in pc_play(), pc_pause()

Race condition fix.
parent a6ef6961
...@@ -34,6 +34,9 @@ ...@@ -34,6 +34,9 @@
struct player_control pc; struct player_control pc;
static void
pc_enqueue_song_locked(struct song *song);
void pc_init(unsigned buffer_chunks, unsigned int buffered_before_play) void pc_init(unsigned buffer_chunks, unsigned int buffered_before_play)
{ {
pc.buffer_chunks = buffer_chunks; pc.buffer_chunks = buffer_chunks;
...@@ -103,15 +106,19 @@ pc_play(struct song *song) ...@@ -103,15 +106,19 @@ pc_play(struct song *song)
{ {
assert(song != NULL); assert(song != NULL);
player_lock();
if (pc.state != PLAYER_STATE_STOP) if (pc.state != PLAYER_STATE_STOP)
player_command(PLAYER_COMMAND_STOP); player_command_locked(PLAYER_COMMAND_STOP);
assert(pc.next_song == NULL); assert(pc.next_song == NULL);
pc_enqueue_song(song); pc_enqueue_song_locked(song);
assert(pc.next_song == NULL); assert(pc.next_song == NULL);
player_unlock();
idle_add(IDLE_PLAYER); idle_add(IDLE_PLAYER);
} }
...@@ -151,8 +158,21 @@ pc_kill(void) ...@@ -151,8 +158,21 @@ pc_kill(void)
void void
pc_pause(void) pc_pause(void)
{ {
player_lock();
if (pc.state != PLAYER_STATE_STOP) {
player_command_locked(PLAYER_COMMAND_PAUSE);
idle_add(IDLE_PLAYER);
}
player_unlock();
}
static void
pc_pause_locked(void)
{
if (pc.state != PLAYER_STATE_STOP) { if (pc.state != PLAYER_STATE_STOP) {
player_command(PLAYER_COMMAND_PAUSE); player_command_locked(PLAYER_COMMAND_PAUSE);
idle_add(IDLE_PLAYER); idle_add(IDLE_PLAYER);
} }
} }
...@@ -160,20 +180,24 @@ pc_pause(void) ...@@ -160,20 +180,24 @@ pc_pause(void)
void void
pc_set_pause(bool pause_flag) pc_set_pause(bool pause_flag)
{ {
player_lock();
switch (pc.state) { switch (pc.state) {
case PLAYER_STATE_STOP: case PLAYER_STATE_STOP:
break; break;
case PLAYER_STATE_PLAY: case PLAYER_STATE_PLAY:
if (pause_flag) if (pause_flag)
pc_pause(); pc_pause_locked();
break; break;
case PLAYER_STATE_PAUSE: case PLAYER_STATE_PAUSE:
if (!pause_flag) if (!pause_flag)
pc_pause(); pc_pause_locked();
break; break;
} }
player_unlock();
} }
void void
...@@ -203,8 +227,10 @@ pc_get_state(void) ...@@ -203,8 +227,10 @@ pc_get_state(void)
void void
pc_clear_error(void) pc_clear_error(void)
{ {
player_lock();
pc.error = PLAYER_ERROR_NOERROR; pc.error = PLAYER_ERROR_NOERROR;
pc.errored_song = NULL; pc.errored_song = NULL;
player_unlock();
} }
enum player_error enum player_error
...@@ -258,16 +284,23 @@ pc_get_error_message(void) ...@@ -258,16 +284,23 @@ pc_get_error_message(void)
return NULL; return NULL;
} }
void static void
pc_enqueue_song(struct song *song) pc_enqueue_song_locked(struct song *song)
{ {
assert(song != NULL); assert(song != NULL);
player_lock();
assert(pc.next_song == NULL); assert(pc.next_song == NULL);
pc.next_song = song; pc.next_song = song;
player_command_locked(PLAYER_COMMAND_QUEUE); player_command_locked(PLAYER_COMMAND_QUEUE);
}
void
pc_enqueue_song(struct song *song)
{
assert(song != NULL);
player_lock();
pc_enqueue_song_locked(song);
player_unlock(); player_unlock();
} }
......
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