[libgdata] core: Don't signal completion of a download in a callback function



commit 475e64a25734af7366984e5a5cdb070e01996dd1
Author: Philip Withnall <philip tecnocode co uk>
Date:   Mon Dec 20 10:12:04 2010 +0000

    core: Don't signal completion of a download in a callback function
    
    If completion of a GDataDownloadStream download is signalled in a callback
    function, it's possible for the stream object to be unreffed and finalised
    while the network thread is still using the object (as it has some cleanup
    work to do after emitting the â??finishedâ?? signal).
    
    This is fixed by moving signalling of finished_cond to the end of the thread's
    main function.

 gdata/gdata-download-stream.c |   29 +++++++++++++----------------
 1 files changed, 13 insertions(+), 16 deletions(-)
---
diff --git a/gdata/gdata-download-stream.c b/gdata/gdata-download-stream.c
index 493eefe..36a7195 100644
--- a/gdata/gdata-download-stream.c
+++ b/gdata/gdata-download-stream.c
@@ -672,35 +672,32 @@ got_chunk_cb (SoupMessage *message, SoupBuffer *buffer, GDataDownloadStream *sel
 	gdata_buffer_push_data (self->priv->buffer, (const guint8*) buffer->data, buffer->length);
 }
 
-static void
-finished_cb (SoupMessage *message, GDataDownloadStream *self)
-{
-	GDataDownloadStreamPrivate *priv = self->priv;
-
-	/* Mark the buffer as having reached EOF */
-	gdata_buffer_push_data (priv->buffer, NULL, 0);
-
-	/* Mark the download as finished */
-	g_static_mutex_lock (&(priv->finished_mutex));
-	priv->finished = TRUE;
-	g_cond_signal (priv->finished_cond);
-	g_static_mutex_unlock (&(priv->finished_mutex));
-}
-
 static gpointer
 download_thread (GDataDownloadStream *self)
 {
 	GDataDownloadStreamPrivate *priv = self->priv;
 
+	g_object_ref (self);
+
 	g_assert (priv->network_cancellable != NULL);
 
 	/* Connect to the got-headers signal so we can notify clients of the values of content-type and content-length */
 	g_signal_connect (priv->message, "got-headers", (GCallback) got_headers_cb, self);
 	g_signal_connect (priv->message, "got-chunk", (GCallback) got_chunk_cb, self);
-	g_signal_connect (priv->message, "finished", (GCallback) finished_cb, self);
 
 	_gdata_service_actually_send_message (priv->session, priv->message, priv->network_cancellable, NULL);
 
+	/* Mark the buffer as having reached EOF */
+	gdata_buffer_push_data (priv->buffer, NULL, 0);
+
+	/* Mark the download as finished */
+	g_static_mutex_lock (&(priv->finished_mutex));
+	priv->finished = TRUE;
+	g_cond_signal (priv->finished_cond);
+	g_static_mutex_unlock (&(priv->finished_mutex));
+
+	g_object_unref (self);
+
 	return NULL;
 }
 



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