[banshee/gapless-ng: 833/836] [libbanshee] Fix enable/disable of ReplayGain while playing.



commit f9d85fb5f2e5401c0ed25f0aa48a5e3ad8bdd4fc
Author: Christopher James Halse Rogers <raof ubuntu com>
Date:   Thu Feb 25 15:12:04 2010 +1100

    [libbanshee] Fix enable/disable of ReplayGain while playing.
    
    The pad_block_cb can, and apparently does, get called multiple times from multiple threads
    This leaves us in an inconsistent state.  Instead, throw a mutex around our unlink/link
    logic, and check whether we need to relink the pipeline within that protection.

 libbanshee/banshee-player-replaygain.c |   21 +++++++++++++++------
 1 files changed, 15 insertions(+), 6 deletions(-)
---
diff --git a/libbanshee/banshee-player-replaygain.c b/libbanshee/banshee-player-replaygain.c
index 7dade14..fc1ac45 100644
--- a/libbanshee/banshee-player-replaygain.c
+++ b/libbanshee/banshee-player-replaygain.c
@@ -87,6 +87,18 @@ pad_block_cb (GstPad *srcPad, gboolean blocked, gpointer user_data) {
     BansheePlayer* player = (BansheePlayer*) user_data;
     g_return_if_fail (IS_BANSHEE_PLAYER (player));
 
+    // The pad_block_cb can get triggered multiple times, on different threads.
+    // Lock around the link/unlink code, so we don't end up going through here
+    // with inconsistent state.
+    g_mutex_lock (player->mutex);
+
+    if ((player->replaygain_enabled && player->rgvolume_in_pipeline) ||
+        (!player->replaygain_enabled && !player->rgvolume_in_pipeline)) {
+        // The pipeline is already in the correct state.  Do nothing.
+        g_mutex_unlock (player->mutex);
+        return;
+    }
+
     if (player->rgvolume_in_pipeline == TRUE) {
         gst_element_unlink(player->before_rgvolume, player->rgvolume);
         gst_element_unlink(player->rgvolume, player->after_rgvolume);
@@ -115,6 +127,9 @@ pad_block_cb (GstPad *srcPad, gboolean blocked, gpointer user_data) {
         player->rgvolume_in_pipeline = FALSE;
     }
 
+    // Our state is now consistent
+    g_mutex_unlock (player->mutex);
+
     if (gst_pad_is_blocked (srcPad)) {
         gst_pad_set_blocked_async(srcPad, FALSE, &pad_block_cb, player);
     }
@@ -156,12 +171,6 @@ void _bp_replaygain_pipeline_rebuild (BansheePlayer* player)
 {
     g_return_if_fail (IS_BANSHEE_PLAYER (player));
 
-    if ((player->replaygain_enabled && player->rgvolume_in_pipeline) ||
-        (!player->replaygain_enabled && !player->rgvolume_in_pipeline)) {
-        // The pipeline is already in the correct state.  Do nothing.
-        return;
-    }
-
     g_return_if_fail (GST_IS_ELEMENT (player->before_rgvolume));
     GstPad* srcPad = gst_element_get_static_pad(player->before_rgvolume, "src");
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]