[gnome-maps/wip/mlundblad/unref-contact-store] application: Dispose contact store on window destroy




commit 1c80648f9e3da35635b04538329ea5b5d72eb6b1
Author: Marcus Lundblad <ml dfupdate se>
Date:   Mon Jun 20 19:21:08 2022 +0200

    application: Dispose contact store on window destroy
    
    When quitting through closing the window, the contact
    store is disposed in the final GJS GC sweep, which
    seems to cause some race condition with respect to
    the main loop.
    As a workaround to this, manually dispose the store
    in this callback, and set it to null.
    Also guard some calls involving contact store with
    nullish checks to avoid possible use-after-free.

 src/application.js | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)
---
diff --git a/src/application.js b/src/application.js
index 0d164870..4c2f7c39 100644
--- a/src/application.js
+++ b/src/application.js
@@ -106,7 +106,7 @@ export class Application extends Gtk.Application {
     }
 
     _showContact(id) {
-        Application.contactStore.lookup(id, (contact) => {
+        Application.contactStore?.lookup(id, (contact) => {
             this.mark_busy();
             if (!contact) {
                 this.unmark_busy();
@@ -125,13 +125,15 @@ export class Application extends Gtk.Application {
 
         let id = parameter.deep_unpack();
 
-        if (Application.contactStore.state === Maps.ContactStoreState.LOADED) {
-            this. _showContact(id);
-        } else {
-            Utils.once(Application.contactStore, 'notify::state', () => {
-                if (Application.contactStore.state === Maps.ContactStoreState.LOADED)
-                    this._showContact(id);
-            });
+        if (Application.contactStore) {
+            if (Application.contactStore.state === Maps.ContactStoreState.LOADED) {
+                this. _showContact(id);
+            } else {
+                Utils.once(Application.contactStore, 'notify::state', () => {
+                    if (Application.contactStore.state === Maps.ContactStoreState.LOADED)
+                        this._showContact(id);
+                });
+            }
         }
     }
 
@@ -158,9 +160,11 @@ export class Application extends Gtk.Application {
     }
 
     _addContacts() {
-        let contacts = Application.contactStore.get_contacts();
+        if (Application.contactStore) {
+            let contacts = Application.contactStore.get_contacts();
 
-        this._addContactsRecursive(contacts, 0);
+            this._addContactsRecursive(contacts, 0);
+        }
     }
 
     _addContactsRecursive(contacts, index) {
@@ -429,6 +433,12 @@ export class Application extends Gtk.Application {
     }
 
     _onWindowDestroy(window) {
+        /* as a workaround, manually dispose the contact store here
+         * to avoid a crash when it's being disposed as a result of the
+         * GC sweep at exit, probably due to some event loop race condition
+         */
+        Application.contactStore.run_dispose();
+        Application.contactStore = null;
         this._mainWindow = null;
     }
 }


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