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>
This commit is contained in:
parent
a2cf75ccd5
commit
c41657bc4f
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user