[libgdata] core: Port GDataUploadStream to use the safe message cancellation methods
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgdata] core: Port GDataUploadStream to use the safe message cancellation methods
- Date: Mon, 20 Dec 2010 13:48:28 +0000 (UTC)
commit 4ca3dbe2b46fab8d578ca9d16ab06fe60be08c26
Author: Philip Withnall <philip tecnocode co uk>
Date: Fri Dec 17 22:22:24 2010 +0000
core: Port GDataUploadStream to use the safe message cancellation methods
GDataUploadStream now uses _gdata_service_actually_send_message(), and
consequently message cancellation is properly an non-racily supported by
holding a GCancellable in the GDataUploadStream's private data.
Helps: bgo#637036
gdata/gdata-upload-stream.c | 31 +++++++++++++++++++++++++------
1 files changed, 25 insertions(+), 6 deletions(-)
---
diff --git a/gdata/gdata-upload-stream.c b/gdata/gdata-upload-stream.c
index 199a2d3..505f172 100644
--- a/gdata/gdata-upload-stream.c
+++ b/gdata/gdata-upload-stream.c
@@ -89,6 +89,7 @@ struct _GDataUploadStreamPrivate {
SoupMessage *message;
GDataBuffer *buffer;
+ GCancellable *cancellable;
GThread *network_thread;
GStaticMutex write_mutex; /* mutex for write operations (specifically, write_finished) */
@@ -275,6 +276,10 @@ gdata_upload_stream_dispose (GObject *object)
* of network operations */
g_output_stream_close (G_OUTPUT_STREAM (object), NULL, NULL);
+ if (priv->cancellable != NULL)
+ g_object_unref (priv->cancellable);
+ priv->cancellable = NULL;
+
if (priv->service != NULL)
g_object_unref (priv->service);
priv->service = NULL;
@@ -668,13 +673,14 @@ static gpointer
upload_thread (GDataUploadStream *self)
{
GDataUploadStreamPrivate *priv = self->priv;
- guint status;
+
+ g_assert (priv->cancellable != NULL);
/* Connect to the wrote-* signals so we can prepare the next chunk for transmission */
g_signal_connect (priv->message, "wrote-headers", (GCallback) wrote_headers_cb, self);
g_signal_connect (priv->message, "wrote-body-data", (GCallback) wrote_body_data_cb, self);
- status = soup_session_send_message (priv->session, priv->message);
+ _gdata_service_actually_send_message (priv->session, priv->message, priv->cancellable, NULL);
/* Signal write_cond, just in case we errored out and finished sending in the middle of a write */
g_static_mutex_lock (&(priv->response_mutex));
@@ -684,18 +690,18 @@ upload_thread (GDataUploadStream *self)
g_static_mutex_unlock (&(priv->write_mutex));
/* Deal with the response if it was unsuccessful */
- if (SOUP_STATUS_IS_SUCCESSFUL (status) == FALSE) {
+ if (SOUP_STATUS_IS_SUCCESSFUL (priv->message->status_code) == FALSE) {
GDataServiceClass *klass = GDATA_SERVICE_GET_CLASS (priv->service);
/* Error! Store it in the structure, and it'll be returned by the next function in the main thread
* which can give an error response.*/
g_assert (klass->parse_error_response != NULL);
- klass->parse_error_response (priv->service, GDATA_OPERATION_UPLOAD, status, priv->message->reason_phrase,
+ klass->parse_error_response (priv->service, GDATA_OPERATION_UPLOAD, priv->message->status_code, priv->message->reason_phrase,
priv->message->response_body->data, priv->message->response_body->length, &(priv->response_error));
}
/* Signal the main thread that the response is ready (good or bad) */
- priv->response_status = status;
+ priv->response_status = priv->message->status_code;
g_cond_signal (priv->finished_cond);
g_static_mutex_unlock (&(priv->response_mutex));
@@ -706,7 +712,20 @@ upload_thread (GDataUploadStream *self)
static void
create_network_thread (GDataUploadStream *self, GError **error)
{
- self->priv->network_thread = g_thread_create ((GThreadFunc) upload_thread, self, TRUE, error);
+ GDataUploadStreamPrivate *priv = self->priv;
+ GError *child_error = NULL;
+
+ g_assert (priv->cancellable == NULL);
+ g_assert (priv->network_thread == NULL);
+
+ priv->cancellable = g_cancellable_new ();
+ priv->network_thread = g_thread_create ((GThreadFunc) upload_thread, self, TRUE, &child_error);
+
+ if (child_error != NULL) {
+ g_object_unref (priv->cancellable);
+ priv->cancellable = NULL;
+ g_propagate_error (error, child_error);
+ }
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]