Skip to content

Commit

Permalink
Fix a data race between the feeder thread and attaching of the stream…
Browse files Browse the repository at this point in the history
… to the mixer.

This is done by by ensuring the stream is pre-filled before attaching is
possible.

Possibly related to #1561
  • Loading branch information
SiegeLordEx authored and SiegeLord committed Jun 24, 2024
1 parent fd7de9f commit 7648fdf
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 12 deletions.
16 changes: 10 additions & 6 deletions addons/acodec/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,23 @@ void _al_acodec_start_feed_thread(ALLEGRO_AUDIO_STREAM *stream)
stream->feed_thread_started_cond = al_create_cond();
stream->feed_thread_started_mutex = al_create_mutex();
al_start_thread(stream->feed_thread);
}

void _al_acodec_stop_feed_thread(ALLEGRO_AUDIO_STREAM *stream)
{
ALLEGRO_EVENT quit_event;

/* Need to wait for the thread to start, otherwise the quit event may be
* sent before the event source is registered with the queue. */
* sent before the event source is registered with the queue.
*
* This also makes the pre-fill system thread safe, as it needs to operate
* before the mutexes are set up.
*/
al_lock_mutex(stream->feed_thread_started_mutex);
while (!stream->feed_thread_started) {
al_wait_cond(stream->feed_thread_started_cond, stream->feed_thread_started_mutex);
}
al_unlock_mutex(stream->feed_thread_started_mutex);
}

void _al_acodec_stop_feed_thread(ALLEGRO_AUDIO_STREAM *stream)
{
ALLEGRO_EVENT quit_event;

quit_event.type = _KCM_STREAM_FEEDER_QUIT_EVENT_TYPE;
al_emit_user_event(al_get_audio_stream_event_source(stream), &quit_event, NULL);
Expand Down
13 changes: 7 additions & 6 deletions addons/audio/kcm_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,11 +692,6 @@ void *_al_kcm_feed_stream(ALLEGRO_THREAD *self, void *vstream)
queue = al_create_event_queue();
al_register_event_source(queue, &stream->spl.es);

al_lock_mutex(stream->feed_thread_started_mutex);
stream->feed_thread_started = true;
al_broadcast_cond(stream->feed_thread_started_cond);
al_unlock_mutex(stream->feed_thread_started_mutex);

stream->quit_feed_thread = false;

while (!stream->quit_feed_thread) {
Expand All @@ -708,7 +703,6 @@ void *_al_kcm_feed_stream(ALLEGRO_THREAD *self, void *vstream)

if ((prefill || event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT)
&& !stream->is_draining) {
prefill = false;
unsigned long bytes;
unsigned long bytes_written;
ALLEGRO_MUTEX *stream_mutex;
Expand Down Expand Up @@ -784,6 +778,13 @@ void *_al_kcm_feed_stream(ALLEGRO_THREAD *self, void *vstream)
fin_event.user.timestamp = al_get_time();
al_emit_user_event(&stream->spl.es, &fin_event, NULL);
}
if (prefill) {
al_lock_mutex(stream->feed_thread_started_mutex);
stream->feed_thread_started = true;
al_broadcast_cond(stream->feed_thread_started_cond);
al_unlock_mutex(stream->feed_thread_started_mutex);
}
prefill = false;
}

al_destroy_event_queue(queue);
Expand Down

0 comments on commit 7648fdf

Please sign in to comment.