player_control: hold mutex in pc_play(), pc_pause()
Race condition fix.
This commit is contained in:
parent
a6ef696132
commit
7f80349494
@ -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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
void
|
void
|
||||||
pc_pause(void)
|
pc_pause(void)
|
||||||
{
|
{
|
||||||
|
player_lock();
|
||||||
|
|
||||||
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
player_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pc_pause_locked(void)
|
||||||
|
{
|
||||||
|
if (pc.state != PLAYER_STATE_STOP) {
|
||||||
|
player_command_locked(PLAYER_COMMAND_PAUSE);
|
||||||
idle_add(IDLE_PLAYER);
|
idle_add(IDLE_PLAYER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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)
|
|||||||
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)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pc_enqueue_song_locked(struct song *song)
|
||||||
|
{
|
||||||
|
assert(song != NULL);
|
||||||
|
assert(pc.next_song == NULL);
|
||||||
|
|
||||||
|
pc.next_song = song;
|
||||||
|
player_command_locked(PLAYER_COMMAND_QUEUE);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pc_enqueue_song(struct song *song)
|
pc_enqueue_song(struct song *song)
|
||||||
{
|
{
|
||||||
assert(song != NULL);
|
assert(song != NULL);
|
||||||
|
|
||||||
player_lock();
|
player_lock();
|
||||||
assert(pc.next_song == NULL);
|
pc_enqueue_song_locked(song);
|
||||||
|
|
||||||
pc.next_song = song;
|
|
||||||
player_command_locked(PLAYER_COMMAND_QUEUE);
|
|
||||||
player_unlock();
|
player_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user