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
This commit is contained in:
parent
fdf264ff64
commit
55d1c7e2ab
@ -134,6 +134,21 @@ const BackgroundCache = new Lang.Class({
|
|||||||
|
|
||||||
_attachCallerToFileLoad: function(caller, fileLoad) {
|
_attachCallerToFileLoad: function(caller, fileLoad) {
|
||||||
fileLoad.callers.push(caller);
|
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) {
|
_loadImageContent: function(params) {
|
||||||
@ -146,6 +161,7 @@ const BackgroundCache = new Lang.Class({
|
|||||||
|
|
||||||
let caller = { monitorIndex: params.monitorIndex,
|
let caller = { monitorIndex: params.monitorIndex,
|
||||||
effects: params.effects,
|
effects: params.effects,
|
||||||
|
cancellable: params.cancellable,
|
||||||
onFinished: params.onFinished };
|
onFinished: params.onFinished };
|
||||||
|
|
||||||
for (let i = 0; i < this._pendingFileLoads.length; i++) {
|
for (let i = 0; i < this._pendingFileLoads.length; i++) {
|
||||||
@ -160,6 +176,7 @@ const BackgroundCache = new Lang.Class({
|
|||||||
|
|
||||||
let fileLoad = { filename: params.filename,
|
let fileLoad = { filename: params.filename,
|
||||||
style: params.style,
|
style: params.style,
|
||||||
|
cancellable: new Gio.Cancellable(),
|
||||||
callers: [] };
|
callers: [] };
|
||||||
this._attachCallerToFileLoad(caller, fileLoad);
|
this._attachCallerToFileLoad(caller, fileLoad);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user