After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 722149 - background: Fix cancellable issues
background: Fix cancellable issues
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: gnome-shell-maint
gnome-shell-maint
Depends on:
Blocks:
 
 
Reported: 2014-01-14 01:18 UTC by Jasper St. Pierre (not reading bugmail)
Modified: 2014-03-12 16:40 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
background: Fix cancellable issues (8.26 KB, patch)
2014-01-14 01:18 UTC, Jasper St. Pierre (not reading bugmail)
needs-work Details | Review
background: Fix cancellable issues (8.34 KB, patch)
2014-02-20 18:51 UTC, Jasper St. Pierre (not reading bugmail)
reviewed Details | Review
background: always copy background content when loading into cache (6.62 KB, patch)
2014-02-26 21:19 UTC, Ray Strode [halfline]
needs-work Details | Review
background: refactor file loading (5.64 KB, patch)
2014-02-26 21:19 UTC, Ray Strode [halfline]
needs-work Details | Review
background: move file loading to separate function (5.18 KB, patch)
2014-02-26 21:19 UTC, Ray Strode [halfline]
needs-work Details | Review
background: get rid of nested loop when finishing file loading (5.67 KB, patch)
2014-02-26 21:19 UTC, Ray Strode [halfline]
needs-work Details | Review
background: fix cancellable issue (5.53 KB, patch)
2014-02-26 21:19 UTC, Ray Strode [halfline]
needs-work Details | Review
background: always copy background content when loading into cache (3.91 KB, patch)
2014-03-12 16:23 UTC, Jasper St. Pierre (not reading bugmail)
committed Details | Review
background: refactor file loading (2.89 KB, patch)
2014-03-12 16:23 UTC, Jasper St. Pierre (not reading bugmail)
committed Details | Review
background: get rid of nested loop when finishing file loading (3.54 KB, patch)
2014-03-12 16:23 UTC, Jasper St. Pierre (not reading bugmail)
committed Details | Review
background: fix cancellable issue (2.59 KB, patch)
2014-03-12 16:23 UTC, Jasper St. Pierre (not reading bugmail)
committed Details | Review

Description Jasper St. Pierre (not reading bugmail) 2014-01-14 01:18:51 UTC
See patch. This is part of my work on cleaning up the overview transition (yes! Yak shaving is excellent...)
Comment 1 Jasper St. Pierre (not reading bugmail) 2014-01-14 01:18:53 UTC
Created attachment 266220 [details] [review]
background: Fix cancellable issues

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.

Additionally, clean up the large nested loops by splitting out duplicated
code and other stuff.
Comment 2 drago01 2014-02-02 12:20:07 UTC
Trying this out crashes with:

gnome-shell:31599): Gjs-WARNING **: JS ERROR: TypeError: caller.cancellable is null
BackgroundCache<._loadImageContent@resource:///org/gnome/shell/ui/background.js:202
wrapper@resource:///org/gnome/gjs/modules/lang.js:169
BackgroundCache<.getImageContent@resource:///org/gnome/shell/ui/background.js:261
wrapper@resource:///org/gnome/gjs/modules/lang.js:169
SystemBackground<._init@resource:///org/gnome/shell/ui/background.js:645
wrapper@resource:///org/gnome/gjs/modules/lang.js:169
_Base.prototype._construct@resource:///org/gnome/gjs/modules/lang.js:110
Class.prototype._construct/newClass@resource:///org/gnome/gjs/modules/lang.js:204
LayoutManager<._loadBackground@resource:///org/gnome/shell/ui/layout.js:566
wrapper@resource:///org/gnome/gjs/modules/lang.js:169
LayoutManager<.init@resource:///org/gnome/shell/ui/layout.js:252
wrapper@resource:///org/gnome/gjs/modules/lang.js:169
_initializeUI@resource:///org/gnome/shell/ui/main.js:175
start@resource:///org/gnome/shell/ui/main.js:117
@<main>:1
Comment 3 drago01 2014-02-02 12:36:44 UTC
Review of attachment 266220 [details] [review]:

