[Pkg-telepathy-commits] [telepathy-idle] 05/26: ServerConnection: kill async read when disconnecting

Simon McVittie smcv at debian.org
Thu Apr 3 17:49:41 UTC 2014


This is an automated email from the git hooks/post-receive script.

smcv pushed a commit to branch debian
in repository telepathy-idle.

commit 42fd234c2336718a93993829c4d55c819b172012
Author: Lionel Landwerlin <llandwerlin at gmail.com>
Date:   Thu Aug 29 23:48:10 2013 +0100

    ServerConnection: kill async read when disconnecting
    
    GSocket creates GSources to provide GInputStream and GOutputStream
    objects. Interestingly, it doesn't set the GIOCondition on the GSource
    to handle G_IO_NVAL (ie. your file descriptor is not valid anymore).
    
    It means that if your trying to read asynchronously from the socket
    while someone else closes the socket, you end with an GInputStream
    that can never complete its asynchronous read operation because the
    file descriptor isn't valid anymore but that isn't a condition to
    dispatch the GSource and end the asynchronous read with an error.
    Alternatively, this wakes up the gmainloop all the time => 100% cpu
    consumption.
    
    Bug: https://bugs.freedesktop.org/show_bug.cgi?id=64923
    Reviewed-by: Simon McVittie <simon.mcvittie at collabora.co.uk>
---
 src/idle-server-connection.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/idle-server-connection.c b/src/idle-server-connection.c
index b593fa3..a921c33 100644
--- a/src/idle-server-connection.c
+++ b/src/idle-server-connection.c
@@ -71,6 +71,7 @@ struct _IdleServerConnectionPrivate {
 
 	GSocketClient *socket_client;
 	GIOStream *io_stream;
+	GCancellable *read_cancellable;
 	GCancellable *cancellable;
 
 	IdleServerConnectionState state;
@@ -245,8 +246,12 @@ static void change_state(IdleServerConnection *conn, IdleServerConnectionState s
 static void _input_stream_read(IdleServerConnection *conn, GInputStream *input_stream, GAsyncReadyCallback callback) {
 	IdleServerConnectionPrivate *priv = IDLE_SERVER_CONNECTION_GET_PRIVATE(conn);
 
+	if (priv->read_cancellable == NULL)
+		priv->read_cancellable = g_cancellable_new ();
+
+
 	memset(priv->input_buffer, '\0', sizeof(priv->input_buffer));
-	g_input_stream_read_async (input_stream, &priv->input_buffer, sizeof(priv->input_buffer) - 1, G_PRIORITY_DEFAULT, NULL, callback, conn);
+	g_input_stream_read_async (input_stream, &priv->input_buffer, sizeof(priv->input_buffer) - 1, G_PRIORITY_DEFAULT, priv->read_cancellable, callback, conn);
 }
 
 static void _input_stream_read_ready(GObject *source_object, GAsyncResult *res, gpointer user_data) {
@@ -514,6 +519,9 @@ void idle_server_connection_disconnect_full_async(IdleServerConnection *conn, gu
 
 	priv->reason = reason;
 
+	g_cancellable_cancel (priv->read_cancellable);
+	g_clear_object (&priv->read_cancellable);
+
 	result = g_simple_async_result_new(G_OBJECT(conn), callback, user_data, idle_server_connection_disconnect_full_async);
 	g_io_stream_close_async(priv->io_stream, G_PRIORITY_DEFAULT, cancellable, _close_ready, result);
 	g_object_unref(priv->io_stream);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-telepathy/telepathy-idle.git



More information about the Pkg-telepathy-commits mailing list