[sysprof/wip/chergert/control-fd: 9/11] libsysprof: implement D-Bus service for control FD
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sysprof/wip/chergert/control-fd: 9/11] libsysprof: implement D-Bus service for control FD
- Date: Tue, 11 Feb 2020 19:24:00 +0000 (UTC)
commit 7c250fc3bc549264c648a5a80b556680378809aa
Author: Christian Hergert <chergert redhat com>
Date: Sat Feb 8 11:40:17 2020 -0800
libsysprof: implement D-Bus service for control FD
This still needs a way to coordinate the flush with the inferior.
However, if the process exits, this gets some peices in place to mux those
streams into the final write stream (meaning the subprocess can collect
without any locking).
src/libsysprof/meson.build | 1 +
src/libsysprof/sysprof-control-source.c | 128 ++++++++++++++++++++++++++++++--
src/meson.build | 6 ++
src/org.gnome.Sysprof3.Collector.xml | 21 ++++++
4 files changed, 151 insertions(+), 5 deletions(-)
---
diff --git a/src/libsysprof/meson.build b/src/libsysprof/meson.build
index d5603ea..ab0f100 100644
--- a/src/libsysprof/meson.build
+++ b/src/libsysprof/meson.build
@@ -78,6 +78,7 @@ libsysprof_private_sources = [
'sysprof-podman.c',
'sysprof-polkit.c',
'sysprof-symbol-map.c',
+ ipc_collector_src,
ipc_service_src,
stackstash_sources,
helpers_sources,
diff --git a/src/libsysprof/sysprof-control-source.c b/src/libsysprof/sysprof-control-source.c
index 89853a4..40193e8 100644
--- a/src/libsysprof/sysprof-control-source.c
+++ b/src/libsysprof/sysprof-control-source.c
@@ -22,18 +22,24 @@
#include "config.h"
+#include <fcntl.h>
+#include <gio/gunixfdlist.h>
#include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h>
#include <sys/socket.h>
#include <sys/types.h>
+#include "ipc-collector.h"
+
#include "sysprof-control-source.h"
struct _SysprofControlSource
{
- GObject parent_instance;
- GDBusConnection *conn;
- GPtrArray *files;
+ GObject parent_instance;
+ IpcCollector *collector;
+ GDBusConnection *conn;
+ SysprofCaptureWriter *writer;
+ GPtrArray *files;
};
static void source_iface_init (SysprofSourceInterface *iface);
@@ -41,6 +47,8 @@ static void source_iface_init (SysprofSourceInterface *iface);
G_DEFINE_TYPE_WITH_CODE (SysprofControlSource, sysprof_control_source, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (SYSPROF_TYPE_SOURCE, source_iface_init))
+static SysprofSourceInterface *parent_iface;
+
SysprofControlSource *
sysprof_control_source_new (void)
{
@@ -53,6 +61,7 @@ sysprof_control_source_finalize (GObject *object)
SysprofControlSource *self = (SysprofControlSource *)object;
g_clear_object (&self->conn);
+ g_clear_object (&self->collector);
g_clear_pointer (&self->files, g_ptr_array_unref);
G_OBJECT_CLASS (sysprof_control_source_parent_class)->finalize (object);
@@ -72,6 +81,44 @@ sysprof_control_source_init (SysprofControlSource *self)
self->files = g_ptr_array_new_with_free_func (g_free);
}
+static gboolean
+on_handle_create_writer_cb (IpcCollector *collector,
+ GDBusMethodInvocation *invocation,
+ GUnixFDList *in_fd_list,
+ SysprofControlSource *self)
+{
+ gchar writer_tmpl[] = "sysprof-collector-XXXXXX";
+ int fd;
+
+ g_assert (IPC_IS_COLLECTOR (collector));
+ g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
+ g_assert (SYSPROF_IS_CONTROL_SOURCE (self));
+
+ fd = g_mkstemp_full (writer_tmpl, O_CLOEXEC, 0);
+
+ if (fd > -1)
+ {
+ g_autoptr(GUnixFDList) out_fd_list = g_unix_fd_list_new_from_array (&fd, 1);
+
+ if (out_fd_list != NULL)
+ {
+ g_ptr_array_add (self->files, g_strdup (writer_tmpl));
+ ipc_collector_complete_create_writer (collector,
+ g_steal_pointer (&invocation),
+ out_fd_list,
+ g_variant_new_handle (0));
+ return TRUE;
+ }
+ }
+
+ g_dbus_method_invocation_return_error (g_steal_pointer (&invocation),
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Failed to create FD for writer");
+
+ return TRUE;
+}
+
static void
sysprof_control_source_modify_spawn (SysprofSource *source,
SysprofSpawnable *spawnable)
@@ -111,14 +158,85 @@ sysprof_control_source_modify_spawn (SysprofSource *source,
g_set_object (&self->conn, conn);
- /* TODO */
- //g_dbus_interface_skeleton_export (GDBusInterfaceSkeleton *interface_, GDBusConnection *connection, const
gchar *object_path, GError **error)
+ self->collector = ipc_collector_skeleton_new ();
+
+ g_signal_connect_object (self->collector,
+ "handle-create-writer",
+ G_CALLBACK (on_handle_create_writer_cb),
+ self,
+ 0);
+
+ g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->collector),
+ conn,
+ "/org/gnome/Sysprof3/Collector",
+ NULL);
g_dbus_connection_start_message_processing (conn);
}
+static void
+sysprof_control_source_stop (SysprofSource *source)
+{
+ SysprofControlSource *self = (SysprofControlSource *)source;
+
+ g_assert (SYSPROF_IS_CONTROL_SOURCE (self));
+
+ if (self->conn != NULL)
+ {
+ g_dbus_connection_close_sync (self->conn, NULL, NULL);
+ g_clear_object (&self->conn);
+ }
+
+ if (parent_iface->stop)
+ parent_iface->stop (source);
+}
+
+static void
+sysprof_control_source_set_writer (SysprofSource *source,
+ SysprofCaptureWriter *writer)
+{
+ SysprofControlSource *self = (SysprofControlSource *)source;
+
+ g_assert (SYSPROF_IS_CONTROL_SOURCE (self));
+
+ g_clear_pointer (&self->writer, sysprof_capture_writer_unref);
+
+ if (writer != NULL)
+ self->writer = sysprof_capture_writer_ref (writer);
+}
+
+static void
+sysprof_control_source_supplement (SysprofSource *source,
+ SysprofCaptureReader *reader)
+{
+ SysprofControlSource *self = (SysprofControlSource *)source;
+
+ g_assert (SYSPROF_IS_CONTROL_SOURCE (self));
+
+ for (guint i = 0; i < self->files->len; i++)
+ {
+ const gchar *filename = g_ptr_array_index (self->files, i);
+ int fd = open (filename, O_RDONLY);
+
+ /* TODO: We can't simply splice these until we've forced the process
+ * to flush the buffers (unless they've already exited).
+ */
+
+ if (fd > -1)
+ {
+ _sysprof_capture_writer_splice_from_fd (self->writer, fd, NULL);
+ close (fd);
+ }
+ }
+}
+
static void
source_iface_init (SysprofSourceInterface *iface)
{
+ parent_iface = g_type_interface_peek_parent (iface);
+
+ iface->set_writer = sysprof_control_source_set_writer;
iface->modify_spawn = sysprof_control_source_modify_spawn;
+ iface->stop = sysprof_control_source_stop;
+ iface->supplement = sysprof_control_source_supplement;
}
diff --git a/src/meson.build b/src/meson.build
index f464cbb..91fad7e 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -19,6 +19,12 @@ ipc_service_src = gnome.gdbus_codegen('ipc-service',
namespace: 'Ipc',
)
+ipc_collector_src = gnome.gdbus_codegen('ipc-collector',
+ sources: 'org.gnome.Sysprof3.Collector.xml',
+ interface_prefix: 'org.gnome.Sysprof3.',
+ namespace: 'Ipc',
+)
+
ipc_legacy_src = gnome.gdbus_codegen('ipc-legacy',
sources: 'org.gnome.Sysprof2.xml',
interface_prefix: 'org.gnome.',
diff --git a/src/org.gnome.Sysprof3.Collector.xml b/src/org.gnome.Sysprof3.Collector.xml
new file mode 100644
index 0000000..76a746f
--- /dev/null
+++ b/src/org.gnome.Sysprof3.Collector.xml
@@ -0,0 +1,21 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.gnome.Sysprof3.Collector">
+ <!--
+ CreateWriter:
+ @fd: (out): a file-descriptor for capture writing
+
+ Creates a FD to use for capture writing. The Sysprof application
+ will mux all streams created using this API when the profiling has
+ completed.
+
+ The caller can close() the FD when it is no longer in use (or allow
+ SysprofCaptureWriter to close it when unref'd.
+ -->
+ <method name="CreateWriter">
+ <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
+ <arg type="h" name="fd" direction="out"/>
+ </method>
+ </interface>
+</node>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]