[glib] gapplication: don't rely on cmdline being finalized immediately



commit c5748328bee08e322997cc4703c372f6866a1693
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Fri Sep 13 11:38:47 2013 -0700

    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

 gio/gapplicationimpl-dbus.c |   26 +++++++++++++++++++++++---
 1 files changed, 23 insertions(+), 3 deletions(-)
---
diff --git a/gio/gapplicationimpl-dbus.c b/gio/gapplicationimpl-dbus.c
index d15e643..5c948cc 100644
--- a/gio/gapplicationimpl-dbus.c
+++ b/gio/gapplicationimpl-dbus.c
@@ -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)


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