X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgtcpconnection.c;h=8ff355d46b04b006b498e8327d4464b28a8757b0;hb=356a3987cee7ceddcb3fe623edf0bd2881895add;hp=59f9c1bebf31727a15c11c26a76e8ad27c229308;hpb=73007021796f33d7ccec4e5f2bb2b2f8660347f2;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gtcpconnection.c b/gio/gtcpconnection.c index 59f9c1b..8ff355d 100644 --- a/gio/gtcpconnection.c +++ b/gio/gtcpconnection.c @@ -11,33 +11,33 @@ */ /** - * SECTION: gtcpconnection + * SECTION:gtcpconnection * @title: GTcpConnection - * @short_description: a TCP #GSocketConnection + * @short_description: A TCP GSocketConnection + * @include: gio/gio.h * @see_also: #GSocketConnection. * * This is the subclass of #GSocketConnection that is created * for TCP/IP sockets. * - * It is currently empty; it offers no additional functionality - * over its base class. - * - * Eventually, some TCP-specific socket stuff will be added. - * * Since: 2.22 */ #include "config.h" #include "gtcpconnection.h" #include "gasyncresult.h" -#include "gsimpleasyncresult.h" +#include "gtask.h" #include "giostream.h" #include "glibintl.h" -#include "gioalias.h" +struct _GTcpConnectionPrivate +{ + guint graceful_disconnect : 1; +}; G_DEFINE_TYPE_WITH_CODE (GTcpConnection, g_tcp_connection, G_TYPE_SOCKET_CONNECTION, + G_ADD_PRIVATE (GTcpConnection) g_socket_connection_factory_register_type (g_define_type_id, G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, @@ -65,11 +65,6 @@ static void g_tcp_connection_close_async (GIOStream *stream, GAsyncReadyCallback callback, gpointer user_data); -struct _GTcpConnectionPrivate -{ - guint graceful_disconnect : 1; -}; - enum { @@ -80,9 +75,7 @@ enum static void g_tcp_connection_init (GTcpConnection *connection) { - connection->priv = G_TYPE_INSTANCE_GET_PRIVATE (connection, - G_TYPE_TCP_CONNECTION, - GTcpConnectionPrivate); + connection->priv = g_tcp_connection_get_instance_private (connection); connection->priv->graceful_disconnect = FALSE; } @@ -131,8 +124,6 @@ g_tcp_connection_class_init (GTcpConnectionClass *class) GObjectClass *gobject_class = G_OBJECT_CLASS (class); GIOStreamClass *stream_class = G_IO_STREAM_CLASS (class); - g_type_class_add_private (class, sizeof (GTcpConnectionPrivate)); - gobject_class->set_property = g_tcp_connection_set_property; gobject_class->get_property = g_tcp_connection_get_property; @@ -157,7 +148,6 @@ g_tcp_connection_close (GIOStream *stream, GSocket *socket; char buffer[1024]; gssize ret; - GError *my_error; gboolean had_error; socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (stream)); @@ -175,20 +165,13 @@ g_tcp_connection_close (GIOStream *stream, { while (TRUE) { - my_error = NULL; - ret = g_socket_receive (socket, buffer, sizeof (buffer), - cancellable, &my_error); + ret = g_socket_receive_with_blocking (socket, buffer, sizeof (buffer), + TRUE, cancellable, error); if (ret < 0) { - if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) - g_error_free (my_error); - else - { - had_error = TRUE; - g_propagate_error (error, my_error); - error = NULL; - break; - } + had_error = TRUE; + error = NULL; + break; } if (ret == 0) break; @@ -200,80 +183,60 @@ g_tcp_connection_close (GIOStream *stream, ->close_fn (stream, cancellable, error) && !had_error; } -typedef struct { - GSimpleAsyncResult *res; - GCancellable *cancellable; -} CloseAsyncData; - -static void -close_async_data_free (CloseAsyncData *data) -{ - g_object_unref (data->res); - if (data->cancellable) - g_object_unref (data->cancellable); - g_free (data); -} - +/* consumes @error */ static void -async_close_finish (CloseAsyncData *data, - GError *error, - gboolean in_mainloop) +async_close_finish (GTask *task, + GError *error) { GIOStreamClass *parent = G_IO_STREAM_CLASS (g_tcp_connection_parent_class); - GIOStream *stream; - GError *my_error; + GIOStream *stream = g_task_get_source_object (task); + GCancellable *cancellable = g_task_get_cancellable (task); - stream = G_IO_STREAM (g_async_result_get_source_object (G_ASYNC_RESULT (data->res))); - - /* Doesn't block, ignore error */ + /* Close underlying stream, ignoring further errors if we already + * have one. + */ if (error) - { - parent->close_fn (stream, data->cancellable, NULL); - g_simple_async_result_set_from_error (data->res, error); - } + parent->close_fn (stream, cancellable, NULL); else - { - my_error = NULL; - parent->close_fn (stream, data->cancellable, &my_error); - if (my_error) - { - g_simple_async_result_set_from_error (data->res, my_error); - g_error_free (my_error); - } - } + parent->close_fn (stream, cancellable, &error); - if (in_mainloop) - g_simple_async_result_complete (data->res); + if (error) + g_task_return_error (task, error); else - g_simple_async_result_complete_in_idle (data->res); + g_task_return_boolean (task, TRUE); } + static gboolean close_read_ready (GSocket *socket, GIOCondition condition, - CloseAsyncData *data) + GTask *task) { GError *error = NULL; char buffer[1024]; gssize ret; - ret = g_socket_receive (socket, buffer, sizeof (buffer), - data->cancellable, &error); + ret = g_socket_receive_with_blocking (socket, buffer, sizeof (buffer), + FALSE, g_task_get_cancellable (task), + &error); if (ret < 0) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) - g_error_free (error); - else { - async_close_finish (data, error, TRUE); g_error_free (error); + return TRUE; + } + else + { + async_close_finish (task, error); + g_object_unref (task); return FALSE; } } if (ret == 0) { - async_close_finish (data, NULL, TRUE); + async_close_finish (task, NULL); return FALSE; } @@ -289,39 +252,29 @@ g_tcp_connection_close_async (GIOStream *stream, gpointer user_data) { GTcpConnection *connection = G_TCP_CONNECTION (stream); - CloseAsyncData *data; GSocket *socket; GSource *source; GError *error; + GTask *task; if (connection->priv->graceful_disconnect && !g_cancellable_is_cancelled (cancellable) /* Cancelled -> close fast */) { - data = g_new (CloseAsyncData, 1); - data->res = - g_simple_async_result_new (G_OBJECT (stream), callback, user_data, - g_tcp_connection_close_async); - if (cancellable) - data->cancellable = g_object_ref (cancellable); - else - data->cancellable = NULL; + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_priority (task, io_priority); socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (stream)); error = NULL; if (!g_socket_shutdown (socket, FALSE, TRUE, &error)) { - async_close_finish (data, error, FALSE); - g_error_free (error); - close_async_data_free (data); + g_task_return_error (task, error); + g_object_unref (task); return; } source = g_socket_create_source (socket, G_IO_IN, cancellable); - g_source_set_callback (source, - (GSourceFunc) close_read_ready, - data, (GDestroyNotify)close_async_data_free); - g_source_attach (source, g_main_context_get_thread_default ()); + g_task_attach_source (task, source, (GSourceFunc) close_read_ready); g_source_unref (source); return; @@ -336,8 +289,8 @@ g_tcp_connection_close_async (GIOStream *stream, * @connection: a #GTcpConnection * @graceful_disconnect: Whether to do graceful disconnects or not * - * This enabled graceful disconnects on close. A graceful disconnect - * means that we signal the recieving end that the connection is terminated + * This enables graceful disconnects on close. A graceful disconnect + * means that we signal the receiving end that the connection is terminated * and wait for it to close the connection before closing the connection. * * A graceful disconnect means that we can be sure that we successfully sent @@ -376,7 +329,3 @@ g_tcp_connection_get_graceful_disconnect (GTcpConnection *connection) { return connection->priv->graceful_disconnect; } - - -#define __G_TCP_CONNECTION_C__ -#include "gioaliasdef.c"