[gnome-shell] background: fix cancellable issue



commit 55d1c7e2ab9fb675f8f5a6e4c03ff17093a01cff
Author: Ray Strode <rstrode redhat com>
Date:   Wed Feb 26 15:45:14 2014 -0500

    background: fix cancellable issue
    
    If we have the following sequence:
    
        cache.getImageContent({ filename: "foo", cancellable: cancellable1 });
        cache.getImageContent({ filename: "foo", cancellable: cancellable2 });
        cancellable1.cancel();
    
    Then the second load will complete with "null" as its content, even though
    it was never cancelled, and we'll see a blank image. Meanwhile, since the
    second load simply appends to the list of callers for the second load,
    cancellable2 does absolutely nothing: cancelling it won't stop the load,
    and it will still receive onFinished handling.
    
    To prevent this from happening, give the actual load operation its own
    Gio.Cancellable, which is "ref-counted" -- only cancel it when all the other
    possible callers cancel.
    
    Based on work from Jasper St. Pierre <jstpierre macheye net>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=722149

 js/ui/background.js |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)
---
diff --git a/js/ui/background.js b/js/ui/background.js
index 506fe59..b1eb57a 100644
--- a/js/ui/background.js
+++ b/js/ui/background.js
@@ -134,6 +134,21 @@ const BackgroundCache = new Lang.Class({
 
     _attachCallerToFileLoad: function(caller, fileLoad) {
         fileLoad.callers.push(caller);
+
+        if (!caller.cancellable)
+            return;
+
+        caller.cancellable.connect(Lang.bind(this, function() {
+            let idx = fileLoad.callers.indexOf(caller);
+            fileLoad.callers.splice(idx, 1);
+
+            if (fileLoad.callers.length == 0) {
+                fileLoad.cancellable.cancel();
+
+                let idx = this._pendingFileLoads.indexOf(fileLoad);
+                this._pendingFileLoads.splice(idx, 1);
+            }
+        }));
     },
 
     _loadImageContent: function(params) {
@@ -146,6 +161,7 @@ const BackgroundCache = new Lang.Class({
 
         let caller = { monitorIndex: params.monitorIndex,
                        effects: params.effects,
+                       cancellable: params.cancellable,
                        onFinished: params.onFinished };
 
         for (let i = 0; i < this._pendingFileLoads.length; i++) {
@@ -160,6 +176,7 @@ const BackgroundCache = new Lang.Class({
 
         let fileLoad = { filename: params.filename,
                          style: params.style,
+                         cancellable: new Gio.Cancellable(),
                          callers: [] };
         this._attachCallerToFileLoad(caller, fileLoad);
 


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