From a3c235a31608a39d86d7c1546ff40d6a92bd69b2 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Sun, 4 Jun 2023 10:20:34 -0700 Subject: [PATCH] libsysprof-profile: don't use FD to drive perf source It is not enough to get writability, as that wont trigger on the perf source. Instead, we need to check the mmap'd header and drive things off of that. It might be nice to eventually determine how many of the samples are from our own process and back-off our timeout based on that. --- .../sysprof-perf-event-stream.c | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/libsysprof-profile/sysprof-perf-event-stream.c b/src/libsysprof-profile/sysprof-perf-event-stream.c index 68e60a64..854793d7 100644 --- a/src/libsysprof-profile/sysprof-perf-event-stream.c +++ b/src/libsysprof-profile/sysprof-perf-event-stream.c @@ -229,6 +229,34 @@ sysprof_perf_event_stream_flush (SysprofPerfEventStream *self) self->map->data_tail = tail; } +static gboolean +sysprof_perf_event_source_prepare (GSource *gsource, + int *timeout) +{ + SysprofPerfEventSource *source = (SysprofPerfEventSource *)gsource; + SysprofPerfEventStream *self = source->stream; + + if (timeout != NULL) + *timeout = 5; + + return self != NULL && + self->active && + self->map != NULL && + self->tail != self->map->data_head; +} + +static gboolean +sysprof_perf_event_source_check (GSource *gsource) +{ + SysprofPerfEventSource *source = (SysprofPerfEventSource *)gsource; + SysprofPerfEventStream *self = source->stream; + + return self != NULL && + self->active && + self->map != NULL && + self->tail != self->map->data_head; +} + static gboolean sysprof_perf_event_source_dispatch (GSource *source, GSourceFunc callback, @@ -238,6 +266,8 @@ sysprof_perf_event_source_dispatch (GSource *source, } static GSourceFuncs source_funcs = { + .prepare = sysprof_perf_event_source_prepare, + .check = sysprof_perf_event_source_check, .dispatch = sysprof_perf_event_source_dispatch, }; @@ -392,6 +422,7 @@ sysprof_perf_event_stream_new (GDBusConnection *connection, gpointer callback_data, GDestroyNotify callback_data_destroy) { + SysprofPerfEventSource *source; g_autoptr(SysprofPerfEventStream) self = NULL; g_autoptr(GUnixFDList) fd_list = NULL; g_autoptr(DexPromise) promise = NULL; @@ -415,7 +446,11 @@ sysprof_perf_event_stream_new (GDBusConnection *connection, self->callback_data = callback_data; self->callback_data_destroy = callback_data_destroy; self->promise = dex_ref (promise); - self->source = g_source_new (&source_funcs, sizeof (SysprofPerfEventSource)); + + source = (SysprofPerfEventSource *) + g_source_new (&source_funcs, sizeof (SysprofPerfEventSource)); + source->stream = self; + self->source = (GSource *)source; g_source_set_callback (self->source, sysprof_perf_event_stream_dispatch, self, NULL); g_source_set_name (self->source, "[perf]");