]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Work around a timer leak with GTK 2.4.22 on openSUSE 13.1.
authorSimon Tatham <anakin@pobox.com>
Tue, 8 Jul 2014 22:22:12 +0000 (22:22 +0000)
committerSimon Tatham <anakin@pobox.com>
Tue, 8 Jul 2014 22:22:12 +0000 (22:22 +0000)
Mihkel Ader reports that on that system, timers apparently aren't
getting auto-destroyed when timer_trigger returns FALSE, so the change
in r10181 has caused GTK PuTTY to gradually allocate more and more
timers and consume more and more CPU as they all keep firing.

As far as I can see, this must surely be a bug in GTK 2 (the docs say
that timers _are_ auto-destroyed when their callback returns false),
and it doesn't seem to happen for me with GTK 2.4.23 on Ubuntu 14.04.
However, I'll try to work around it by _explicitly_ destroying each
old timer before we zero out the variable containing its id.

[originally from svn r10202]
[r10181 == e4c4bd20920e11458ab0ec0cd17c69b8bf7f6d00]

unix/gtkwin.c

index 4f626cbe1ace982cd4612c8d87f9d1a1c112cec8..fe597bf26206179f63290ee37b9320211211d525 100644 (file)
@@ -1477,12 +1477,13 @@ static gint timer_trigger(gpointer data)
     long ticks;
 
     /*
-     * The timer we last scheduled via gtk_timeout_add has just
-     * triggered, and since we're about to return FALSE, it won't be
-     * resumed. So zero out its id, in case we don't overwrite it in
-     * the next loop.
+     * Remove the timer we got here on; if we need another one, we'll
+     * set it up below.
      */
-    timer_id = 0;
+    if (timer_id) {
+       gtk_timeout_remove(timer_id);
+        timer_id = 0;
+    }
 
     if (run_timers(now, &next)) {
        then = now;
@@ -1496,8 +1497,9 @@ static gint timer_trigger(gpointer data)
     }
 
     /*
-     * Never let a timer resume. If we need another one, we've
-     * asked for it explicitly above.
+     * Returning FALSE means 'don't call this timer again', which
+     * _should_ be redundant given that we removed it above, but just
+     * in case, return FALSE anyway.
      */
     return FALSE;
 }