[rygel/rygel-0-12] core: Restart find_object on container update



commit 596d318bd735d6ef036cec141e17fd386129fbc3
Author: Jens Georg <mail jensge org>
Date:   Tue Oct 11 14:11:44 2011 +0200

    core: Restart find_object on container update
    
    Before asynchronously descending in the hierarchy, we connect to the
    updated signal of this container. If the container is updated, it might
    be that this.children changed while we're iterating over it. If that
    happens, we restart the foreach loop, but only 10 times. If we still
    are interrupted, we give up.

 src/rygel/rygel-simple-container.vala |   48 ++++++++++++++++++++++++++------
 1 files changed, 39 insertions(+), 9 deletions(-)
---
diff --git a/src/rygel/rygel-simple-container.vala b/src/rygel/rygel-simple-container.vala
index 1030882..79fcafd 100644
--- a/src/rygel/rygel-simple-container.vala
+++ b/src/rygel/rygel-simple-container.vala
@@ -135,21 +135,51 @@ public class Rygel.SimpleContainer : Rygel.MediaContainer,
                                                     Cancellable? cancellable)
                                                     throws Error {
         MediaObject media_object = null;
+        var restart_count = 0;
+        var restart = false;
 
-        foreach (var child in this.children) {
-            if (child.id == id) {
-                media_object = child;
+        do {
+            restart = false;
+            ulong updated_id = 0;
 
-                break;
-            } else if (child is MediaContainer) {
-                var container = child as MediaContainer;
+            foreach (var child in this.children) {
+                if (child.id == id) {
+                    media_object = child;
 
-                media_object = yield container.find_object (id, cancellable);
-                if (media_object != null) {
                     break;
+                } else if (child is MediaContainer) {
+                    updated_id = this.container_updated.connect ( (_, updated) => {
+                        if (updated == this) {
+                            restart = true;
+                            restart_count++;
+
+                            // bail out on first update
+                            this.disconnect (updated_id);
+                            updated_id = 0;
+                        }
+                    });
+
+                    var container = child as MediaContainer;
+                    media_object = yield container.find_object (id, cancellable);
+
+                    if (media_object != null) {
+                        // no need to loop when we've found what we were looking
+                        // for
+                        restart = false;
+
+                        break;
+                    }
+
+                    if (restart) {
+                        break;
+                    }
+
+                    if (updated_id != 0) {
+                        this.disconnect (updated_id);
+                    }
                 }
             }
-        }
+        } while (restart && restart_count < 10);
 
         return media_object;
     }



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