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

Bug#717146: pu: package gnome-shell/3.4.2-7+deb7u1



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: pu

Hi,

please find attached a proposed update for gnome-shell. It includes 
these changes:
 - a bugfix in the “gdm-shell” mode of the login manager;
 - a move of the first GC pass much earlier in the session, to avoid 
   losing several minutes worth of work if it locks up (I hope you 
   remember the trouble with this crappy GC during the freeze);
 - a watchdog to suicide the process (and let gnome-session restart it) 
   if the GC actually locks up.

Unfortunately I couldn’t have definite confirmation, in sid, that the 
latter change does the trick for the handful of users affected by the 
deadlock, since most of them migrated to gnome-fallback or another DE, 
but it should be harmless, and from my testing of a simulated deadlock, 
it worked.

Thanks for considering,
-- 
Joss
Index: debian/changelog
===================================================================
--- debian/changelog	(révision 38749)
+++ debian/changelog	(copie de travail)
@@ -1,3 +1,20 @@
+gnome-shell (3.4.2-7+deb7u1) UNRELEASED; urgency=low
+
+  [ Josselin Mouette ]
+  * 30_lockup_gc.patch:
+    + Run the GC a first time after 15 seconds, and next every 10 
+      minutes. This is to avoid running into a deadlock (which often 
+      happens the first time) and lose 10 minutes of work.
+    + Add a watchdog thread to suicide the process after 10 seconds if 
+      the GC locks up.
+
+  [ Sébastien Villemot ]
+  * debian/patches/61-disable-restart-buttons.patch: new patch, backported from
+    upstream. Makes the 'disable-restart-buttons' option of gdm-shell work.
+    (Closes: #714862)
+
+ -- Josselin Mouette <joss@debian.org>  Thu, 20 Jun 2013 00:56:14 +0200
+
 gnome-shell (3.4.2-7) unstable; urgency=low
 
   [ Michael Biebl ]
Index: debian/patches/61-disable-restart-buttons.patch
===================================================================
--- debian/patches/61-disable-restart-buttons.patch	(révision 0)
+++ debian/patches/61-disable-restart-buttons.patch	(révision 39004)
@@ -0,0 +1,62 @@
+Description: loginScreen: Add support for 'disable-restart-buttons'
+ GDM's GSettings schema contains a 'disable-restart-buttons' key
+ that currently is only supported by the fallback greeter.
+ Implement support in the shell greeter as well.
+ .
+ Compared to the original upstream fix, this patch handles gracefully the case
+ where gdm's schema are not available, in order to prevent crashes if gdm3 is
+ not installed.
+Origin: backport, https://git.gnome.org/browse/gnome-shell/commit/?id=86c85a752eacf4f89d8d5ca5ef1000692385c1af
+Bug: https://bugzilla.gnome.org/show_bug.cgi?id=686247
+Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=714862
+Last-Update: 2013-07-03
+--- a/js/gdm/powerMenu.js
++++ b/js/gdm/powerMenu.js
+@@ -18,6 +18,7 @@
+  * 02111-1307, USA.
+  */
+ 
++const Gio = imports.gi.Gio;
+ const Lang = imports.lang;
+ const UPowerGlib = imports.gi.UPowerGlib;
+ 
+@@ -27,6 +28,8 @@
+ const PanelMenu = imports.ui.panelMenu;
+ const PopupMenu = imports.ui.popupMenu;
+ 
++const _LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
++
+ const PowerMenuButton = new Lang.Class({
+     Name: 'PowerMenuButton',
+     Extends: PanelMenu.SystemStatusButton,
+@@ -40,6 +43,12 @@
+         else
+             this._consoleKitManager = new ConsoleKit.ConsoleKitManager();
+ 
++        if (Gio.Settings.list_schemas().indexOf(_LOGIN_SCREEN_SCHEMA) != -1) {
++            this._settings = new Gio.Settings({ schema: _LOGIN_SCREEN_SCHEMA });
++            this._settings.connect('changed::disable-restart-buttons',
++                                   Lang.bind(this, this._updateVisibility));
++        }
++
+         this._createSubMenu();
+ 
+         this._upClient.connect('notify::can-suspend',
+@@ -59,8 +68,16 @@
+         this._updateHaveRestart();
+     },
+ 
++    _hasDisableRestartButtons: function() {
++        if (this._settings)
++            return this._settings.get_boolean('disable-restart-buttons');
++        else
++            return false;
++    },
++
+     _updateVisibility: function() {
+-        if (!this._haveSuspend && !this._haveShutdown && !this._haveRestart)
++        if ((!this._haveSuspend && !this._haveShutdown && !this._haveRestart)
++            || this._hasDisableRestartButtons())
+             this.actor.hide();
+         else
+             this.actor.show();
Index: debian/patches/series
===================================================================
--- debian/patches/series	(révision 38749)
+++ debian/patches/series	(copie de travail)
@@ -15,3 +15,4 @@
 33-screen-reader-l10n.patch
 40-force-online.patch
 50-remove-folks-integration.patch
+61-disable-restart-buttons.patch
Index: debian/patches/30_lockup_gc.patch
===================================================================
--- debian/patches/30_lockup_gc.patch	(révision 38749)
+++ debian/patches/30_lockup_gc.patch	(copie de travail)
@@ -1,24 +1,30 @@
 Index: gnome-shell-3.4.2/src/shell-global.c
 ===================================================================
---- gnome-shell-3.4.2.orig/src/shell-global.c	2012-07-20 19:38:25.000000000 +0200
-+++ gnome-shell-3.4.2/src/shell-global.c	2013-01-03 00:58:06.396025821 +0100
-@@ -45,6 +45,7 @@ static ShellGlobal *the_object = NULL;
+--- gnome-shell-3.4.2.orig/src/shell-global.c	2013-06-20 20:19:51.447692008 +0200
++++ gnome-shell-3.4.2/src/shell-global.c	2013-06-20 20:20:28.683874046 +0200
+@@ -45,6 +45,8 @@ static ShellGlobal *the_object = NULL;
  static void grab_notify (GtkWidget *widget, gboolean is_grab, gpointer user_data);
  static void shell_global_on_gc (GjsContext   *context,
                                  ShellGlobal  *global);
 +static gboolean on_gc_timeout (gpointer data);
++static gpointer gc_watchdog_func (gpointer data);
  
  struct _ShellGlobal {
    GObject parent;
-@@ -92,6 +93,7 @@ struct _ShellGlobal {
+@@ -92,6 +94,12 @@ struct _ShellGlobal {
    guint32 xdnd_timestamp;
  
    gint64 last_gc_end_time;
 +  guint gc_timer;
++  gboolean gc_timer_first;
++  gboolean gc_is_running;
++  GThread *gc_watchdog;
++  GMutex gc_is_running_mutex;
++  GCond gc_watchdog_cond;
  };
  
  enum {
-@@ -277,8 +279,13 @@ shell_global_init (ShellGlobal *global)
+@@ -277,8 +285,19 @@ shell_global_init (ShellGlobal *global)
                                       "js-version", "1.8",
                                       "gc-notifications", TRUE,
                                       NULL);
@@ -29,10 +35,16 @@
 +     minutes or so. */
 +  global->gc_timer = g_timeout_add_seconds (600, on_gc_timeout, global);
 +
++  /* Since it can deadlock more easily the first time, run it once right
++     after startup, so that it locks up soon and not after 10 minutes worth
++     of work. */
++  global->gc_timer_first = TRUE;
++  g_timeout_add_seconds (15, on_gc_timeout, global);
++
    g_strfreev (search_path);
  }
  
-@@ -1605,13 +1612,6 @@ run_leisure_functions (gpointer data)
+@@ -1605,13 +1624,6 @@ run_leisure_functions (gpointer data)
    if (global->work_count > 0)
      return FALSE;
  
@@ -46,7 +58,7 @@
    /* No leisure closures, so we are done */
    if (global->leisure_closures == NULL)
      return FALSE;
-@@ -1635,6 +1635,16 @@ run_leisure_functions (gpointer data)
+@@ -1635,6 +1647,58 @@ run_leisure_functions (gpointer data)
    return FALSE;
  }
  
@@ -54,12 +66,86 @@
 +on_gc_timeout (gpointer data)
 +{
 +  ShellGlobal *global = data;
++
++  /* Set up a watchdog thread to suicide the process if the GC is on deadlock */
++  if (global->gc_watchdog == NULL)
++    global->gc_watchdog = g_thread_new ("gc-watchdog", gc_watchdog_func, global);
++
++  g_mutex_lock (&global->gc_is_running_mutex);
++  global->gc_is_running = TRUE;
++  g_cond_signal (&global->gc_watchdog_cond);
++  g_mutex_unlock (&global->gc_is_running_mutex);
++
 +  gjs_context_gc (global->js_context);
 +
++  g_mutex_lock (&global->gc_is_running_mutex);
++  global->gc_is_running = FALSE;
++  g_cond_signal (&global->gc_watchdog_cond);
++  g_mutex_unlock (&global->gc_is_running_mutex);
++
++  if (global->gc_timer_first) {
++    /* The first time, the timeout is much shorter; cancel this timer only */
++    global->gc_timer_first = FALSE;
++    return FALSE;
++  }
 +  return TRUE;
 +}
 +
++static gpointer
++gc_watchdog_func (gpointer data)
++{
++  ShellGlobal *global = data;
++  gint64 end_time;
++  g_mutex_lock (&global->gc_is_running_mutex);
++  while (TRUE)
++  {
++    /* Wait for a GC to start */
++    while (!global->gc_is_running)
++      g_cond_wait (&global->gc_watchdog_cond, &global->gc_is_running_mutex);
++    /* Now watch for the GC for 10 seconds */
++    end_time = g_get_monotonic_time () + 10 * G_TIME_SPAN_SECOND;
++    while (global->gc_is_running)
++      if (!g_cond_wait_until (&global->gc_watchdog_cond, &global->gc_is_running_mutex, end_time))
++        {
++          /* Ka-BOOM */
++          g_error ("Garbage collector went into timeout after 10 seconds");
++          return NULL;
++        }
++  }
++}
 +
  static void
  schedule_leisure_functions (ShellGlobal *global)
  {
+Index: gnome-shell-3.4.2/configure.ac
+===================================================================
+--- gnome-shell-3.4.2.orig/configure.ac	2013-06-20 20:19:51.447692008 +0200
++++ gnome-shell-3.4.2/configure.ac	2013-06-20 20:19:51.435691949 +0200
+@@ -75,6 +75,7 @@ GCR_MIN_VERSION=3.3.90
+ 
+ # Collect more than 20 libraries for a prize!
+ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
++			       gthread-2.0
+ 			       libxml-2.0
+                                gtk+-3.0 >= $GTK_MIN_VERSION
+                                folks >= $FOLKS_MIN_VERSION
+Index: gnome-shell-3.4.2/src/main.c
+===================================================================
+--- gnome-shell-3.4.2.orig/src/main.c	2013-06-20 20:19:51.447692008 +0200
++++ gnome-shell-3.4.2/src/main.c	2013-06-20 20:19:51.439691969 +0200
+@@ -10,6 +10,7 @@
+ 
+ #include <clutter/clutter.h>
+ #include <clutter/x11/clutter-x11.h>
++#include <glib.h>
+ #include <gdk/gdk.h>
+ #include <gdk/gdkx.h>
+ #include <gtk/gtk.h>
+@@ -275,6 +276,7 @@ main (int argc, char **argv)
+   TpDebugSender *sender;
+ 
+   g_type_init ();
++  g_thread_init (NULL);
+ 
+   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
Index: gnome-shell-3.4.2/src/shell-global.c
===================================================================
--- gnome-shell-3.4.2.orig/src/shell-global.c	2013-06-20 20:19:51.447692008 +0200
+++ gnome-shell-3.4.2/src/shell-global.c	2013-06-20 20:20:28.683874046 +0200
@@ -45,6 +45,8 @@ static ShellGlobal *the_object = NULL;
 static void grab_notify (GtkWidget *widget, gboolean is_grab, gpointer user_data);
 static void shell_global_on_gc (GjsContext   *context,
                                 ShellGlobal  *global);
+static gboolean on_gc_timeout (gpointer data);
+static gpointer gc_watchdog_func (gpointer data);
 
 struct _ShellGlobal {
   GObject parent;
@@ -92,6 +94,12 @@ struct _ShellGlobal {
   guint32 xdnd_timestamp;
 
   gint64 last_gc_end_time;
+  guint gc_timer;
+  gboolean gc_timer_first;
+  gboolean gc_is_running;
+  GThread *gc_watchdog;
+  GMutex gc_is_running_mutex;
+  GCond gc_watchdog_cond;
 };
 
 enum {
@@ -277,8 +285,19 @@ shell_global_init (ShellGlobal *global)
                                      "js-version", "1.8",
                                      "gc-notifications", TRUE,
                                      NULL);
+
   g_signal_connect (global->js_context, "gc", G_CALLBACK (shell_global_on_gc), global);
 
+  /* Since the GC has a tendency to deadlock, only run it once every 10
+     minutes or so. */
+  global->gc_timer = g_timeout_add_seconds (600, on_gc_timeout, global);
+
+  /* Since it can deadlock more easily the first time, run it once right
+     after startup, so that it locks up soon and not after 10 minutes worth
+     of work. */
+  global->gc_timer_first = TRUE;
+  g_timeout_add_seconds (15, on_gc_timeout, global);
+
   g_strfreev (search_path);
 }
 
@@ -1605,13 +1624,6 @@ run_leisure_functions (gpointer data)
   if (global->work_count > 0)
     return FALSE;
 
-  /* Previously we called gjs_maybe_gc().  However, it simply doesn't
-   * trigger often enough.  Garbage collection is very fast here, so
-   * let's just aggressively GC.  This will help avoid both heap
-   * fragmentation, and the GC kicking in when we don't want it to.
-   */
-  gjs_context_gc (global->js_context);
-
   /* No leisure closures, so we are done */
   if (global->leisure_closures == NULL)
     return FALSE;
@@ -1635,6 +1647,58 @@ run_leisure_functions (gpointer data)
   return FALSE;
 }
 
+static gboolean
+on_gc_timeout (gpointer data)
+{
+  ShellGlobal *global = data;
+
+  /* Set up a watchdog thread to suicide the process if the GC is on deadlock */
+  if (global->gc_watchdog == NULL)
+    global->gc_watchdog = g_thread_new ("gc-watchdog", gc_watchdog_func, global);
+
+  g_mutex_lock (&global->gc_is_running_mutex);
+  global->gc_is_running = TRUE;
+  g_cond_signal (&global->gc_watchdog_cond);
+  g_mutex_unlock (&global->gc_is_running_mutex);
+
+  gjs_context_gc (global->js_context);
+
+  g_mutex_lock (&global->gc_is_running_mutex);
+  global->gc_is_running = FALSE;
+  g_cond_signal (&global->gc_watchdog_cond);
+  g_mutex_unlock (&global->gc_is_running_mutex);
+
+  if (global->gc_timer_first) {
+    /* The first time, the timeout is much shorter; cancel this timer only */
+    global->gc_timer_first = FALSE;
+    return FALSE;
+  }
+  return TRUE;
+}
+
+static gpointer
+gc_watchdog_func (gpointer data)
+{
+  ShellGlobal *global = data;
+  gint64 end_time;
+  g_mutex_lock (&global->gc_is_running_mutex);
+  while (TRUE)
+  {
+    /* Wait for a GC to start */
+    while (!global->gc_is_running)
+      g_cond_wait (&global->gc_watchdog_cond, &global->gc_is_running_mutex);
+    /* Now watch for the GC for 10 seconds */
+    end_time = g_get_monotonic_time () + 10 * G_TIME_SPAN_SECOND;
+    while (global->gc_is_running)
+      if (!g_cond_wait_until (&global->gc_watchdog_cond, &global->gc_is_running_mutex, end_time))
+        {
+          /* Ka-BOOM */
+          g_error ("Garbage collector went into timeout after 10 seconds");
+          return NULL;
+        }
+  }
+}
+
 static void
 schedule_leisure_functions (ShellGlobal *global)
 {
Index: gnome-shell-3.4.2/configure.ac
===================================================================
--- gnome-shell-3.4.2.orig/configure.ac	2013-06-20 20:19:51.447692008 +0200
+++ gnome-shell-3.4.2/configure.ac	2013-06-20 20:19:51.435691949 +0200
@@ -75,6 +75,7 @@ GCR_MIN_VERSION=3.3.90
 
 # Collect more than 20 libraries for a prize!
 PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
+			       gthread-2.0
 			       libxml-2.0
                                gtk+-3.0 >= $GTK_MIN_VERSION
                                folks >= $FOLKS_MIN_VERSION
Index: gnome-shell-3.4.2/src/main.c
===================================================================
--- gnome-shell-3.4.2.orig/src/main.c	2013-06-20 20:19:51.447692008 +0200
+++ gnome-shell-3.4.2/src/main.c	2013-06-20 20:19:51.439691969 +0200
@@ -10,6 +10,7 @@
 
 #include <clutter/clutter.h>
 #include <clutter/x11/clutter-x11.h>
+#include <glib.h>
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
@@ -275,6 +276,7 @@ main (int argc, char **argv)
   TpDebugSender *sender;
 
   g_type_init ();
+  g_thread_init (NULL);
 
   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");

Reply to: