From f550394b62be352c597934bce52e538ad866aa51 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Wed, 3 May 2023 15:31:56 -0700 Subject: [PATCH] libsysprof-analyze: add prepare vfunc for symbolizers This will allow them to pre-process the document and extract whatever information they need out of it to do symbolizing. --- .../sysprof-document-symbols.c | 1 + .../sysprof-multi-symbolizer.c | 86 +++++++++++++++++++ .../sysprof-symbolizer-private.h | 22 +++++ src/libsysprof-analyze/sysprof-symbolizer.c | 47 ++++++++++ 4 files changed, 156 insertions(+) diff --git a/src/libsysprof-analyze/sysprof-document-symbols.c b/src/libsysprof-analyze/sysprof-document-symbols.c index d0c40352..b67ebe9d 100644 --- a/src/libsysprof-analyze/sysprof-document-symbols.c +++ b/src/libsysprof-analyze/sysprof-document-symbols.c @@ -21,6 +21,7 @@ #include "config.h" #include "sysprof-document-symbols-private.h" +#include "sysprof-symbolizer-private.h" struct _SysprofDocumentSymbols { diff --git a/src/libsysprof-analyze/sysprof-multi-symbolizer.c b/src/libsysprof-analyze/sysprof-multi-symbolizer.c index 2b386907..f5dce1b3 100644 --- a/src/libsysprof-analyze/sysprof-multi-symbolizer.c +++ b/src/libsysprof-analyze/sysprof-multi-symbolizer.c @@ -36,6 +36,87 @@ struct _SysprofMultiSymbolizerClass G_DEFINE_FINAL_TYPE (SysprofMultiSymbolizer, sysprof_multi_symbolizer, SYSPROF_TYPE_SYMBOLIZER) +static void +sysprof_multi_symbolizer_prepare_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + SysprofSymbolizer *symbolizer = (SysprofSymbolizer *)object; + g_autoptr(GTask) task = user_data; + g_autoptr(GError) error = NULL; + GPtrArray *state; + + g_assert (SYSPROF_IS_SYMBOLIZER (symbolizer)); + g_assert (G_IS_ASYNC_RESULT (result)); + g_assert (G_IS_TASK (task)); + + state = g_task_get_task_data (task); + + g_assert (state != NULL); + g_assert (state->len > 0); + + if (!_sysprof_symbolizer_prepare_finish (symbolizer, result, &error)) + g_warning ("Failed to initialize symbolizer: %s", error->message); + + g_ptr_array_remove (state, symbolizer); + + if (state->len == 0) + g_task_return_boolean (task, TRUE); +} + +static void +sysprof_multi_symbolizer_prepare_async (SysprofSymbolizer *symbolizer, + SysprofDocument *document, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + SysprofMultiSymbolizer *self = (SysprofMultiSymbolizer *)symbolizer; + g_autoptr(GTask) task = NULL; + g_autoptr(GPtrArray) state = NULL; + + g_assert (SYSPROF_IS_MULTI_SYMBOLIZER (self)); + g_assert (SYSPROF_IS_DOCUMENT (document)); + g_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); + + state = g_ptr_array_new_with_free_func (g_object_unref); + for (guint i = 0; i < self->symbolizers->len; i++) + g_ptr_array_add (state, g_object_ref (g_ptr_array_index (self->symbolizers, i))); + + task = g_task_new (self, cancellable, callback, user_data); + g_task_set_source_tag (task, sysprof_multi_symbolizer_prepare_async); + g_task_set_task_data (task, g_ptr_array_ref (state), (GDestroyNotify)g_ptr_array_unref); + + if (state->len == 0) + { + g_task_return_boolean (task, TRUE); + return; + } + + for (guint i = 0; i < state->len; i++) + { + SysprofSymbolizer *child = g_ptr_array_index (state, i); + + _sysprof_symbolizer_prepare_async (child, + document, + cancellable, + sysprof_multi_symbolizer_prepare_cb, + g_object_ref (task)); + } +} + +static gboolean +sysprof_multi_symbolizer_prepare_finish (SysprofSymbolizer *symbolizer, + GAsyncResult *result, + GError **error) +{ + g_assert (SYSPROF_IS_MULTI_SYMBOLIZER (symbolizer)); + g_assert (G_IS_TASK (result)); + g_assert (g_task_is_valid (result, symbolizer)); + + return g_task_propagate_boolean (G_TASK (result), error); +} + static void sysprof_multi_symbolizer_finalize (GObject *object) { @@ -50,8 +131,12 @@ static void sysprof_multi_symbolizer_class_init (SysprofMultiSymbolizerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + SysprofSymbolizerClass *symbolizer_class = SYSPROF_SYMBOLIZER_CLASS (klass); object_class->finalize = sysprof_multi_symbolizer_finalize; + + symbolizer_class->prepare_async = sysprof_multi_symbolizer_prepare_async; + symbolizer_class->prepare_finish = sysprof_multi_symbolizer_prepare_finish; } static void @@ -72,6 +157,7 @@ sysprof_multi_symbolizer_add (SysprofMultiSymbolizer *self, { g_return_if_fail (SYSPROF_IS_MULTI_SYMBOLIZER (self)); g_return_if_fail (SYSPROF_IS_SYMBOLIZER (symbolizer)); + g_return_if_fail ((gpointer)self != (gpointer)symbolizer); g_ptr_array_add (self->symbolizers, g_object_ref (symbolizer)); } diff --git a/src/libsysprof-analyze/sysprof-symbolizer-private.h b/src/libsysprof-analyze/sysprof-symbolizer-private.h index d7f65b75..c70a110c 100644 --- a/src/libsysprof-analyze/sysprof-symbolizer-private.h +++ b/src/libsysprof-analyze/sysprof-symbolizer-private.h @@ -20,10 +20,13 @@ #pragma once +#include "sysprof-document.h" #include "sysprof-symbolizer.h" G_BEGIN_DECLS +#define SYSPROF_SYMBOLIZER_GET_CLASS(obj) G_TYPE_INSTANCE_GET_CLASS(obj, SYSPROF_TYPE_SYMBOLIZER, SysprofSymbolizerClass) + struct _SysprofSymbolizer { GObject parent; @@ -32,6 +35,25 @@ struct _SysprofSymbolizer struct _SysprofSymbolizerClass { GObjectClass parent_class; + + void (*prepare_async) (SysprofSymbolizer *self, + SysprofDocument *document, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*prepare_finish) (SysprofSymbolizer *self, + GAsyncResult *result, + GError **error); }; + +void _sysprof_symbolizer_prepare_async (SysprofSymbolizer *self, + SysprofDocument *document, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean _sysprof_symbolizer_prepare_finish (SysprofSymbolizer *self, + GAsyncResult *result, + GError **error); + G_END_DECLS diff --git a/src/libsysprof-analyze/sysprof-symbolizer.c b/src/libsysprof-analyze/sysprof-symbolizer.c index bc8642c1..8f494903 100644 --- a/src/libsysprof-analyze/sysprof-symbolizer.c +++ b/src/libsysprof-analyze/sysprof-symbolizer.c @@ -24,6 +24,25 @@ G_DEFINE_ABSTRACT_TYPE (SysprofSymbolizer, sysprof_symbolizer, G_TYPE_OBJECT) +static void +sysprof_symbolizer_real_prepare_async (SysprofSymbolizer *self, + SysprofDocument *document, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_autoptr(GTask) task = g_task_new (self, cancellable, callback, user_data); + g_task_return_boolean (task, TRUE); +} + +static gboolean +sysprof_symbolizer_real_prepare_finish (SysprofSymbolizer *self, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (result), error); +} + static void sysprof_symbolizer_finalize (GObject *object) { @@ -36,9 +55,37 @@ sysprof_symbolizer_class_init (SysprofSymbolizerClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = sysprof_symbolizer_finalize; + + klass->prepare_async = sysprof_symbolizer_real_prepare_async; + klass->prepare_finish = sysprof_symbolizer_real_prepare_finish; } static void sysprof_symbolizer_init (SysprofSymbolizer *self) { } + +void +_sysprof_symbolizer_prepare_async (SysprofSymbolizer *self, + SysprofDocument *document, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (SYSPROF_IS_SYMBOLIZER (self)); + g_return_if_fail (SYSPROF_IS_DOCUMENT (document)); + g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); + + SYSPROF_SYMBOLIZER_GET_CLASS (self)->prepare_async (self, document, cancellable, callback, user_data); +} + +gboolean +_sysprof_symbolizer_prepare_finish (SysprofSymbolizer *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (SYSPROF_IS_SYMBOLIZER (self), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + return SYSPROF_SYMBOLIZER_GET_CLASS (self)->prepare_finish (self, result, error); +}