mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-12 16:10:54 +00:00
sysprof-user-sampler: implement await for FDs
This allows us to not need libdex 0.9+ for use by the sampler.
This commit is contained in:
@ -144,6 +144,7 @@ libsysprof_private_sources = [
|
|||||||
'sysprof-document-symbols.c',
|
'sysprof-document-symbols.c',
|
||||||
'sysprof-elf-loader.c',
|
'sysprof-elf-loader.c',
|
||||||
'sysprof-elf.c',
|
'sysprof-elf.c',
|
||||||
|
'sysprof-fd.c',
|
||||||
'sysprof-leak-detector.c',
|
'sysprof-leak-detector.c',
|
||||||
'sysprof-maps-parser.c',
|
'sysprof-maps-parser.c',
|
||||||
'sysprof-mount-device.c',
|
'sysprof-mount-device.c',
|
||||||
|
|||||||
39
src/libsysprof/sysprof-fd-private.h
Normal file
39
src/libsysprof/sysprof-fd-private.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* sysprof-fd-private.h
|
||||||
|
*
|
||||||
|
* Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
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
|
||||||
67
src/libsysprof/sysprof-fd.c
Normal file
67
src/libsysprof/sysprof-fd.c
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/* sysprof-fd.c
|
||||||
|
*
|
||||||
|
* Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#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)
|
||||||
@ -32,6 +32,7 @@
|
|||||||
#include "sysprof-recording-private.h"
|
#include "sysprof-recording-private.h"
|
||||||
#include "sysprof-user-sampler.h"
|
#include "sysprof-user-sampler.h"
|
||||||
#include "sysprof-muxer-source.h"
|
#include "sysprof-muxer-source.h"
|
||||||
|
#include "sysprof-fd-private.h"
|
||||||
|
|
||||||
#include "ipc-unwinder.h"
|
#include "ipc-unwinder.h"
|
||||||
|
|
||||||
@ -85,6 +86,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
|
static void
|
||||||
sysprof_user_sampler_ioctl (SysprofUserSampler *self,
|
sysprof_user_sampler_ioctl (SysprofUserSampler *self,
|
||||||
gboolean enable)
|
gboolean enable)
|
||||||
@ -149,7 +174,7 @@ _perf_event_open_cb (GObject *object,
|
|||||||
if (-1 == (fd = g_unix_fd_list_get (fd_list, handle, &error)))
|
if (-1 == (fd = g_unix_fd_list_get (fd_list, handle, &error)))
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
dex_promise_resolve_fd (promise, g_steal_fd (&fd));
|
promise_resolve_fd (promise, g_steal_fd (&fd));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +259,7 @@ try_again:
|
|||||||
_perf_event_open_cb,
|
_perf_event_open_cb,
|
||||||
dex_ref (promise));
|
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);
|
g_clear_pointer (&options, g_variant_unref);
|
||||||
|
|
||||||
@ -274,7 +299,7 @@ call_unwind_cb (GObject *object,
|
|||||||
|
|
||||||
if (ipc_unwinder_call_unwind_finish (IPC_UNWINDER (object), &out_capture_fd, &out_fd_list, result, &error) &&
|
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)))
|
-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
|
else
|
||||||
dex_promise_reject (promise, error);
|
dex_promise_reject (promise, error);
|
||||||
}
|
}
|
||||||
@ -406,7 +431,7 @@ sysprof_user_sampler_prepare_fiber (gpointer user_data)
|
|||||||
call_unwind_cb,
|
call_unwind_cb,
|
||||||
dex_ref (promise));
|
dex_ref (promise));
|
||||||
|
|
||||||
fd = dex_await_fd (dex_ref (promise), &error);
|
fd = await_fd (dex_ref (promise), &error);
|
||||||
|
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user