[gtksourceview/wip/loader-saver] FileLoader: temporary strong ref to the source_buffer
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/loader-saver] FileLoader: temporary strong ref to the source_buffer
- Date: Fri, 28 Mar 2014 17:45:15 +0000 (UTC)
commit 69ba2da08f52882ad341712ce2b93d4e63ade510
Author: Sébastien Wilmet <swilmet gnome org>
Date: Fri Mar 28 18:41:51 2014 +0100
FileLoader: temporary strong ref to the source_buffer
During the file loading.
gtksourceview/gtksourcebufferoutputstream.c | 43 ++++++++++++++-------------
gtksourceview/gtksourcefileloader.c | 29 ++++++++++++++----
2 files changed, 44 insertions(+), 28 deletions(-)
---
diff --git a/gtksourceview/gtksourcebufferoutputstream.c b/gtksourceview/gtksourcebufferoutputstream.c
index 628a3b4..880772b 100644
--- a/gtksourceview/gtksourcebufferoutputstream.c
+++ b/gtksourceview/gtksourcebufferoutputstream.c
@@ -55,8 +55,7 @@
struct _GtkSourceBufferOutputStreamPrivate
{
- /* TODO rename */
- GtkSourceBuffer *doc;
+ GtkSourceBuffer *source_buffer;
GtkTextIter pos;
gchar *buffer;
@@ -118,7 +117,8 @@ gtk_source_buffer_output_stream_set_property (GObject *object,
switch (prop_id)
{
case PROP_BUFFER:
- stream->priv->doc = GTK_SOURCE_BUFFER (g_value_get_object (value));
+ g_assert (stream->priv->source_buffer == NULL);
+ stream->priv->source_buffer = g_value_dup_object (value);
break;
case PROP_ENSURE_TRAILING_NEWLINE:
@@ -142,7 +142,7 @@ gtk_source_buffer_output_stream_get_property (GObject *object,
switch (prop_id)
{
case PROP_BUFFER:
- g_value_set_object (value, stream->priv->doc);
+ g_value_set_object (value, stream->priv->source_buffer);
break;
case PROP_ENSURE_TRAILING_NEWLINE:
@@ -160,6 +160,7 @@ gtk_source_buffer_output_stream_dispose (GObject *object)
{
GtkSourceBufferOutputStream *stream = GTK_SOURCE_BUFFER_OUTPUT_STREAM (object);
+ g_clear_object (&stream->priv->source_buffer);
g_clear_object (&stream->priv->charset_conv);
G_OBJECT_CLASS (gtk_source_buffer_output_stream_parent_class)->dispose (object);
@@ -182,18 +183,18 @@ gtk_source_buffer_output_stream_constructed (GObject *object)
{
GtkSourceBufferOutputStream *stream = GTK_SOURCE_BUFFER_OUTPUT_STREAM (object);
- if (stream->priv->doc == NULL)
+ if (stream->priv->source_buffer == NULL)
{
g_critical ("This should never happen, a problem happened constructing the Buffer Output
Stream!");
return;
}
- gtk_source_buffer_begin_not_undoable_action (stream->priv->doc);
+ gtk_source_buffer_begin_not_undoable_action (stream->priv->source_buffer);
- gtk_text_buffer_set_text (GTK_TEXT_BUFFER (stream->priv->doc), "", 0);
- gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (stream->priv->doc), FALSE);
+ gtk_text_buffer_set_text (GTK_TEXT_BUFFER (stream->priv->source_buffer), "", 0);
+ gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (stream->priv->source_buffer), FALSE);
- gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (stream->priv->doc));
+ gtk_source_buffer_end_not_undoable_action (stream->priv->source_buffer);
G_OBJECT_CLASS (gtk_source_buffer_output_stream_parent_class)->constructed (object);
}
@@ -496,7 +497,7 @@ gtk_source_buffer_output_stream_detect_newline_type (GtkSourceBufferOutputStream
type = GTK_SOURCE_NEWLINE_TYPE_DEFAULT;
- gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (stream->priv->doc),
+ gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (stream->priv->source_buffer),
&iter);
if (gtk_text_iter_ends_line (&iter) || gtk_text_iter_forward_to_line_end (&iter))
@@ -545,10 +546,10 @@ apply_error_tag (GtkSourceBufferOutputStream *stream)
return;
}
- gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (stream->priv->doc),
+ gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (stream->priv->source_buffer),
&start, stream->priv->error_offset);
- _gtk_source_buffer_set_as_invalid_character (stream->priv->doc,
+ _gtk_source_buffer_set_as_invalid_character (stream->priv->source_buffer,
&start,
&stream->priv->pos);
@@ -572,7 +573,7 @@ insert_fallback (GtkSourceBufferOutputStream *stream,
out[2] = hex[(v & 0x0f) >> 0];
out[3] = '\0';
- gtk_text_buffer_insert (GTK_TEXT_BUFFER (stream->priv->doc),
+ gtk_text_buffer_insert (GTK_TEXT_BUFFER (stream->priv->source_buffer),
&stream->priv->pos, (const gchar *)out, 3);
++stream->priv->n_fallback_errors;
@@ -587,7 +588,7 @@ validate_and_insert (GtkSourceBufferOutputStream *stream,
GtkTextIter *iter;
gsize len;
- text_buffer = GTK_TEXT_BUFFER (stream->priv->doc);
+ text_buffer = GTK_TEXT_BUFFER (stream->priv->source_buffer);
iter = &stream->priv->pos;
len = count;
@@ -673,7 +674,7 @@ remove_ending_newline (GtkSourceBufferOutputStream *stream)
GtkTextIter end;
GtkTextIter start;
- gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (stream->priv->doc), &end);
+ gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (stream->priv->source_buffer), &end);
start = end;
gtk_text_iter_set_line_offset (&start, 0);
@@ -687,7 +688,7 @@ remove_ending_newline (GtkSourceBufferOutputStream *stream)
}
/* Delete the empty line which is from 'start' to 'end' */
- gtk_text_buffer_delete (GTK_TEXT_BUFFER (stream->priv->doc),
+ gtk_text_buffer_delete (GTK_TEXT_BUFFER (stream->priv->source_buffer),
&start,
&end);
}
@@ -701,10 +702,10 @@ end_append_text_to_document (GtkSourceBufferOutputStream *stream)
remove_ending_newline (stream);
}
- gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (stream->priv->doc),
+ gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (stream->priv->source_buffer),
FALSE);
- gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (stream->priv->doc));
+ gtk_source_buffer_end_not_undoable_action (stream->priv->source_buffer);
}
static gboolean
@@ -876,9 +877,9 @@ gtk_source_buffer_output_stream_write (GOutputStream *stream,
}
/* Init the undoable action */
- gtk_source_buffer_begin_not_undoable_action (GTK_SOURCE_BUFFER (ostream->priv->doc));
+ gtk_source_buffer_begin_not_undoable_action (ostream->priv->source_buffer);
- gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (ostream->priv->doc),
+ gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (ostream->priv->source_buffer),
&ostream->priv->pos);
ostream->priv->is_initialized = TRUE;
@@ -1046,7 +1047,7 @@ gtk_source_buffer_output_stream_flush (GOutputStream *stream,
apply_error_tag (ostream);
/* See special case above, flush this */
- gtk_text_buffer_insert (GTK_TEXT_BUFFER (ostream->priv->doc),
+ gtk_text_buffer_insert (GTK_TEXT_BUFFER (ostream->priv->source_buffer),
&ostream->priv->pos,
"\r",
1);
diff --git a/gtksourceview/gtksourcefileloader.c b/gtksourceview/gtksourcefileloader.c
index b4ccf40..5767da1 100644
--- a/gtksourceview/gtksourcefileloader.c
+++ b/gtksourceview/gtksourcefileloader.c
@@ -53,7 +53,16 @@ enum
struct _GtkSourceFileLoaderPrivate
{
+ /* Weak reference to the source_buffer. A subclass of GtkSourceBuffer
+ * can have the ownership of the FileLoader. And a FileLoader can be
+ * used several times, so the object can be kept around until the
+ * subclass of GtkSourceBuffer is disposed.
+ * The GtkSourceBufferOutputStream has a strong reference to the
+ * source_buffer, so the buffer will not be finalized when the file is
+ * being loaded. So there can be a temporary reference cycle.
+ */
GtkSourceBuffer *source_buffer;
+
GFile *file;
/* The value of the "input-stream" property. */
@@ -508,7 +517,7 @@ add_gzip_decompressor_stream (GtkSourceFileLoader *loader)
}
static void
-create_streams (GtkSourceFileLoader *loader)
+create_input_stream (GtkSourceFileLoader *loader)
{
loader->priv->auto_detected_compression_type = GTK_SOURCE_COMPRESSION_TYPE_NONE;
@@ -535,10 +544,6 @@ create_streams (GtkSourceFileLoader *loader)
g_return_if_fail (loader->priv->input_stream != NULL);
- loader->priv->output_stream = gtk_source_buffer_output_stream_new (loader->priv->source_buffer,
- loader->priv->candidate_encodings,
-
loader->priv->remove_trailing_newline);
-
/* start reading */
read_file_chunk (loader);
}
@@ -572,7 +577,7 @@ query_info_cb (GFile *file,
return;
}
- create_streams (loader);
+ create_input_stream (loader);
}
static void
@@ -772,6 +777,8 @@ gtk_source_file_loader_load_async (GtkSourceFileLoader *loader,
g_return_if_fail (GTK_SOURCE_IS_FILE_LOADER (loader));
g_return_if_fail (loader->priv->task == NULL);
+ reset (loader);
+
loader->priv->task = g_task_new (loader, cancellable, callback, user_data);
g_task_set_priority (loader->priv->task, io_priority);
@@ -782,12 +789,20 @@ gtk_source_file_loader_load_async (GtkSourceFileLoader *loader,
g_print ("Start loading\n");
});
+ /* The BufferOutputStream has a strong reference to the source_buffer.
+ * We create the BufferOutputStream here so we are sure that the
+ * source_buffer will not be destroyed during the file loading.
+ */
+ loader->priv->output_stream = gtk_source_buffer_output_stream_new (loader->priv->source_buffer,
+ loader->priv->candidate_encodings,
+
loader->priv->remove_trailing_newline);
+
if (loader->priv->input_stream_property != NULL)
{
loader->priv->guess_content_type_from_content = TRUE;
loader->priv->info = g_file_info_new ();
- create_streams (loader);
+ create_input_stream (loader);
}
else
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]