From 91c95a0e0d89604455edd89e2799a55d099f4bee Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Mon, 13 May 2019 23:59:40 -0700 Subject: [PATCH] libsysprof-ui: work on async loading --- src/libsysprof-ui/sysprof-capture-view.c | 54 ++++++++++++++++++++++- src/libsysprof-ui/sysprof-marks-model.c | 56 +++++++++++++++++++----- src/libsysprof-ui/sysprof-marks-model.h | 3 +- src/libsysprof-ui/sysprof-marks-view.c | 54 ++++++++++++++++++----- src/libsysprof-ui/sysprof-marks-view.h | 14 ++++-- src/libsysprof/sysprof-selection.h | 6 +-- src/sysprof/sysprof-window.c | 2 +- 7 files changed, 156 insertions(+), 33 deletions(-) diff --git a/src/libsysprof-ui/sysprof-capture-view.c b/src/libsysprof-ui/sysprof-capture-view.c index e16f32af..cab04066 100644 --- a/src/libsysprof-ui/sysprof-capture-view.c +++ b/src/libsysprof-ui/sysprof-capture-view.c @@ -55,6 +55,7 @@ typedef struct typedef struct { SysprofCaptureReader *reader; + SysprofSelection *selection; gint n_active; guint has_error : 1; } LoadAsync; @@ -77,6 +78,7 @@ load_async_free (gpointer data) if (state != NULL) { g_clear_pointer (&state->reader, sysprof_capture_reader_unref); + g_clear_object (&state->selection); g_slice_free (LoadAsync, state); } } @@ -301,6 +303,42 @@ sysprof_capture_view_scan_finish (SysprofCaptureView *self, return g_task_propagate_boolean (G_TASK (result), error); } +static void +sysprof_capture_view_load_marks_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + SysprofMarksView *view = (SysprofMarksView *)object; + g_autoptr(GError) error = NULL; + g_autoptr(GTask) task = user_data; + LoadAsync *state; + + g_assert (SYSPROF_IS_MARKS_VIEW (view)); + 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->reader != NULL); + g_assert (state->n_active > 0); + + state->n_active--; + + if (!sysprof_marks_view_load_finish (view, result, &error)) + { + if (!state->has_error) + { + state->has_error = TRUE; + g_task_return_error (task, g_steal_pointer (&error)); + } + + return; + } + + if (state->n_active == 0) + g_task_return_boolean (task, TRUE); +} + static void sysprof_capture_view_load_callgraph_cb (GObject *object, GAsyncResult *result, @@ -367,7 +405,7 @@ sysprof_capture_view_load_scan_cb (GObject *object, state->n_active++; sysprof_capture_view_generate_callgraph_async (self, state->reader, - NULL, + state->selection, g_task_get_cancellable (task), sysprof_capture_view_load_callgraph_cb, g_object_ref (task)); @@ -377,7 +415,15 @@ sysprof_capture_view_load_scan_cb (GObject *object, sysprof_visualizer_view_set_reader (priv->visualizer_view, state->reader); if (priv->features.has_marks) - sysprof_marks_view_set_reader (priv->marks_view, state->reader); + { + state->n_active++; + sysprof_marks_view_load_async (priv->marks_view, + state->reader, + state->selection, + g_task_get_cancellable (task), + sysprof_capture_view_load_marks_cb, + g_object_ref (task)); + } if (state->n_active == 0) g_task_return_boolean (task, TRUE); @@ -392,6 +438,7 @@ sysprof_capture_view_real_load_async (SysprofCaptureView *self, { SysprofCaptureViewPrivate *priv = sysprof_capture_view_get_instance_private (self); g_autoptr(GTask) task = NULL; + SysprofSelection *selection; LoadAsync *state; g_assert (SYSPROF_IS_CAPTURE_VIEW (self)); @@ -401,8 +448,11 @@ sysprof_capture_view_real_load_async (SysprofCaptureView *self, g_clear_pointer (&priv->reader, sysprof_capture_reader_unref); priv->reader = sysprof_capture_reader_ref (reader); + selection = sysprof_visualizer_view_get_selection (priv->visualizer_view); + state = g_slice_new0 (LoadAsync); state->reader = sysprof_capture_reader_copy (reader); + state->selection = g_object_ref (selection); state->n_active = 0; task = g_task_new (self, cancellable, callback, user_data); diff --git a/src/libsysprof-ui/sysprof-marks-model.c b/src/libsysprof-ui/sysprof-marks-model.c index e76aac05..219bf420 100644 --- a/src/libsysprof-ui/sysprof-marks-model.c +++ b/src/libsysprof-ui/sysprof-marks-model.c @@ -310,43 +310,77 @@ sysprof_marks_model_new_worker (GTask *task, gpointer task_data, GCancellable *cancellable) { - const SysprofCaptureFrameType types[] = { SYSPROF_CAPTURE_FRAME_MARK }; - SysprofCaptureReader *reader = task_data; - g_autoptr(SysprofCaptureCursor) cursor = NULL; g_autoptr(SysprofMarksModel) self = NULL; - SysprofCaptureCondition *condition; + SysprofCaptureCursor *cursor = task_data; g_assert (G_IS_TASK (task)); g_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); self = g_object_new (SYSPROF_TYPE_MARKS_MODEL, NULL); - - cursor = sysprof_capture_cursor_new (reader); - condition = sysprof_capture_condition_new_where_type_in (G_N_ELEMENTS (types), types); - sysprof_capture_cursor_add_condition (cursor, g_steal_pointer (&condition)); sysprof_capture_cursor_foreach (cursor, cursor_foreach_cb, self); - g_array_sort (self->items, item_compare); g_task_return_pointer (task, g_steal_pointer (&self), g_object_unref); } +static void +sysprof_marks_model_selection_foreach_cb (SysprofSelection *selection, + gint64 begin, + gint64 end, + gpointer user_data) +{ + SysprofCaptureCondition **condition = user_data; + SysprofCaptureCondition *c; + + g_assert (SYSPROF_IS_SELECTION (selection)); + g_assert (condition != NULL); + + c = sysprof_capture_condition_new_where_time_between (begin, end); + + if (*condition) + *condition = sysprof_capture_condition_new_or (c, *condition); + else + *condition = c; +} + void sysprof_marks_model_new_async (SysprofCaptureReader *reader, + SysprofSelection *selection, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { + const SysprofCaptureFrameType types[] = { SYSPROF_CAPTURE_FRAME_MARK }; + g_autoptr(SysprofCaptureCursor) cursor = NULL; g_autoptr(GTask) task = NULL; + SysprofCaptureCondition *c; g_return_if_fail (reader != NULL); + g_return_if_fail (!selection || SYSPROF_IS_SELECTION (selection)); g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); + cursor = sysprof_capture_cursor_new (reader); + + c = sysprof_capture_condition_new_where_type_in (G_N_ELEMENTS (types), types); + + if (selection) + { + SysprofCaptureCondition *condition = NULL; + + sysprof_selection_foreach (selection, + sysprof_marks_model_selection_foreach_cb, + &condition); + if (condition) + c = sysprof_capture_condition_new_and (c, condition); + } + + sysprof_capture_cursor_add_condition (cursor, g_steal_pointer (&c)); + task = g_task_new (NULL, cancellable, callback, user_data); g_task_set_source_tag (task, sysprof_marks_model_new_async); g_task_set_task_data (task, - sysprof_capture_reader_ref (reader), - (GDestroyNotify) sysprof_capture_reader_unref); + g_steal_pointer (&cursor), + (GDestroyNotify) sysprof_capture_cursor_unref); g_task_run_in_thread (task, sysprof_marks_model_new_worker); } diff --git a/src/libsysprof-ui/sysprof-marks-model.h b/src/libsysprof-ui/sysprof-marks-model.h index 292afb86..54d833cb 100644 --- a/src/libsysprof-ui/sysprof-marks-model.h +++ b/src/libsysprof-ui/sysprof-marks-model.h @@ -21,7 +21,7 @@ #pragma once #include -#include +#include G_BEGIN_DECLS @@ -41,6 +41,7 @@ typedef enum G_DECLARE_FINAL_TYPE (SysprofMarksModel, sysprof_marks_model, SYSPROF, MARKS_MODEL, GObject) void sysprof_marks_model_new_async (SysprofCaptureReader *reader, + SysprofSelection *selection, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); diff --git a/src/libsysprof-ui/sysprof-marks-view.c b/src/libsysprof-ui/sysprof-marks-view.c index 4039eb5d..2a8a901c 100644 --- a/src/libsysprof-ui/sysprof-marks-view.c +++ b/src/libsysprof-ui/sysprof-marks-view.c @@ -59,22 +59,26 @@ sysprof_marks_view_new (void) } static void -new_marks_model_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) +sysprof_marks_view_load_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) { - g_autoptr(SysprofMarksView) self = user_data; - SysprofMarksViewPrivate *priv = sysprof_marks_view_get_instance_private (self); g_autoptr(SysprofMarksModel) model = NULL; g_autoptr(GError) error = NULL; + g_autoptr(GTask) task = user_data; + SysprofMarksView *self; + SysprofMarksViewPrivate *priv; gint64 zoom_begin, zoom_end; - g_assert (SYSPROF_IS_MARKS_VIEW (self)); g_assert (G_IS_ASYNC_RESULT (result)); + g_assert (G_IS_TASK (task)); + + self = g_task_get_source_object (task); + priv = sysprof_marks_view_get_instance_private (self); if (!(model = sysprof_marks_model_new_finish (result, &error))) { - g_warning ("Failed to load marks model: %s", error->message); + g_task_return_error (task, g_steal_pointer (&error)); return; } @@ -85,16 +89,42 @@ new_marks_model_cb (GObject *object, NULL); gtk_tree_view_set_model (priv->tree_view, GTK_TREE_MODEL (model)); + + g_task_return_boolean (task, TRUE); } void -sysprof_marks_view_set_reader (SysprofMarksView *self, - SysprofCaptureReader *reader) +sysprof_marks_view_load_async (SysprofMarksView *self, + SysprofCaptureReader *reader, + SysprofSelection *selection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(GTask) task = NULL; + g_return_if_fail (SYSPROF_IS_MARKS_VIEW (self)); + g_return_if_fail (reader != NULL); + g_return_if_fail (!selection || SYSPROF_IS_SELECTION (selection)); + g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); + + task = g_task_new (self, cancellable, callback, user_data); + g_task_set_source_tag (task, sysprof_marks_view_load_async); sysprof_marks_model_new_async (reader, - NULL, - new_marks_model_cb, - g_object_ref (self)); + selection, + cancellable, + sysprof_marks_view_load_cb, + g_steal_pointer (&task)); +} + +gboolean +sysprof_marks_view_load_finish (SysprofMarksView *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (SYSPROF_IS_MARKS_VIEW (self), FALSE); + g_return_val_if_fail (G_IS_TASK (result), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); } diff --git a/src/libsysprof-ui/sysprof-marks-view.h b/src/libsysprof-ui/sysprof-marks-view.h index 5f245760..6a65ea54 100644 --- a/src/libsysprof-ui/sysprof-marks-view.h +++ b/src/libsysprof-ui/sysprof-marks-view.h @@ -39,9 +39,17 @@ struct _SysprofMarksViewClass }; SYSPROF_AVAILABLE_IN_ALL -GtkWidget *sysprof_marks_view_new (void); +GtkWidget *sysprof_marks_view_new (void); SYSPROF_AVAILABLE_IN_ALL -void sysprof_marks_view_set_reader (SysprofMarksView *self, - SysprofCaptureReader *reader); +void sysprof_marks_view_load_async (SysprofMarksView *self, + SysprofCaptureReader *reader, + SysprofSelection *selection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +SYSPROF_AVAILABLE_IN_ALL +gboolean sysprof_marks_view_load_finish (SysprofMarksView *self, + GAsyncResult *result, + GError **error); G_END_DECLS diff --git a/src/libsysprof/sysprof-selection.h b/src/libsysprof/sysprof-selection.h index 58e2f58b..f173e86b 100644 --- a/src/libsysprof/sysprof-selection.h +++ b/src/libsysprof/sysprof-selection.h @@ -36,9 +36,9 @@ SYSPROF_AVAILABLE_IN_ALL G_DECLARE_FINAL_TYPE (SysprofSelection, sysprof_selection, SYSPROF, SELECTION, GObject) typedef void (*SysprofSelectionForeachFunc) (SysprofSelection *self, - gint64 begin_time, - gint64 end_time, - gpointer user_data); + gint64 begin_time, + gint64 end_time, + gpointer user_data); SYSPROF_AVAILABLE_IN_ALL gboolean sysprof_selection_get_has_selection (SysprofSelection *self); diff --git a/src/sysprof/sysprof-window.c b/src/sysprof/sysprof-window.c index 32ce1546..ca950bab 100644 --- a/src/sysprof/sysprof-window.c +++ b/src/sysprof/sysprof-window.c @@ -270,7 +270,7 @@ sysprof_window_build_profile (SysprofWindow *self) sysprof_window_build_profile_cb, g_object_ref (self)); - sysprof_marks_view_set_reader (self->marks_view, self->reader); + sysprof_marks_view_load_async (self->marks_view, self->reader, selection, NULL, NULL, NULL); } static void