[libgdata] core: Block gdata_download_stream_close() on completion of network activity
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgdata] core: Block gdata_download_stream_close() on completion of network activity
- Date: Mon, 20 Dec 2010 13:47:33 +0000 (UTC)
commit 3e9e1dbfa7b8a2853635aa3f0ea64421290490b5
Author: Philip Withnall <philip tecnocode co uk>
Date: Thu Dec 16 17:36:04 2010 +0000
core: Block gdata_download_stream_close() on completion of network activity
It wasn't previously waiting for the network activity to finish, which it
should (if any has started).
Helps: bgo#637036
gdata/gdata-download-stream.c | 33 +++++++++++++++++++++++++++++----
1 files changed, 29 insertions(+), 4 deletions(-)
---
diff --git a/gdata/gdata-download-stream.c b/gdata/gdata-download-stream.c
index 75c3fc3..d356586 100644
--- a/gdata/gdata-download-stream.c
+++ b/gdata/gdata-download-stream.c
@@ -68,10 +68,13 @@ struct _GDataDownloadStreamPrivate {
SoupSession *session;
SoupMessage *message;
GDataBuffer *buffer;
- gboolean finished;
goffset offset; /* seek offset */
GThread *network_thread;
+ gboolean finished;
+ GCond *finished_cond;
+ GStaticMutex finished_mutex; /* mutex for ->finished, protected by ->finished_cond */
+
/* Cached data from the SoupMessage */
gchar *content_type;
gssize content_length;
@@ -184,6 +187,11 @@ gdata_download_stream_init (GDataDownloadStream *self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GDATA_TYPE_DOWNLOAD_STREAM, GDataDownloadStreamPrivate);
self->priv->content_length = -1;
self->priv->buffer = gdata_buffer_new ();
+
+ self->priv->finished = FALSE;
+ self->priv->finished_cond = g_cond_new ();
+ g_static_mutex_init (&(self->priv->finished_mutex));
+
g_static_mutex_init (&(self->priv->content_mutex));
}
@@ -237,6 +245,10 @@ gdata_download_stream_finalize (GObject *object)
GDataDownloadStreamPrivate *priv = GDATA_DOWNLOAD_STREAM (object)->priv;
g_thread_join (priv->network_thread);
+
+ g_cond_free (priv->finished_cond);
+ g_static_mutex_free (&(priv->finished_mutex));
+
g_static_mutex_free (&(priv->content_mutex));
gdata_buffer_free (priv->buffer);
g_free (priv->download_uri);
@@ -339,8 +351,15 @@ gdata_download_stream_close (GInputStream *stream, GCancellable *cancellable, GE
{
GDataDownloadStreamPrivate *priv = GDATA_DOWNLOAD_STREAM (stream)->priv;
- if (priv->finished == FALSE)
+ g_static_mutex_lock (&(priv->finished_mutex));
+
+ /* If the operation has started but hasn't already finished, cancel the SoupMessage and wait for it to finish before returning */
+ if (priv->network_thread != NULL && priv->finished == FALSE) {
soup_session_cancel_message (priv->session, priv->message, SOUP_STATUS_CANCELLED);
+ g_cond_wait (priv->finished_cond, g_static_mutex_get_mutex (&(priv->finished_mutex)));
+ }
+
+ g_static_mutex_unlock (&(priv->finished_mutex));
return TRUE;
}
@@ -457,10 +476,16 @@ got_chunk_cb (SoupMessage *message, SoupBuffer *buffer, GDataDownloadStream *sel
static void
finished_cb (SoupMessage *message, GDataDownloadStream *self)
{
- self->priv->finished = TRUE;
+ GDataDownloadStreamPrivate *priv = self->priv;
/* Mark the buffer as having reached EOF */
- gdata_buffer_push_data (self->priv->buffer, NULL, 0);
+ 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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]