[anjuta] sourceview: keep ref on SourceViewIO during call to input_stream_read_async().



commit bd6e418f40931ffb81e70e1fb25f7785d8c663c3
Author: Carl-Anton Ingmarsson <ca ingmarsson gmail com>
Date:   Sat Dec 22 10:25:41 2012 +0100

    sourceview: keep ref on SourceViewIO during call to input_stream_read_async().
    
    Also disconnect signal handlers from SourceViewIO and cancel it before
    releasing our reference to it in Sourceview.
    
    This fixes warnings and segfaults when a Sourceview is destroyed before the
    async call has finished.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=690641

 plugins/sourceview/sourceview-io.c |   56 ++++++++++++++++++------------------
 plugins/sourceview/sourceview.c    |    8 +++++
 2 files changed, 36 insertions(+), 28 deletions(-)
---
diff --git a/plugins/sourceview/sourceview-io.c b/plugins/sourceview/sourceview-io.c
index 3c749f1..8986ac4 100644
--- a/plugins/sourceview/sourceview-io.c
+++ b/plugins/sourceview/sourceview-io.c
@@ -408,41 +408,41 @@ on_read_finished (GObject* input, GAsyncResult* result, gpointer data)
 	gsize current_bytes = 0;
 	GError* err = NULL;
 
-	current_bytes = g_input_stream_read_finish (input_stream, result, &err);
+	if (!g_cancellable_set_error_if_cancelled (sio->cancel, &err))
+		current_bytes = g_input_stream_read_finish (input_stream, result, &err);
 	if (err)
 	{
 		g_signal_emit_by_name (sio, "open-failed", err);
 		g_error_free (err);
-		g_object_unref (input_stream);
-		g_free (sio->read_buffer);
-		sio->read_buffer = NULL;
-		sio->bytes_read = 0;
-		return;
-	}
-
-	sio->bytes_read += current_bytes;
-	if (current_bytes != 0)
-	{
-		sio->read_buffer = g_realloc (sio->read_buffer, sio->bytes_read + READ_SIZE);
-		g_input_stream_read_async (G_INPUT_STREAM (input_stream),
-								   sio->read_buffer + sio->bytes_read,
-								   READ_SIZE,
-								   G_PRIORITY_LOW,
-								   sio->cancel,
-								   on_read_finished,
-								   sio);
-		return;
 	}
 	else
 	{
-		if (append_buffer (sio, sio->bytes_read))
-			g_signal_emit_by_name (sio, "open-finished");
-		sio->bytes_read = 0;
-		g_object_unref (input_stream);
-		setup_monitor (sio);
-		g_free (sio->read_buffer);
-		sio->read_buffer = NULL;
+		sio->bytes_read += current_bytes;
+		if (current_bytes != 0)
+		{
+			sio->read_buffer = g_realloc (sio->read_buffer, sio->bytes_read + READ_SIZE);
+			g_input_stream_read_async (G_INPUT_STREAM (input_stream),
+									   sio->read_buffer + sio->bytes_read,
+									   READ_SIZE,
+									   G_PRIORITY_LOW,
+									   sio->cancel,
+									   on_read_finished,
+									   sio);
+			return;
+		}
+		else
+		{
+			if (append_buffer (sio, sio->bytes_read))
+				g_signal_emit_by_name (sio, "open-finished");
+			setup_monitor (sio);
+		}
 	}
+
+	g_object_unref (input_stream);
+	g_free (sio->read_buffer);
+	sio->read_buffer = NULL;
+	sio->bytes_read = 0;
+	g_object_unref (sio);
 }
 
 void
@@ -473,7 +473,7 @@ sourceview_io_open (SourceviewIO* sio, GFile* file)
 							   G_PRIORITY_LOW,
 							   sio->cancel,
 							   on_read_finished,
-							   sio);
+							   g_object_ref (sio));
 }
 
 GFile*
diff --git a/plugins/sourceview/sourceview.c b/plugins/sourceview/sourceview.c
index 4683973..a7f4f10 100644
--- a/plugins/sourceview/sourceview.c
+++ b/plugins/sourceview/sourceview.c
@@ -887,6 +887,14 @@ sourceview_dispose(GObject *object)
 	}
 	if (cobj->priv->io)
 	{
+		g_signal_handlers_disconnect_by_func (cobj->priv->io, on_file_changed, cobj);
+		g_signal_handlers_disconnect_by_func (cobj->priv->io, on_file_deleted, cobj);
+		g_signal_handlers_disconnect_by_func (cobj->priv->io, on_open_finish, cobj);
+		g_signal_handlers_disconnect_by_func (cobj->priv->io, on_open_failed, cobj);
+		g_signal_handlers_disconnect_by_func (cobj->priv->io, on_save_finish, cobj);
+		g_signal_handlers_disconnect_by_func (cobj->priv->io, on_save_failed, cobj);
+		
+		sourceview_io_cancel (cobj->priv->io);
 		g_clear_object (&cobj->priv->io);
 	}
 



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