[glib-networking/wip/pwithnall/dtls: 14/24] gnutls: Implement half-duplex close in GTlsInputStreamGnutls
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/wip/pwithnall/dtls: 14/24] gnutls: Implement half-duplex close in GTlsInputStreamGnutls
- Date: Wed, 7 Oct 2015 13:24:22 +0000 (UTC)
commit 400d4cf0969805ad4d728d6e3d0782d30ba38ddb
Author: Philip Withnall <philip withnall collabora co uk>
Date: Fri Sep 26 15:50:23 2014 +0100
gnutls: Implement half-duplex close in GTlsInputStreamGnutls
https://bugzilla.gnome.org/show_bug.cgi?id=735754
tls/gnutls/gtlsinputstream-gnutls.c | 83 +++++++++++++++++++++++++++++++++++
1 files changed, 83 insertions(+), 0 deletions(-)
---
diff --git a/tls/gnutls/gtlsinputstream-gnutls.c b/tls/gnutls/gtlsinputstream-gnutls.c
index c6789ea..ca9cbe2 100644
--- a/tls/gnutls/gtlsinputstream-gnutls.c
+++ b/tls/gnutls/gtlsinputstream-gnutls.c
@@ -126,6 +126,86 @@ g_tls_input_stream_gnutls_pollable_read_nonblocking (GPollableInputStream *poll
return ret;
}
+static gboolean
+g_tls_input_stream_gnutls_close (GInputStream *stream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (stream);
+ GIOStream *conn;
+ gboolean ret;
+
+ conn = g_weak_ref_get (&tls_stream->priv->weak_conn);
+
+ /* Special case here because this is called by the finalize
+ * of the main GTlsConnection object.
+ */
+ if (conn == NULL)
+ return TRUE;
+
+ ret = g_tls_connection_gnutls_close_internal (conn, G_TLS_DIRECTION_READ,
+ cancellable, error);
+
+ g_object_unref (conn);
+ return ret;
+}
+
+/* We do async close as synchronous-in-a-thread so we don't need to
+ * implement G_IO_IN/G_IO_OUT flip-flopping just for this one case
+ * (since handshakes are also done synchronously now).
+ */
+static void
+close_thread (GTask *task,
+ gpointer object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ GTlsInputStreamGnutls *tls_stream = object;
+ GError *error = NULL;
+ GIOStream *conn;
+
+ conn = g_weak_ref_get (&tls_stream->priv->weak_conn);
+
+ if (conn && !g_tls_connection_gnutls_close_internal (conn,
+ G_TLS_DIRECTION_READ,
+ cancellable, &error))
+ g_task_return_error (task, error);
+ else
+ g_task_return_boolean (task, TRUE);
+
+ if (conn)
+ g_object_unref (conn);
+}
+
+
+static void
+g_tls_input_stream_gnutls_close_async (GInputStream *stream,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_tls_input_stream_gnutls_close_async);
+ g_task_set_priority (task, io_priority);
+ g_task_run_in_thread (task, close_thread);
+ g_object_unref (task);
+}
+
+static gboolean
+g_tls_input_stream_gnutls_close_finish (GInputStream *stream,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
+ g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
+ g_tls_input_stream_gnutls_close_async, FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
static void
g_tls_input_stream_gnutls_class_init (GTlsInputStreamGnutlsClass *klass)
{
@@ -138,6 +218,9 @@ g_tls_input_stream_gnutls_class_init (GTlsInputStreamGnutlsClass *klass)
gobject_class->finalize = g_tls_input_stream_gnutls_finalize;
input_stream_class->read_fn = g_tls_input_stream_gnutls_read;
+ input_stream_class->close_fn = g_tls_input_stream_gnutls_close;
+ input_stream_class->close_async = g_tls_input_stream_gnutls_close_async;
+ input_stream_class->close_finish = g_tls_input_stream_gnutls_close_finish;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]