From 781d438e5e3d4189d8a1970707983ccc6897175c Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Wed, 6 Nov 2024 15:09:13 -0800 Subject: [PATCH] sysprof-user-sampler: implement await for FDs This allows us to not need libdex 0.9+ for use by the sampler. --- src/libsysprof/meson.build | 1 + src/libsysprof/sysprof-fd-private.h | 39 ++++++++++++++++ src/libsysprof/sysprof-fd.c | 67 +++++++++++++++++++++++++++ src/libsysprof/sysprof-user-sampler.c | 33 +++++++++++-- 4 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 src/libsysprof/sysprof-fd-private.h create mode 100644 src/libsysprof/sysprof-fd.c diff --git a/src/libsysprof/meson.build b/src/libsysprof/meson.build index e49c3a37..2ae977ca 100644 --- a/src/libsysprof/meson.build +++ b/src/libsysprof/meson.build @@ -144,6 +144,7 @@ libsysprof_private_sources = [ 'sysprof-document-symbols.c', 'sysprof-elf-loader.c', 'sysprof-elf.c', + 'sysprof-fd.c', 'sysprof-leak-detector.c', 'sysprof-maps-parser.c', 'sysprof-mount-device.c', diff --git a/src/libsysprof/sysprof-fd-private.h b/src/libsysprof/sysprof-fd-private.h new file mode 100644 index 00000000..1d4dfabc --- /dev/null +++ b/src/libsysprof/sysprof-fd-private.h @@ -0,0 +1,39 @@ +/* sysprof-fd-private.h + * + * Copyright 2024 Christian Hergert + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define SYSPROF_TYPE_FD (sysprof_fd_get_type()) + +typedef struct _SysprofFD SysprofFD; + +GType sysprof_fd_get_type (void) G_GNUC_CONST; +int sysprof_fd_peek (const SysprofFD *fd); +int sysprof_fd_steal (SysprofFD *fd); +SysprofFD *sysprof_fd_dup (const SysprofFD *fd); +void sysprof_fd_free (SysprofFD *fd); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (SysprofFD, sysprof_fd_free) + +G_END_DECLS diff --git a/src/libsysprof/sysprof-fd.c b/src/libsysprof/sysprof-fd.c new file mode 100644 index 00000000..5e34f8d9 --- /dev/null +++ b/src/libsysprof/sysprof-fd.c @@ -0,0 +1,67 @@ +/* sysprof-fd.c + * + * Copyright 2024 Christian Hergert + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "config.h" + +#include + +#include "sysprof-fd-private.h" + +int +sysprof_fd_peek (const SysprofFD *fd) +{ + if (fd == NULL) + return -1; + + return *(int *)fd; +} + +int +sysprof_fd_steal (SysprofFD *fd) +{ + if (fd == NULL) + return -1; + + return g_steal_fd ((int *)fd); +} + +void +sysprof_fd_free (SysprofFD *fd) +{ + int real = sysprof_fd_steal (fd); + if (real != -1) + close (real); + g_free (fd); +} + +SysprofFD * +sysprof_fd_dup (const SysprofFD *fd) +{ + int real = sysprof_fd_peek (fd); + + if (real == -1) + return NULL; + + real = dup (real); + + return g_memdup2 (&real, sizeof real); +} + +G_DEFINE_BOXED_TYPE (SysprofFD, sysprof_fd, sysprof_fd_dup, sysprof_fd_free) diff --git a/src/libsysprof/sysprof-user-sampler.c b/src/libsysprof/sysprof-user-sampler.c index 0e3afeae..1ae3ea27 100644 --- a/src/libsysprof/sysprof-user-sampler.c +++ b/src/libsysprof/sysprof-user-sampler.c @@ -32,6 +32,7 @@ #include "sysprof-recording-private.h" #include "sysprof-user-sampler.h" #include "sysprof-muxer-source.h" +#include "sysprof-fd-private.h" #include "ipc-unwinder.h" @@ -81,6 +82,30 @@ close_fd (gpointer data) } } +static void +promise_resolve_fd (DexPromise *promise, + int fd) +{ + GValue gvalue = {SYSPROF_TYPE_FD, {{.v_pointer = &fd}, {.v_int = 0}}}; + dex_promise_resolve (promise, &gvalue); +} + +static int +await_fd (DexFuture *future, + GError **error) +{ + SysprofFD *fd = dex_await_boxed (future, error); + int ret = -1; + + if (fd != NULL) + { + ret = sysprof_fd_steal (fd); + sysprof_fd_free (fd); + } + + return ret; +} + static void sysprof_user_sampler_ioctl (SysprofUserSampler *self, gboolean enable) @@ -145,7 +170,7 @@ _perf_event_open_cb (GObject *object, if (-1 == (fd = g_unix_fd_list_get (fd_list, handle, &error))) goto failure; - dex_promise_resolve_fd (promise, g_steal_fd (&fd)); + promise_resolve_fd (promise, g_steal_fd (&fd)); return; } @@ -230,7 +255,7 @@ try_again: _perf_event_open_cb, dex_ref (promise)); - if (-1 == (perf_fd = dex_await_fd (dex_ref (promise), error))) + if (-1 == (perf_fd = await_fd (dex_ref (promise), error))) { g_clear_pointer (&options, g_variant_unref); @@ -270,7 +295,7 @@ call_unwind_cb (GObject *object, if (ipc_unwinder_call_unwind_finish (IPC_UNWINDER (object), &out_capture_fd, &out_fd_list, result, &error) && -1 != (capture_fd = g_unix_fd_list_get (out_fd_list, g_variant_get_handle (out_capture_fd), &error))) - dex_promise_resolve_fd (promise, g_steal_fd (&capture_fd)); + promise_resolve_fd (promise, g_steal_fd (&capture_fd)); else dex_promise_reject (promise, error); } @@ -402,7 +427,7 @@ sysprof_user_sampler_prepare_fiber (gpointer user_data) call_unwind_cb, dex_ref (promise)); - fd = dex_await_fd (dex_ref (promise), &error); + fd = await_fd (dex_ref (promise), &error); if (fd == -1) { -- 2.45.2