[sysprof/wip/chergert/control-fd: 8/11] libsysprof: stub out control FD source



commit 1196f5210355d8ded462e282cd93d2d99f82b14c
Author: Christian Hergert <chergert redhat com>
Date:   Sat Feb 8 09:32:09 2020 -0800

    libsysprof: stub out control FD source
    
    The goal here is to register a D-Bus socketpair that we can share with
    the subprocess being profiled. After it completes, we want to mux all of
    the capture data into the final file.

 src/libsysprof/meson.build              |   2 +
 src/libsysprof/sysprof-control-source.c | 103 ++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)
---
diff --git a/src/libsysprof/meson.build b/src/libsysprof/meson.build
index a7c52bd..d5603ea 100644
--- a/src/libsysprof/meson.build
+++ b/src/libsysprof/meson.build
@@ -7,6 +7,7 @@ libsysprof_public_sources = [
   'sysprof-callgraph-profile.c',
   'sysprof-capture-gobject.c',
   'sysprof-capture-symbol-resolver.c',
+  'sysprof-control-source.c',
   'sysprof-diskstat-source.c',
   'sysprof-elf-symbol-resolver.c',
   'sysprof-gjs-source.c',
@@ -37,6 +38,7 @@ libsysprof_public_headers = [
   'sysprof-callgraph-profile.h',
   'sysprof-capture-gobject.h',
   'sysprof-capture-symbol-resolver.h',
+  'sysprof-control-source.h',
   'sysprof-diskstat-source.h',
   'sysprof-elf-symbol-resolver.h',
   'sysprof-gjs-source.h',
diff --git a/src/libsysprof/sysprof-control-source.c b/src/libsysprof/sysprof-control-source.c
index 914ebbb..89853a4 100644
--- a/src/libsysprof/sysprof-control-source.c
+++ b/src/libsysprof/sysprof-control-source.c
@@ -18,4 +18,107 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
+#define G_LOG_DOMAIN "sysprof-control-source"
 
+#include "config.h"
+
+#include <gio/gunixinputstream.h>
+#include <gio/gunixoutputstream.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include "sysprof-control-source.h"
+
+struct _SysprofControlSource
+{
+  GObject          parent_instance;
+  GDBusConnection *conn;
+  GPtrArray       *files;
+};
+
+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))
+
+SysprofControlSource *
+sysprof_control_source_new (void)
+{
+  return g_object_new (SYSPROF_TYPE_CONTROL_SOURCE, NULL);
+}
+
+static void
+sysprof_control_source_finalize (GObject *object)
+{
+  SysprofControlSource *self = (SysprofControlSource *)object;
+
+  g_clear_object (&self->conn);
+  g_clear_pointer (&self->files, g_ptr_array_unref);
+
+  G_OBJECT_CLASS (sysprof_control_source_parent_class)->finalize (object);
+}
+
+static void
+sysprof_control_source_class_init (SysprofControlSourceClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = sysprof_control_source_finalize;
+}
+
+static void
+sysprof_control_source_init (SysprofControlSource *self)
+{
+  self->files = g_ptr_array_new_with_free_func (g_free);
+}
+
+static void
+sysprof_control_source_modify_spawn (SysprofSource    *source,
+                                     SysprofSpawnable *spawnable)
+{
+  SysprofControlSource *self = (SysprofControlSource *)source;
+  g_autofree gchar *child_no_str = NULL;
+  g_autoptr(GInputStream) in_stream = NULL;
+  g_autoptr(GOutputStream) out_stream = NULL;
+  g_autoptr(GIOStream) io_stream = NULL;
+  g_autoptr(GDBusConnection) conn = NULL;
+  int fds[2];
+  int child_no;
+
+  g_assert (SYSPROF_IS_SOURCE (source));
+  g_assert (SYSPROF_IS_SPAWNABLE (spawnable));
+
+  /* Create a socket pair to communicate D-Bus protocol over */
+  if (socketpair (PF_LOCAL, SOCK_STREAM, 0, fds) != 0)
+    return;
+
+  /* @child_no is assigned the FD the child will receive. We can
+   * use that to set the environment vaiable of the control FD.
+   */
+  child_no = sysprof_spawnable_take_fd (spawnable, fds[1], -1);
+  child_no_str = g_strdup_printf ("%d", child_no);
+  sysprof_spawnable_setenv (spawnable, "SYSPROF_CONTROL_FD", child_no_str);
+
+  /* Create our D-Bus connection for our side and export our service
+   * that can create new writers.
+   */
+  in_stream = g_unix_input_stream_new (dup (fds[0]), TRUE);
+  out_stream = g_unix_output_stream_new (fds[0], TRUE);
+  io_stream = g_simple_io_stream_new (in_stream, out_stream);
+  conn = g_dbus_connection_new_sync (io_stream, NULL,
+                                     G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING,
+                                     NULL, NULL, NULL);
+
+  g_set_object (&self->conn, conn);
+
+  /* TODO */
+  //g_dbus_interface_skeleton_export (GDBusInterfaceSkeleton *interface_, GDBusConnection *connection, const 
gchar *object_path, GError **error)
+
+  g_dbus_connection_start_message_processing (conn);
+}
+
+static void
+source_iface_init (SysprofSourceInterface *iface)
+{
+  iface->modify_spawn = sysprof_control_source_modify_spawn;
+}


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