* SECTION:gtcpconnection
* @title: GTcpConnection
* @short_description: A TCP GSocketConnection
+ * @include: gio/gio.h
* @see_also: #GSocketConnection.
*
* This is the subclass of #GSocketConnection that is created
#include "config.h"
#include "gtcpconnection.h"
#include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
#include "giostream.h"
#include "glibintl.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,
GAsyncReadyCallback callback,
gpointer user_data);
-struct _GTcpConnectionPrivate
-{
- guint graceful_disconnect : 1;
-};
-
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;
}
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;
GSocket *socket;
char buffer[1024];
gssize ret;
- GError *my_error;
gboolean had_error;
socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (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;
->close_fn (stream, cancellable, error) && !had_error;
}
-typedef struct {
- GSimpleAsyncResult *res;
- GCancellable *cancellable;
-} CloseAsyncData;
-
+/* consumes @error */
static void
-close_async_data_free (CloseAsyncData *data)
-{
- g_object_unref (data->res);
- if (data->cancellable)
- g_object_unref (data->cancellable);
- g_free (data);
-}
-
-static void
-async_close_finish (CloseAsyncData *data,
- GError *error /* consumed */,
- 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;
-
- stream = G_IO_STREAM (g_async_result_get_source_object (G_ASYNC_RESULT (data->res)));
+ GIOStream *stream = g_task_get_source_object (task);
+ GCancellable *cancellable = g_task_get_cancellable (task);
- /* 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_take_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_take_error (data->res, 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);
+ {
+ g_error_free (error);
+ return TRUE;
+ }
else
{
- async_close_finish (data, error, TRUE);
+ 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;
}
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);
- 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;
* @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
+ * 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