[rygel] renderer Fix referencing of invalid GUPnP.Service



commit ed989d75f58b9a15ee524bd7b493e13024458551
Author: Milan Plzik <milan plzik streamunlimited com>
Date:   Wed Feb 25 17:52:11 2015 +0100

    renderer Fix referencing of invalid GUPnP.Service
    
    If AVTransport or RenderingControl is destroyed while a timeout is running,
    ChangeLog is not destroyed with the Service and hence has a dangling service
    pointer.
    
    Rygel.ChangeLog was holding an unowned reference to GUPnP.Service. In a case
    when the Service was already destroyed and ChangeLog's timeout method was
    invoked, this resulted in accessing of already-destroyed instance. This patch
    fixes it by using a WeakRef to the Service.
    
    Signed-off-by: Milan Plzik <milan plzik streamunlimited com>

 src/librygel-renderer/rygel-changelog.vala |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)
---
diff --git a/src/librygel-renderer/rygel-changelog.vala b/src/librygel-renderer/rygel-changelog.vala
index 6f54c92..4f3933d 100644
--- a/src/librygel-renderer/rygel-changelog.vala
+++ b/src/librygel-renderer/rygel-changelog.vala
@@ -26,7 +26,7 @@ using Gee;
 
 // Helper class for building LastChange messages
 internal class Rygel.ChangeLog : Object {
-    public unowned Service service { get; set; }
+    public WeakRef service;
 
     private string service_ns;
 
@@ -37,7 +37,7 @@ internal class Rygel.ChangeLog : Object {
     private uint timeout_id = 0;
 
     public ChangeLog (Service? service, string service_ns) {
-        this.service = service;
+        this.service = WeakRef(service);
         this.service_ns = service_ns;
         this.str = new StringBuilder ();
         this.hash = new HashMap<string, string> ();
@@ -50,8 +50,13 @@ internal class Rygel.ChangeLog : Object {
     }
 
     private bool timeout () {
+        // Check whether the AVTransport service has not been destroyed already
+        Service? service = (Service?)this.service.get();
+        if (service == null)
+            return false;
+
         // Emit notification
-        this.service.notify ("LastChange", typeof (string), this.finish ());
+        service.notify ("LastChange", typeof (string), this.finish ());
         debug ("LastChange sent");
 
         // Reset
@@ -64,7 +69,7 @@ internal class Rygel.ChangeLog : Object {
 
     private void ensure_timeout () {
         // Make sure we have a notification timeout
-        if (this.service != null && this.timeout_id == 0) {
+        if (this.service.get() != null && this.timeout_id == 0) {
             debug ("Setting up timeout for LastChange");
             this.timeout_id = Timeout.add (150, this.timeout);
         }


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