[gnome-shell] gdm: disconnect signals



commit 8d3ff56846163e9ce9391bbe9f1f09a06a6baac7
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Thu Oct 9 14:10:12 2014 -0400

    gdm: disconnect signals
    
    Many signal connections on global objects and on non-widgets were not
    disconnected when the unlock screen was destroyed, causing leaks.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=738256

 js/gdm/authPrompt.js  |    3 +-
 js/gdm/loginDialog.js |   77 ++++++++++++++++++++++++++++++++++--------------
 js/gdm/util.js        |   41 +++++++++++++++++++-------
 3 files changed, 85 insertions(+), 36 deletions(-)
---
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
index 3b435de..ca4db89 100644
--- a/js/gdm/authPrompt.js
+++ b/js/gdm/authPrompt.js
@@ -134,8 +134,7 @@ const AuthPrompt = new Lang.Class({
     },
 
     _onDestroy: function() {
-        this._userVerifier.clear();
-        this._userVerifier.disconnectAll();
+        this._userVerifier.destroy();
         this._userVerifier = null;
     },
 
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
index cbb5721..ceaccaa 100644
--- a/js/gdm/loginDialog.js
+++ b/js/gdm/loginDialog.js
@@ -64,6 +64,8 @@ const UserListItem = new Lang.Class({
                                      reactive: true,
                                      x_align: St.Align.START,
                                      x_fill: true });
+        this.actor.connect('destroy',
+                           Lang.bind(this, this._onDestroy));
 
         this._userWidget = new UserWidget.UserWidget(this.user);
         layout.add(this._userWidget.actor);
@@ -87,6 +89,10 @@ const UserListItem = new Lang.Class({
             this.actor.remove_style_pseudo_class('logged-in');
     },
 
+    _onDestroy: function() {
+        this._user.disconnect(this._userChangedId);
+    },
+
     _onClicked: function() {
         this.emit('activate');
     },
@@ -373,13 +379,12 @@ const LoginDialog = new Lang.Class({
         if (GLib.getenv('GDM_GREETER_TEST') != '1') {
             this._greeter = gdmClient.get_greeter_sync(null);
 
-            this._greeter.connect('default-session-name-changed',
-                                  Lang.bind(this, this._onDefaultSessionChanged));
-
-            this._greeter.connect('session-opened',
-                                  Lang.bind(this, this._onSessionOpened));
-            this._greeter.connect('timed-login-requested',
-                                  Lang.bind(this, this._onTimedLoginRequested));
+            this._defaultSessionChangedId = this._greeter.connect('default-session-name-changed',
+                                                                  Lang.bind(this, 
this._onDefaultSessionChanged));
+            this._sessionOpenedId = this._greeter.connect('session-opened',
+                                                          Lang.bind(this, this._onSessionOpened));
+            this._timedLoginRequestedId = this._greeter.connect('timed-login-requested',
+                                                                Lang.bind(this, 
this._onTimedLoginRequested));
         }
 
         this._settings = new Gio.Settings({ schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA });
@@ -394,8 +399,8 @@ const LoginDialog = new Lang.Class({
                                Lang.bind(this, this._updateLogo));
 
         this._textureCache = St.TextureCache.get_default();
-        this._textureCache.connect('texture-file-changed',
-                                   Lang.bind(this, this._updateLogoTexture));
+        this._updateLogoTextureId = this._textureCache.connect('texture-file-changed',
+                                                               Lang.bind(this, this._updateLogoTexture));
 
         this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box',
                                                     x_align: Clutter.ActorAlign.CENTER,
@@ -476,8 +481,8 @@ const LoginDialog = new Lang.Class({
         // If the user list is enabled, it should take key focus; make sure the
         // screen shield is initialized first to prevent it from stealing the
         // focus later
-        Main.layoutManager.connect('startup-complete',
-                                   Lang.bind(this, this._updateDisableUserList));
+        this._startupCompleteId = Main.layoutManager.connect('startup-complete',
+                                                             Lang.bind(this, this._updateDisableUserList));
     },
 
     _ensureUserListLoaded: function() {
@@ -665,10 +670,12 @@ const LoginDialog = new Lang.Class({
     },
 
     _gotGreeterSessionProxy: function(proxy) {
-        proxy.connect('g-properties-changed', Lang.bind(this, function() {
-            if (proxy.Active)
-                this._loginScreenSessionActivated();
-        }));
+        this._greeterSessionProxy = proxy;
+        this._greeterSessionProxyChangedId =
+            proxy.connect('g-properties-changed', Lang.bind(this, function() {
+                if (proxy.Active)
+                    this._loginScreenSessionActivated();
+            }));
     },
 
     _startSession: function(serviceName) {
@@ -890,6 +897,30 @@ const LoginDialog = new Lang.Class({
             this._userManager.disconnect(this._userManagerLoadedId);
             this._userManagerLoadedId = 0;
         }
+        if (this._userAddedId) {
+            this._userManager.disconnect(this._userAddedId);
+            this._userAddedId = 0;
+        }
+        if (this._userRemovedId) {
+            this._userManager.disconnect(this._userRemovedId);
+            this._userRemovedId = 0;
+        }
+        this._textureCache.disconnect(this._updateLogoTextureId);
+        Main.layoutManager.disconnect(this._startupCompleteId);
+        if (this._settings) {
+            this._settings.run_dispose();
+            this._settings = null;
+        }
+        if (this._greeter) {
+            this._greeter.disconnect(this._defaultSessionChangedId);
+            this._greeter.disconnect(this._sessionOpenedId);
+            this._greeter.disconnect(this._timedLoginRequestedId);
+            this._greeter = null;
+        }
+        if (this._greeterSessionProxy) {
+            this._greeterSessionProxy.disconnect(this._greeterSessionProxyChangedId);
+            this._greeterSessionProxy = null;
+        }
     },
 
     _loadUserList: function() {
@@ -904,15 +935,15 @@ const LoginDialog = new Lang.Class({
             this._userList.addUser(users[i]);
         }
 
-        this._userManager.connect('user-added',
-                                  Lang.bind(this, function(userManager, user) {
-                                      this._userList.addUser(user);
-                                  }));
+        this._userAddedId = this._userManager.connect('user-added',
+                                                      Lang.bind(this, function(userManager, user) {
+                                                          this._userList.addUser(user);
+                                                      }));
 
-        this._userManager.connect('user-removed',
-                                  Lang.bind(this, function(userManager, user) {
-                                      this._userList.removeUser(user);
-                                  }));
+        this._userRemovedId = this._userManager.connect('user-removed',
+                                                        Lang.bind(this, function(userManager, user) {
+                                                            this._userList.removeUser(user);
+                                                        }));
 
         return GLib.SOURCE_REMOVE;
     },
diff --git a/js/gdm/util.js b/js/gdm/util.js
index c9d2055..6ddd371 100644
--- a/js/gdm/util.js
+++ b/js/gdm/util.js
@@ -142,10 +142,10 @@ const ShellUserVerifier = new Lang.Class({
         // after a user has been picked.
         this._checkForSmartcard();
 
-        this._smartcardManager.connect('smartcard-inserted',
-                                       Lang.bind(this, this._checkForSmartcard));
-        this._smartcardManager.connect('smartcard-removed',
-                                       Lang.bind(this, this._checkForSmartcard));
+        this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted',
+                                                                   Lang.bind(this, this._checkForSmartcard));
+        this._smartcardRemovedId = this._smartcardManager.connect('smartcard-removed',
+                                                                  Lang.bind(this, this._checkForSmartcard));
 
         this._messageQueue = [];
         this._messageQueueTimeoutId = 0;
@@ -159,8 +159,8 @@ const ShellUserVerifier = new Lang.Class({
         if (this._oVirtCredentialsManager.hasToken())
             this._oVirtUserAuthenticated(this._oVirtCredentialsManager.getToken());
 
-        this._oVirtCredentialsManager.connect('user-authenticated',
-                                              Lang.bind(this, this._oVirtUserAuthenticated));
+        this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated',
+                                                                               Lang.bind(this, 
this._oVirtUserAuthenticated));
     },
 
     begin: function(userName, hold) {
@@ -191,20 +191,37 @@ const ShellUserVerifier = new Lang.Class({
         }
     },
 
+    _clearUserVerifier: function() {
+        if (this._userVerifier) {
+            this._userVerifier.run_dispose();
+            this._userVerifier = null;
+        }
+    },
+
     clear: function() {
         if (this._cancellable) {
             this._cancellable.cancel();
             this._cancellable = null;
         }
 
-        if (this._userVerifier) {
-            this._userVerifier.run_dispose();
-            this._userVerifier = null;
-        }
-
+        this._clearUserVerifier();
         this._clearMessageQueue();
     },
 
+    destroy: function() {
+        this.clear();
+
+        this._settings.run_dispose();
+        this._settings = null;
+
+        this._smartcardManager.disconnect(this._smartcardInsertedId);
+        this._smartcardManager.disconnect(this._smartcardRemovedId);
+        this._smartcardManager = null;
+
+        this._oVirtCredentialsManager.disconnect(this._oVirtUserAuthenticatedId);
+        this._oVirtCredentialsManager = null;
+    },
+
     answerQuery: function(serviceName, answer) {
         if (!this.hasPendingMessages) {
             this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
@@ -326,6 +343,7 @@ const ShellUserVerifier = new Lang.Class({
 
     _reauthenticationChannelOpened: function(client, result) {
         try {
+            this._clearUserVerifier();
             this._userVerifier = client.open_reauthentication_channel_finish(result);
         } catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
             return;
@@ -349,6 +367,7 @@ const ShellUserVerifier = new Lang.Class({
 
     _userVerifierGot: function(client, result) {
         try {
+            this._clearUserVerifier();
             this._userVerifier = client.get_user_verifier_finish(result);
         } catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
             return;


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