From 7da58b47cb35304c07247dba5e51875fb0e8f995 Mon Sep 17 00:00:00 2001 From: Jens Georg Date: Tue, 11 Oct 2011 14:11:44 +0200 Subject: [PATCH] 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 file 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; } -- 2.7.4