Does not work (a tleast on my setup with two monitors)
Comment 4 Jasper St. Pierre (not reading bugmail) 2014-02-20 18:51:55 UTC
Created attachment 269823 [details] [review]
background: Fix cancellable issues

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.

Additionally, clean up the large nested loops by splitting out duplicated
code and other stuff.
Comment 5 Adam Williamson 2014-02-21 03:57:22 UTC
sigh - I want to test this, but it's going to have to wait for the other side of the cogl rebuild.
Comment 6 Adam Williamson 2014-02-21 09:56:04 UTC
Looks good in at least one case I've noticed on the fedlet - rotating the screen used to kill the background, now it pops out briefly (probably only noticeable because of a performance bug which makes everything sloooooow on it...) and then comes back quickly. Also have the patches applied on my desktop, will keep an eye out.
Comment 7 drago01 2014-02-21 10:03:55 UTC
Review of attachment 269823 [details] [review]:

LG and does not crash here anymore.
Comment 8 Ray Strode [halfline] 2014-02-26 21:17:31 UTC
Review of attachment 269823 [details] [review]:

Jasper asked me to look at this, too.  While the patch may fix the bug I think it's a little hard to read.  It does too many things at once:

1) changes the code to always copy the background content instead of only copying it for secondary callers
2) Adds code style changes
3) changes terminology (i.e. pendingFileLoad objects become "info" objects)
4) moves large chunks of the code to a helper function
5) increases code clarity by replacing a nested loop with a call to indexOf

While I think most of those changes are fine in pricinple, they are sort of orthogonal, and make it hard to follow the progression of changes in the patch.

I really recommend splitting them up for future code spelunking sanity.  I actually needed to split the code out to understand what the patch was doing, anyway, so i'll attach what I did here (untested changes).
Comment 9 Ray Strode [halfline] 2014-02-26 21:19:12 UTC
Created attachment 270420 [details] [review]
background: always copy background content when loading into cache

Copying is actually a lightweight operation, so trying to avoid it just adds
code complexity for little gain.

Based on work from Jasper St. Pierre <jstpierre@macheye.net>
Comment 10 Ray Strode [halfline] 2014-02-26 21:19:16 UTC
Created attachment 270421 [details] [review]
background: refactor file loading

This commit moves the code around a bit such that the
caller gets allocated up front and then a file load is either
found or created to attach the caller to.

Functionally, the code is the same, it's just now factored in a way
that will make it easier to fix a bug with cancellation later.
Comment 11 Ray Strode [halfline] 2014-02-26 21:19:20 UTC
Created attachment 270422 [details] [review]
background: move file loading to separate function

This improves readability.

Based on work from Jasper St. Pierre <jstpierre@macheye.net>
Comment 12 Ray Strode [halfline] 2014-02-26 21:19:25 UTC
Created attachment 270423 [details] [review]
background: get rid of nested loop when finishing file loading

At the moment when a file is loaded, we iterate through the list of
pending file loads and ignore any unrelated to the file, then iterate
all the callers of the related file loads and finish them.

In fact, there can only ever be one pending file load related to the
file, and we already know it, so we can avoid the ugly nested loops.
Comment 13 Ray Strode [halfline] 2014-02-26 21:19:29 UTC
Created attachment 270424 [details] [review]
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>
Comment 14 Jasper St. Pierre (not reading bugmail) 2014-02-26 21:25:18 UTC
Review of attachment 270422 [details] [review]:

Hm, is this really necessary? I don't think it helps that much, and I don't see anything in future commits calling finishFileLoad. Can we drop this one?

