[gnome-builder] buffer: introduce buffer reclamation machinery
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] buffer: introduce buffer reclamation machinery
- Date: Fri, 24 Apr 2015 20:09:25 +0000 (UTC)
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]