[mutter] wayland/activation: Remove token from hash table on timeout



commit c41657bc4faf790a0f14e634490b7fffa844e0b4
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Mon Nov 8 10:44:17 2021 +0100

    wayland/activation: Remove token from hash table on timeout
    
    When an activation times out, we'll be signalled two signals on the
    startup sequence object: "timeout", and "complete".
    
    Normally, the "complete" signal is emitted when a startup sequence is
    completed succesfully by it being used for activation, and in this case,
    the xdg_activation implementation should remove the sequence from the
    startup notification machinery.
    
    However, in the timeout case, we should not remove it, as the startup
    notification machinery itself will deal with this. If we would, we'd end
    up with use-after-free issues, as the sequence would be finalized when
    removed the first time.
    
    To avoid this, just clean up the Wayland side in the "timeout" signal
    handler, leaving the "complete" signal handler early out if it was
    already handled by it.
    
    This avoids crashes like:
    
      0) g_type_check_instance (type_instance=type_instance@entry=0xdd6740)
      1) g_signal_handlers_disconnect_matched (instance=0xdd6740, ...)
      2) meta_startup_notification_remove_sequence (sn=0x4cc890,
                                                    seq=0xdd6740) at
           ../src/core/startup-notification.c:544
      3) startup_sequence_timeout (data=0x4cc890, ...) at
           ../src/core/startup-notification.c:504
      4) g_timeout_dispatch (...) at ../glib/gmain.c:4933
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2081>

 src/wayland/meta-wayland-activation.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
---
diff --git a/src/wayland/meta-wayland-activation.c b/src/wayland/meta-wayland-activation.c
index 07bc1adaad..20fb1f1e98 100644
--- a/src/wayland/meta-wayland-activation.c
+++ b/src/wayland/meta-wayland-activation.c
@@ -51,6 +51,7 @@ struct _MetaXdgActivationToken
   char *token;
   uint32_t serial;
   gulong sequence_complete_id;
+  gulong sequence_timeout_id;
   gboolean committed;
 };
 
@@ -102,11 +103,23 @@ sequence_complete_cb (MetaStartupSequence    *sequence,
   MetaWaylandActivation *activation = token->activation;
   MetaDisplay *display = meta_get_display ();
 
+  if (!g_hash_table_contains (activation->tokens, token->token))
+    return;
+
   meta_startup_notification_remove_sequence (display->startup_notification,
                                              sequence);
   g_hash_table_remove (activation->tokens, token->token);
 }
 
+static void
+sequence_timeout_cb (MetaStartupSequence    *sequence,
+                     MetaXdgActivationToken *token)
+{
+  MetaWaylandActivation *activation = token->activation;
+
+  g_hash_table_remove (activation->tokens, token->token);
+}
+
 static char *
 create_startup_token (MetaWaylandActivation *activation,
                       MetaDisplay           *display)
@@ -158,6 +171,11 @@ token_commit (struct wl_client   *client,
                       "complete",
                       G_CALLBACK (sequence_complete_cb),
                       token);
+  token->sequence_timeout_id =
+    g_signal_connect (token->sequence,
+                      "timeout",
+                      G_CALLBACK (sequence_timeout_cb),
+                      token);
 
   meta_startup_notification_add_sequence (display->startup_notification,
                                           token->sequence);
@@ -188,6 +206,8 @@ meta_xdg_activation_token_free (MetaXdgActivationToken *token)
     {
       g_clear_signal_handler (&token->sequence_complete_id,
                               token->sequence);
+      g_clear_signal_handler (&token->sequence_timeout_id,
+                              token->sequence);
       g_clear_object (&token->sequence);
     }
 


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