::: js/ui/background.js
@@ +168,3 @@
+    },
+
+    _finishFileLoad: function(fileLoad) {

I don't like this name. _finish implies some operation has finished, but here, it's just really a continuation of the above function.

@@ +187,3 @@
                                                   let pendingLoad = this._pendingFileLoads[i];
+                                                  if (pendingLoad.filename != filename ||
+                                                      pendingLoad.style != style)

Were these meant to be fileLoad.filename and fileLoad.style?
Comment 15 Jasper St. Pierre (not reading bugmail) 2014-02-26 21:26:01 UTC
Review of attachment 270423 [details] [review]:

::: js/ui/background.js
@@ +184,3 @@
                                               }
 
+                                              for (let j = 0; j < fileLoad.callers.length; j++) {

This should probably be renamed to 'i'.

@@ +185,3 @@
 
+                                              for (let j = 0; j < fileLoad.callers.length; j++) {
+                                                  if (fileLoad.callers[j].onFinished) {

We should probably have:

    let caller = fileLoad.callers[i];
Comment 16 Jasper St. Pierre (not reading bugmail) 2014-02-26 21:27:05 UTC
Review of attachment 270420 [details] [review]:

OK.
Comment 17 Jasper St. Pierre (not reading bugmail) 2014-02-26 21:27:30 UTC
Review of attachment 270421 [details] [review]:

OK.
Comment 18 Jasper St. Pierre (not reading bugmail) 2014-02-26 21:29:26 UTC
Review of attachment 270424 [details] [review]:

Yep.
Comment 19 Ray Strode [halfline] 2014-02-26 21:49:05 UTC
(Chatted with Jasper a bit on IRC, since my earlier comment wasn't too clear)
The patches attached earlier weren't really meant to go to git.  They were just output from me deconstructing attachment 269823 [details] [review]

Marking them needs-work since they're untested, probably have typos, etc.
Comment 20 Jasper St. Pierre (not reading bugmail) 2014-03-12 16:23:27 UTC
Created attachment 271614 [details] [review]
background: always copy background content when loading into cache

Copying is actually a lightweight operation, so trying to avoid it just adds
code complexity for little gain.

Based on work from Jasper St. Pierre <jstpierre@macheye.net>
Comment 21 Jasper St. Pierre (not reading bugmail) 2014-03-12 16:23:32 UTC
Created attachment 271615 [details] [review]
background: refactor file loading

This commit moves the code around a bit such that the
caller gets allocated up front and then a file load is either
found or created to attach the caller to.

Functionally, the code is the same, it's just now factored in a way
that will make it easier to fix a bug with cancellation later.
Comment 22 Jasper St. Pierre (not reading bugmail) 2014-03-12 16:23:37 UTC
Created attachment 271616 [details] [review]
background: get rid of nested loop when finishing file loading

At the moment when a file is loaded, we iterate through the list of
pending file loads and ignore any unrelated to the file, then iterate
all the callers of the related file loads and finish them.

In fact, there can only ever be one pending file load related to the
file, and we already know it, so we can avoid the ugly nested loops.
Comment 23 Jasper St. Pierre (not reading bugmail) 2014-03-12 16:23:40 UTC
Created attachment 271617 [details] [review]
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>
Comment 24 Ray Strode [halfline] 2014-03-12 16:28:52 UTC
Review of attachment 271614 [details] [review]:

sure.
Comment 25 Ray Strode [halfline] 2014-03-12 16:34:13 UTC
Review of attachment 271615 [details] [review]:

k
Comment 26 Ray Strode [halfline] 2014-03-12 16:37:10 UTC
Review of attachment 271616 [details] [review]:

yup.
Comment 27 Ray Strode [halfline] 2014-03-12 16:37:50 UTC
Review of attachment 271617 [details] [review]:

++
Comment 28 Jasper St. Pierre (not reading bugmail) 2014-03-12 16:40:11 UTC
Attachment 271614 [details] pushed as ec6facb - background: always copy background content when loading into cache
Attachment 271615 [details] pushed as e917b7c - background: refactor file loading
Attachment 271616 [details] pushed as fdf264f - background: get rid of nested loop when finishing file loading
Attachment 271617 [details] pushed as 55d1c7e - background: fix cancellable issue