summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2018-05-19 20:36:00 +0100
committerMatthias Clasen <mclasen@redhat.com>2019-05-07 09:37:59 -0700
commit18127be3bd3a1bc003775d5dda14b8cb658fbf32 (patch)
treee2fd8963bf4b343fa7e4008a5fcaf3d8b49fcaa5
parent64454a7e47f5d0bac12bae3c1d73e47392803d38 (diff)
downloadgtk+-18127be3bd3a1bc003775d5dda14b8cb658fbf32.tar.gz
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.
-rw-r--r--gtk/gtkapplication.c149
-rw-r--r--gtk/gtkapplicationprivate.h1
2 files changed, 150 insertions, 0 deletions
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;