[gnome-builder] buffer: introduce buffer reclamation machinery



commit 59210ea293d00904c3acefcac5ed084818603999
Author: Christian Hergert <christian hergert me>
Date:   Fri Apr 24 12:41:44 2015 -0700

    buffer: introduce buffer reclamation machinery
    
    This gives us the plumbing we need to opportunistically release buffers
    from the buffer manager when they are no longer viewed.
    
    Still work in progress, but this can land as it's own patch.

 libide/ide-buffer-manager.c |    9 +++++
 libide/ide-buffer.c         |   72 +++++++++++++++++++++++++++++++++++++++++++
 libide/ide-buffer.h         |    2 +
 libide/ide-internal.h       |    2 +
 libide/ide-source-view.c    |    4 ++
 5 files changed, 89 insertions(+), 0 deletions(-)
---
diff --git a/libide/ide-buffer-manager.c b/libide/ide-buffer-manager.c
index 47f5f81..14dbba4 100644
--- a/libide/ide-buffer-manager.c
+++ b/libide/ide-buffer-manager.c
@@ -1518,3 +1518,12 @@ ide_buffer_manager_create_buffer (IdeBufferManager *self)
 
   return buffer;
 }
+
+void
+_ide_buffer_manager_reclaim (IdeBufferManager *self,
+                             IdeBuffer        *buffer)
+{
+  g_assert (IDE_IS_BUFFER_MANAGER (self));
+  g_assert (IDE_IS_BUFFER (buffer));
+
+}
diff --git a/libide/ide-buffer.c b/libide/ide-buffer.c
index 6f7e4c5..51b8b25 100644
--- a/libide/ide-buffer.c
+++ b/libide/ide-buffer.c
@@ -32,6 +32,7 @@
 #include "ide-file-settings.h"
 #include "ide-highlighter.h"
 #include "ide-highlight-engine.h"
+#include "ide-internal.h"
 #include "ide-language.h"
 #include "ide-source-location.h"
 #include "ide-source-range.h"
@@ -42,6 +43,7 @@
 
 #define DEFAULT_DIAGNOSE_TIMEOUT_MSEC          333
 #define DEFAULT_DIAGNOSE_CONSERVE_TIMEOUT_MSEC 5000
+#define RECLAIMATION_TIMEOUT_SECS              5
 
 #define TAG_ERROR   "diagnostician::error"
 #define TAG_WARNING "diagnostician::warning"
@@ -67,6 +69,9 @@ typedef struct
 
   GTimeVal                mtime;
 
+  gint                    hold_count;
+  guint                   reclamation_handler;
+
   guint                   changed_on_volume : 1;
   guint                   diagnostics_dirty : 1;
   guint                   highlight_diagnostics : 1;
@@ -806,6 +811,12 @@ ide_buffer_finalize (GObject *object)
 
   IDE_ENTRY;
 
+  if (priv->reclamation_handler != 0)
+    {
+      g_source_remove (priv->reclamation_handler);
+      priv->reclamation_handler = 0;
+    }
+
   ide_clear_weak_pointer (&priv->context);
 
   G_OBJECT_CLASS (ide_buffer_parent_class)->finalize (object);
@@ -1851,3 +1862,64 @@ ide_buffer_get_symbols_finish (IdeBuffer     *self,
 
   return g_task_propagate_pointer (task, error);
 }
+
+static gboolean
+ide_buffer_reclaim_timeout (gpointer data)
+{
+  IdeBuffer *self = data;
+  IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
+  IdeBufferManager *buffer_manager;
+
+  g_assert (IDE_IS_BUFFER (self));
+
+  priv->reclamation_handler = 0;
+
+  buffer_manager = ide_context_get_buffer_manager (priv->context);
+
+  _ide_buffer_manager_reclaim (buffer_manager, self);
+
+  return G_SOURCE_REMOVE;
+}
+
+void
+ide_buffer_hold (IdeBuffer *self)
+{
+  IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
+
+  g_return_if_fail (IDE_IS_BUFFER (self));
+  g_return_if_fail (priv->hold_count >= 0);
+
+  priv->hold_count++;
+
+  if (priv->reclamation_handler != 0)
+    {
+      g_source_remove (priv->reclamation_handler);
+      priv->reclamation_handler = 0;
+    }
+}
+
+void
+ide_buffer_release (IdeBuffer *self)
+{
+  IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
+
+  g_return_if_fail (IDE_IS_BUFFER (self));
+  g_return_if_fail (priv->hold_count >= 0);
+
+  priv->hold_count--;
+
+  /*
+   * If our hold count has reached zero, then queue the buffer for
+   * reclamation by the buffer manager after a grace period has elapsed.
+   * This helps us proactively drop buffers after there are no more views
+   * watching them, but deal with the case where we are transitioning to
+   * a new split after dropping the current split.
+   */
+
+  if ((priv->hold_count == 0) && (priv->reclamation_handler == 0))
+    {
+      priv->reclamation_handler = g_timeout_add_seconds (RECLAIMATION_TIMEOUT_SECS,
+                                                         ide_buffer_reclaim_timeout,
+                                                         self);
+    }
+}
diff --git a/libide/ide-buffer.h b/libide/ide-buffer.h
index 4e2b4cf..b99630b 100644
--- a/libide/ide-buffer.h
+++ b/libide/ide-buffer.h
@@ -104,6 +104,8 @@ void                ide_buffer_get_symbols_async             (IdeBuffer
 GPtrArray          *ide_buffer_get_symbols_finish            (IdeBuffer            *self,
                                                               GAsyncResult         *result,
                                                               GError              **error);
+void                ide_buffer_hold                          (IdeBuffer            *self);
+void                ide_buffer_release                       (IdeBuffer            *self);
 
 G_END_DECLS
 
diff --git a/libide/ide-internal.h b/libide/ide-internal.h
index 0a27226..dbff757 100644
--- a/libide/ide-internal.h
+++ b/libide/ide-internal.h
@@ -60,6 +60,8 @@ void                _ide_buffer_set_mtime              (IdeBuffer             *s
                                                         const GTimeVal        *mtime);
 void                _ide_buffer_set_read_only          (IdeBuffer             *buffer,
                                                         gboolean               read_only);
+void                _ide_buffer_manager_reclaim        (IdeBufferManager      *self,
+                                                        IdeBuffer             *buffer);
 void                _ide_build_system_set_project_file (IdeBuildSystem        *self,
                                                         GFile                 *project_file);
 void                _ide_diagnostic_add_range          (IdeDiagnostic         *self,
diff --git a/libide/ide-source-view.c b/libide/ide-source-view.c
index 6c29cac..ba897bc 100644
--- a/libide/ide-source-view.c
+++ b/libide/ide-source-view.c
@@ -1369,6 +1369,8 @@ ide_source_view_connect_buffer (IdeSourceView *self,
   g_assert (IDE_IS_SOURCE_VIEW (self));
   g_assert (IDE_IS_BUFFER (buffer));
 
+  ide_buffer_hold (buffer);
+
   if (_ide_buffer_get_loading (buffer))
     {
       GtkSourceCompletion *completion;
@@ -1535,6 +1537,8 @@ ide_source_view_disconnect_buffer (IdeSourceView *self,
   g_clear_object (&priv->search_context);
 
   ide_source_view_set_indenter (self, NULL);
+
+  ide_buffer_release (buffer);
 }
 
 static void


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