mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-14 19:55:12 +01:00
gapplication: don't rely on cmdline being finalized immediately
The GApplicationCommandLine DBus implementation currently calls g_dbus_method_invocation_return_value() in its finalize() implementation only, relying on the object being destroyed after g_object_unref() is called on it inside g_application_impl_method_call(). While this is usually fine for C applications, when overriding the command_line vfunc from language bindings, the binding might add extra references to the object, which might not be released immediately - e.g. because they're garbage collected, or possibly even leaked. The same scenario could happen in a C application that decides to keep a reference to the passed-in GApplicationCommandLine object. To ensure the CommandLine DBus method always gets a reply after the invocation of command_line in the primary instance, explicitly send the message back before dropping our reference to the object. https://bugzilla.gnome.org/show_bug.cgi?id=708042
This commit is contained in:
parent
be2656f139
commit
c5748328be
@ -129,6 +129,9 @@ struct _GApplicationImpl
|
||||
static GApplicationCommandLine *
|
||||
g_dbus_command_line_new (GDBusMethodInvocation *invocation);
|
||||
|
||||
static void
|
||||
g_dbus_command_line_return (GApplicationCommandLine *cmdline);
|
||||
|
||||
static GVariant *
|
||||
g_application_impl_get_property (GDBusConnection *connection,
|
||||
const gchar *sender,
|
||||
@ -259,6 +262,8 @@ g_application_impl_method_call (GDBusConnection *connection,
|
||||
g_application_command_line_set_exit_status (cmdline, status);
|
||||
class->after_emit (impl->app, platform_data);
|
||||
g_variant_unref (platform_data);
|
||||
|
||||
g_dbus_command_line_return (cmdline);
|
||||
g_object_unref (cmdline);
|
||||
}
|
||||
else if (g_str_equal (method_name, "ActivateAction"))
|
||||
@ -787,6 +792,8 @@ typedef struct
|
||||
GDBusConnection *connection;
|
||||
const gchar *bus_name;
|
||||
const gchar *object_path;
|
||||
|
||||
gboolean returned;
|
||||
} GDBusCommandLine;
|
||||
|
||||
|
||||
@ -852,16 +859,29 @@ g_dbus_command_line_get_stdin (GApplicationCommandLine *cmdline)
|
||||
}
|
||||
|
||||
static void
|
||||
g_dbus_command_line_finalize (GObject *object)
|
||||
g_dbus_command_line_return (GApplicationCommandLine *cmdline)
|
||||
{
|
||||
GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
|
||||
GDBusCommandLine *gdbcl = (GDBusCommandLine *) object;
|
||||
GDBusCommandLine *gdbcl = (GDBusCommandLine *) cmdline;
|
||||
gint status;
|
||||
|
||||
if (gdbcl->returned)
|
||||
return;
|
||||
|
||||
gdbcl->returned = TRUE;
|
||||
|
||||
status = g_application_command_line_get_exit_status (cmdline);
|
||||
|
||||
g_dbus_method_invocation_return_value (gdbcl->invocation,
|
||||
g_variant_new ("(i)", status));
|
||||
}
|
||||
|
||||
static void
|
||||
g_dbus_command_line_finalize (GObject *object)
|
||||
{
|
||||
GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
|
||||
GDBusCommandLine *gdbcl = (GDBusCommandLine *) object;
|
||||
|
||||
g_dbus_command_line_return (cmdline);
|
||||
g_object_unref (gdbcl->invocation);
|
||||
|
||||
G_OBJECT_CLASS (g_dbus_command_line_parent_class)
|
||||
|
Loading…
x
Reference in New Issue
Block a user