diff options
author | Matthias Clasen <mclasen@redhat.com> | 2018-05-19 20:36:00 +0100 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-05-07 09:37:59 -0700 |
commit | 18127be3bd3a1bc003775d5dda14b8cb658fbf32 (patch) | |
tree | e2fd8963bf4b343fa7e4008a5fcaf3d8b49fcaa5 /gtk/gtkapplication.c | |
parent | 64454a7e47f5d0bac12bae3c1d73e47392803d38 (diff) | |
download | gtk+-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.
Diffstat (limited to 'gtk/gtkapplication.c')
-rw-r--r-- | gtk/gtkapplication.c | 149 |
1 files changed, 149 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; |