fbd-dev-sound: Delay sending ended signal

Remove the feedback and the associated callback data before invoking the
callback (which then triggers FbdFeebackBased:ended) since we otherwise
remove the data from the currently playing sound from the hash table
instead of removing the data from the sound that just finished playing.

Call flow for a repeating sound before:

  on_sound_play_finished_callback()
    data->callback()
      fbd_feedback_get_ended()
        on_fb_ended()
          fbd_feedback_run()
            g_hash_table_insert(..., feedback, data)
            fbd_dev_sound_play()
              gsound_context_play_full() [async]
    g_hash_table_remove (..., data->feedback) <- removes wrong feedback

So (since the feedback is still the same but only the callback data
changes) we end up removing the data from the currently playing sound
from the hash table and any calls to fbd_dev_sound_stop() would fail
to find data and hence not cancel the playing sound.

Call flow for a repeating sound now:

  on_sound_play_finished_callback()
    g_hash_table_remove (..., data->feedback)
    data->callback()
      fbd_feedback_get_ended()
        on_fb_ended()
          fbd_feedback_run()
            g_hash_table_insert(..., feedback, data)
            fbd_dev_sound_play()
              gsound_context_play_full() [async]

So we remove the data of the currently playing sound before adding
the feedback to the hash table again. No ownership is transfered to
the hash table so no cleanusp need to be changed.

Closes: https://source.puri.sm/Librem5/feedbackd/-/issues/46
This commit is contained in:
Guido Günther
2021-10-15 15:12:55 +02:00
parent 05bd9ae0cb
commit c88c6cfff5
+5 -2
View File
@@ -187,9 +187,11 @@ on_sound_play_finished_callback (GSoundContext *ctx,
}
}
/* Order matters here. We need to remove the feedback from the hash table before
invoking the callback. */
g_hash_table_remove (data->dev->playbacks, data->feedback);
(*data->callback)(data->feedback);
g_hash_table_remove (data->dev->playbacks, data->feedback);
fbd_async_data_dispose (data);
}
@@ -204,7 +206,8 @@ fbd_dev_sound_play (FbdDevSound *self, FbdFeedbackSound *feedback, FbdDevSoundPl
data = fbd_async_data_new (self, feedback, callback);
g_hash_table_insert (self->playbacks, feedback, data);
if (!g_hash_table_insert (self->playbacks, feedback, data))
g_warning ("Feedback %p already present", feedback);
gsound_context_play_full (self->ctx, data->cancel,
(GAsyncReadyCallback) on_sound_play_finished_callback,