[gtk/tracing-for-merge: 7/8] GtkApplication: Add a profiler dbus api



commit 958d21171c66c8351be352b5e9f7bd9dd11dbd68
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat May 19 20:36:00 2018 +0100

    GtkApplication: Add a profiler dbus api
    
    Implement the org.gnome.Sysprof2.Profiler D-Bus
    api to let sysprof start and stop tracing at runtime,
    and get the data directly, via a passed fd.

 gtk/gtkapplication.c        | 149 ++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkapplicationprivate.h |   1 +
 2 files changed, 150 insertions(+)
---
diff --git a/gtk/gtkapplication.c b/gtk/gtkapplication.c
index 7adfc70f03..944d7fc8d9 100644
--- a/gtk/gtkapplication.c
+++ b/gtk/gtkapplication.c
@@ -21,6 +21,11 @@
 #include "config.h"
 
 #include "gtkapplication.h"
+#include "gdkprofilerprivate.h"
+
+#ifdef G_OS_UNIX
+#include <gio/gunixfdlist.h>
+#endif
 
 #include <stdlib.h>
 
@@ -603,6 +608,148 @@ gtk_application_finalize (GObject *object)
   G_OBJECT_CLASS (gtk_application_parent_class)->finalize (object);
 }
 
+#ifdef G_OS_UNIX
+
+static const gchar org_gnome_Sysprof2_Profiler_xml[] =
+  "<node>"
+    "<interface name='org.gnome.Sysprof2.Profiler'>"
+      "<method name='Start'>"
+        "<arg type='h' name='fd' direction='in'/>"
+      "</method>"
+      "<method name='Stop'>"
+      "</method>"
+    "</interface>"
+  "</node>";
+
+static GDBusInterfaceInfo *org_gnome_Sysprof2_Profiler;
+
+static void
+sysprof_profiler_method_call (GDBusConnection       *connection,
+                              const gchar           *sender,
+                              const gchar           *object_path,
+                              const gchar           *interface_name,
+                              const gchar           *method_name,
+                              GVariant              *parameters,
+                              GDBusMethodInvocation *invocation,
+                              gpointer               user_data)
+{
+  if (strcmp (method_name, "Start") == 0)
+    {
+      GDBusMessage *message;
+      GUnixFDList *fd_list;
+      int fd = -1;
+      int idx;
+
+      if (gdk_profiler_is_running ())
+        {
+          g_dbus_method_invocation_return_error (invocation,
+                                                 G_DBUS_ERROR,
+                                                 G_DBUS_ERROR_FAILED,
+                                                 "Profiler already running");
+          return;
+        }
+
+      g_variant_get (parameters, "(h)", &idx);
+
+      message = g_dbus_method_invocation_get_message (invocation);
+      fd_list = g_dbus_message_get_unix_fd_list (message);
+      if (fd_list)
+        fd = g_unix_fd_list_get (fd_list, idx, NULL);
+
+      gdk_profiler_start (fd);
+    }
+  else if (strcmp (method_name, "Stop") == 0)
+    {
+      if (!gdk_profiler_is_running ())
+        {
+          g_dbus_method_invocation_return_error (invocation,
+                                                 G_DBUS_ERROR,
+                                                 G_DBUS_ERROR_FAILED,
+                                                 "Profiler not running");
+          return;
+        }
+
+      gdk_profiler_stop ();
+    }
+  else
+    {
+      g_dbus_method_invocation_return_error (invocation,
+                                             G_DBUS_ERROR,
+                                             G_DBUS_ERROR_UNKNOWN_METHOD,
+                                             "Unknown method");
+      return;
+    }
+
+  g_dbus_method_invocation_return_value (invocation, NULL);
+}
+
+static gboolean
+gtk_application_dbus_register (GApplication     *application,
+                               GDBusConnection  *connection,
+                               const char       *obect_path,
+                               GError          **error)
+{
+  GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) application;
+  GDBusInterfaceVTable vtable = {
+    sysprof_profiler_method_call,
+    NULL,
+    NULL
+  };
+
+  if (org_gnome_Sysprof2_Profiler == NULL)
+    {
+      GDBusNodeInfo *info;
+
+      info = g_dbus_node_info_new_for_xml (org_gnome_Sysprof2_Profiler_xml, error);
+      if (info == NULL)
+        return FALSE;
+
+      org_gnome_Sysprof2_Profiler = g_dbus_node_info_lookup_interface (info, "org.gnome.Sysprof2.Profiler");
+      g_dbus_interface_info_ref (org_gnome_Sysprof2_Profiler);
+      g_dbus_node_info_unref (info);
+    }
+
+  dbus->profiler_id = g_dbus_connection_register_object (connection,
+                                                         "/org/gtk/Profiler",
+                                                         org_gnome_Sysprof2_Profiler,
+                                                         &vtable,
+                                                         NULL,
+                                                         NULL,
+                                                         error);
+
+  return TRUE;
+}
+
+static void
+gtk_application_dbus_unregister (GApplication     *application,
+                                 GDBusConnection  *connection,
+                                 const char       *obect_path)
+{
+  GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) application;
+
+  g_dbus_connection_unregister_object (connection, dbus->profiler_id);
+}
+
+#else
+
+static gboolean
+gtk_application_dbus_register (GApplication     *application,
+                               GDBusConnection  *connection,
+                               const char       *obect_path,
+                               GError          **error)
+{
+  return TRUE;
+}
+
+static void
+gtk_application_dbus_unregister (GApplication     *application,
+                                 GDBusConnection  *connection,
+                                 const char       *obect_path)
+{
+}
+
+#endif
+
 static void
 gtk_application_class_init (GtkApplicationClass *class)
 {
@@ -619,6 +766,8 @@ gtk_application_class_init (GtkApplicationClass *class)
   application_class->after_emit = gtk_application_after_emit;
   application_class->startup = gtk_application_startup;
   application_class->shutdown = gtk_application_shutdown;
+  application_class->dbus_register = gtk_application_dbus_register;
+  application_class->dbus_unregister = gtk_application_dbus_unregister;
 
   class->window_added = gtk_application_window_added;
   class->window_removed = gtk_application_window_removed;
diff --git a/gtk/gtkapplicationprivate.h b/gtk/gtkapplicationprivate.h
index 24ef7c4a40..f167c74362 100644
--- a/gtk/gtkapplicationprivate.h
+++ b/gtk/gtkapplicationprivate.h
@@ -127,6 +127,7 @@ typedef struct
 
   gchar           *menubar_path;
   guint            menubar_id;
+  guint            profiler_id;
 
   /* Session management... */
   GDBusProxy      *sm_proxy;


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