[sysprof] ui: avoid concurrent reloads of stack depths



commit db160cf536f34dd37a940ed452f8ab6565bd697f
Author: Christian Hergert <chergert redhat com>
Date:   Wed Jan 8 11:13:24 2020 -0800

    ui: avoid concurrent reloads of stack depths
    
    This ensures that we only have one thread doing reloads of stack frame
    depths at a time. While we only ref the reader in the state, it should
    still be fine because cursors *always* make a copy of the reader for their
    internal use. I don't think this should fix #23, but it may reduce the
    chances of it happening.
    
    It's unclear to me what could cause #23 to happen, unless for some reason
    multiple threads were sharing the reader's internal buffer causing the
    frame-> dereferences to be junk. But as stated with reader copies, that
    should not be able to happen.
    
    Another possible avenue is that the task is cancelled and for some reason
    the task is clearing the task data while the thread is running. Again,
    that is not supposed to be possible given the design of GTask as it
    should not release task data until finalized.

 src/libsysprof-ui/sysprof-depth-visualizer.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
---
diff --git a/src/libsysprof-ui/sysprof-depth-visualizer.c b/src/libsysprof-ui/sysprof-depth-visualizer.c
index 8fab70e..39ebf37 100644
--- a/src/libsysprof-ui/sysprof-depth-visualizer.c
+++ b/src/libsysprof-ui/sysprof-depth-visualizer.c
@@ -35,6 +35,8 @@ struct _SysprofDepthVisualizer
   guint                 reload_source;
   guint                 mode;
   GtkAllocation         last_alloc;
+  guint                 reloading : 1;
+  guint                 needs_reload : 1;
 };
 
 typedef struct
@@ -48,6 +50,8 @@ typedef struct
   guint                 mode;
 } State;
 
+static void sysprof_depth_visualizer_reload (SysprofDepthVisualizer *self);
+
 G_DEFINE_TYPE (SysprofDepthVisualizer, sysprof_depth_visualizer, SYSPROF_TYPE_VISUALIZER)
 
 static void
@@ -165,12 +169,17 @@ apply_point_cache_cb (GObject      *object,
   g_assert (SYSPROF_IS_DEPTH_VISUALIZER (self));
   g_assert (G_IS_TASK (result));
 
+  self->reloading = FALSE;
+
   if ((pc = g_task_propagate_pointer (G_TASK (result), NULL)))
     {
       g_clear_pointer (&self->points, point_cache_unref);
       self->points = g_steal_pointer (&pc);
       gtk_widget_queue_draw (GTK_WIDGET (self));
     }
+
+  if (self->needs_reload)
+    sysprof_depth_visualizer_reload (self);
 }
 
 static void
@@ -182,6 +191,14 @@ sysprof_depth_visualizer_reload (SysprofDepthVisualizer *self)
 
   g_assert (SYSPROF_IS_DEPTH_VISUALIZER (self));
 
+  self->needs_reload = TRUE;
+
+  if (self->reloading)
+    return;
+
+  self->reloading = TRUE;
+  self->needs_reload = FALSE;
+
   gtk_widget_get_allocation (GTK_WIDGET (self), &alloc);
 
   st = g_atomic_rc_box_new0 (State);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]