From 83626fe905463583e4559507d9a9ee35377a55a8 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Thu, 7 Oct 2010 14:03:11 -0400 Subject: [PATCH 1/3] Keep GCancellable alive during the async calls Keep a reference on GCancellable for the time of the async calls. This is important to allow simple cancel and forget of cancellable by caller. Most call where already implemented correctly, this patch fixes the remaining. --- tests/wocky-test-sasl-auth-server.c | 21 +++++++++++++++- tests/wocky-test-stream.c | 9 +++++- wocky/wocky-openssl.c | 11 ++++++- wocky/wocky-porter.c | 32 ++++++++++++++++++++--- wocky/wocky-tls.c | 9 +++++- wocky/wocky-xmpp-connection.c | 47 +++++++++++++++++++++++++++++++--- 6 files changed, 112 insertions(+), 17 deletions(-) diff --git a/tests/wocky-test-sasl-auth-server.c b/tests/wocky-test-sasl-auth-server.c index 9fd26f2..64d2c22 100644 --- a/tests/wocky-test-sasl-auth-server.c +++ b/tests/wocky-test-sasl-auth-server.c @@ -160,6 +160,7 @@ test_sasl_auth_server_dispose (GObject *object) #endif g_warn_if_fail (priv->result == NULL); + g_warn_if_fail (priv->cancellable == NULL); if (G_OBJECT_CLASS (test_sasl_auth_server_parent_class)->dispose) G_OBJECT_CLASS (test_sasl_auth_server_parent_class)->dispose (object); @@ -271,6 +272,12 @@ post_auth_recv_stanza (GObject *source, GSimpleAsyncResult *r = priv->result; priv->result = NULL; + + if (priv->cancellable != NULL) + g_object_unref (priv->cancellable); + + priv->cancellable = NULL; + g_simple_async_result_set_from_error (r, error); g_simple_async_result_complete (r); @@ -317,6 +324,12 @@ post_auth_open_sent (GObject *source, GSimpleAsyncResult *r = priv->result; priv->result = NULL; + + if (priv->cancellable != NULL) + g_object_unref (priv->cancellable); + + priv->cancellable = NULL; + g_simple_async_result_complete (r); g_object_unref (r); } @@ -391,6 +404,10 @@ failure_sent (GObject *source, if (r != NULL) { + if (priv->cancellable != NULL) + g_object_unref (priv->cancellable); + + priv->cancellable = NULL; g_simple_async_result_complete (r); g_object_unref (r); } @@ -994,7 +1011,9 @@ test_sasl_auth_server_auth_async (GObject *obj, priv->state = AUTH_STATE_STARTED; priv->conn = g_object_ref (conn); - priv->cancellable = cancellable; + + if (cancellable != NULL) + priv->cancellable = g_object_ref (cancellable); /* save the details of the point ot which we will hand back control */ if (cb != NULL) diff --git a/tests/wocky-test-stream.c b/tests/wocky-test-stream.c index 5f93936..1f955a1 100644 --- a/tests/wocky-test-stream.c +++ b/tests/wocky-test-stream.c @@ -309,9 +309,10 @@ read_async_complete (WockyTestInputStream *self) { g_signal_handler_disconnect (self->read_cancellable, self->read_cancellable_sig_id); + g_object_unref (self->read_cancellable); + self->read_cancellable = NULL; } - self->read_cancellable = NULL; self->read_result = NULL; g_simple_async_result_complete_in_idle (r); @@ -358,11 +359,12 @@ wocky_test_input_stream_read_async (GInputStream *stream, g_error_free (self->read_error); self->read_error = NULL; read_async_complete (self); + return; } if (cancellable != NULL) { - self->read_cancellable = cancellable; + self->read_cancellable = g_object_ref (cancellable); self->read_cancellable_sig_id = g_signal_connect (cancellable, "cancelled", G_CALLBACK (read_cancelled_cb), self); } @@ -434,6 +436,9 @@ wocky_test_input_stream_dispose (GObject *object) g_async_queue_unref (self->queue); self->queue = NULL; + g_warn_if_fail (self->read_result == NULL); + g_warn_if_fail (self->read_cancellable == NULL); + /* release any references held by the object here */ if (G_OBJECT_CLASS (wocky_test_input_stream_parent_class)->dispose) G_OBJECT_CLASS (wocky_test_input_stream_parent_class)->dispose (object); diff --git a/wocky/wocky-openssl.c b/wocky/wocky-openssl.c index 62b454b..9e95872 100644 --- a/wocky/wocky-openssl.c +++ b/wocky/wocky-openssl.c @@ -282,6 +282,14 @@ wocky_tls_job_make_result (WockyTLSJob *job, if (job->source_object) g_object_unref (job->source_object); + + job->source_object = NULL; + + if (job->cancellable) + g_object_unref (job->cancellable); + + job->cancellable = NULL; + job->active = FALSE; return simple; @@ -625,9 +633,8 @@ wocky_tls_job_start (WockyTLSJob *job, job->source_object = g_object_ref (source_object); job->io_priority = io_priority; - job->cancellable = cancellable; if (cancellable) - g_object_ref (cancellable); + job->cancellable = g_object_ref (cancellable); job->callback = callback; job->user_data = user_data; job->source_tag = source_tag; diff --git a/wocky/wocky-porter.c b/wocky/wocky-porter.c index 6f08d67..9874085 100644 --- a/wocky/wocky-porter.c +++ b/wocky/wocky-porter.c @@ -606,12 +606,24 @@ wocky_porter_dispose (GObject *object) priv->close_result = NULL; } + if (priv->close_cancellable != NULL) + { + g_object_unref (priv->close_cancellable); + priv->close_cancellable = NULL; + } + if (priv->force_close_result != NULL) { g_object_unref (priv->force_close_result); priv->force_close_result = NULL; } + if (priv->force_close_cancellable != NULL) + { + g_object_unref (priv->force_close_cancellable); + priv->force_close_cancellable = NULL; + } + if (G_OBJECT_CLASS (wocky_porter_parent_class)->dispose) G_OBJECT_CLASS (wocky_porter_parent_class)->dispose (object); } @@ -866,12 +878,19 @@ complete_close (WockyPorter *self) G_IO_ERROR_CANCELLED, "closing operation was cancelled"); } - g_simple_async_result_complete (priv->close_result); + if (priv->close_cancellable) + g_object_unref (priv->close_cancellable); - tmp = priv->close_result; - priv->close_result = NULL; priv->close_cancellable = NULL; + if (priv->force_close_cancellable) + g_object_unref (priv->force_close_cancellable); + + priv->force_close_cancellable = NULL; + + tmp = priv->close_result; + priv->close_result = NULL; + g_simple_async_result_complete (tmp); g_object_unref (tmp); } @@ -1399,7 +1418,8 @@ wocky_porter_close_async (WockyPorter *self, priv->close_result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, wocky_porter_close_async); - priv->close_cancellable = cancellable; + if (cancellable != NULL) + priv->close_cancellable = g_object_ref (cancellable); g_signal_emit (self, signals[CLOSING], 0); @@ -1815,7 +1835,9 @@ wocky_porter_force_close_async (WockyPorter *self, priv->force_close_result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, wocky_porter_force_close_async); - priv->force_close_cancellable = cancellable; + + if (cancellable != NULL) + priv->force_close_cancellable = g_object_ref (cancellable); /* force_close_result now keeps a ref on ourself so we can release the ref * without risking to destroy the object */ diff --git a/wocky/wocky-tls.c b/wocky/wocky-tls.c index 21a3911..96d5dab 100644 --- a/wocky/wocky-tls.c +++ b/wocky/wocky-tls.c @@ -327,7 +327,13 @@ wocky_tls_job_make_result (WockyTLSJob *job, g_error_free (error); } + if (job->cancellable) + g_object_unref (job->cancellable); + job->cancellable = NULL; + g_object_unref (job->source_object); + job->source_object = NULL; + job->active = FALSE; return simple; @@ -461,9 +467,8 @@ wocky_tls_job_start (WockyTLSJob *job, job->source_object = g_object_ref (source_object); job->io_priority = io_priority; - job->cancellable = cancellable; if (cancellable) - g_object_ref (cancellable); + job->cancellable = g_object_ref (cancellable); job->callback = callback; job->user_data = user_data; job->source_tag = source_tag; diff --git a/wocky/wocky-xmpp-connection.c b/wocky/wocky-xmpp-connection.c index 28a5b96..cbc22df 100644 --- a/wocky/wocky-xmpp-connection.c +++ b/wocky/wocky-xmpp-connection.c @@ -228,6 +228,30 @@ wocky_xmpp_connection_dispose (GObject *object) priv->writer = NULL; } + if (priv->output_result != NULL) + { + g_object_unref (priv->output_result); + priv->output_result = NULL; + } + + if (priv->output_cancellable != NULL) + { + g_object_unref (priv->output_cancellable); + priv->output_cancellable = NULL; + } + + if (priv->input_result != NULL) + { + g_object_unref (priv->input_result); + priv->input_result = NULL; + } + + if (priv->input_cancellable != NULL) + { + g_object_unref (priv->input_cancellable); + priv->input_cancellable = NULL; + } + /* release any references held by the object here */ if (G_OBJECT_CLASS (wocky_xmpp_connection_parent_class)->dispose) @@ -304,6 +328,9 @@ finished: { GSimpleAsyncResult *r = priv->output_result; + if (priv->output_cancellable != NULL) + g_object_unref (priv->output_cancellable); + priv->output_cancellable = NULL; priv->output_result = NULL; @@ -376,7 +403,9 @@ wocky_xmpp_connection_send_open_async (WockyXmppConnection *connection, priv->output_result = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, wocky_xmpp_connection_send_open_async); - priv->output_cancellable = cancellable; + if (cancellable != NULL) + priv->output_cancellable = g_object_ref (cancellable); + priv->offset = 0; priv->length = 0; @@ -523,6 +552,9 @@ finished: { GSimpleAsyncResult *r = priv->input_result; + if (priv->input_cancellable != NULL) + g_object_unref (priv->input_cancellable); + priv->input_cancellable = NULL; priv->input_result = NULL; @@ -567,7 +599,8 @@ wocky_xmpp_connection_recv_open_async (WockyXmppConnection *connection, priv->input_result = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, wocky_xmpp_connection_recv_open_async); - priv->input_cancellable = cancellable; + if (cancellable != NULL) + priv->input_cancellable = g_object_ref (cancellable); wocky_xmpp_connection_do_read (connection); @@ -697,7 +730,8 @@ wocky_xmpp_connection_send_stanza_async (WockyXmppConnection *connection, priv->output_result = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, wocky_xmpp_connection_send_stanza_async); - priv->output_cancellable = cancellable; + if (cancellable != NULL) + priv->output_cancellable = g_object_ref (cancellable); priv->offset = 0; priv->length = 0; @@ -807,7 +841,8 @@ wocky_xmpp_connection_recv_stanza_async (WockyXmppConnection *connection, return; } - priv->input_cancellable = cancellable; + if (cancellable != NULL) + priv->input_cancellable = g_object_ref (cancellable); wocky_xmpp_connection_do_read (connection); return; @@ -931,7 +966,9 @@ wocky_xmpp_connection_send_close_async (WockyXmppConnection *connection, priv->output_result = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, wocky_xmpp_connection_send_close_async); - priv->output_cancellable = cancellable; + if (cancellable != NULL) + priv->output_cancellable = g_object_ref (cancellable); + priv->offset = 0; priv->length = 0; -- 1.7.2.3