mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-10 03:04:05 +02:00
gtlsconnection: use a vfunc to implement get_negotiated_protocol()
The current code is unsafe to use from multiple threads at once. GIOStream functions like this are supposed to be semi-threadsafe. It's allowed for them to be called on both a reader thread and a writer thread at the same time. Of course, it's still tricky and dangerous, because it's only *really* threadsafe if the handshake has finished, and API users have no plausible way to know that because the API does not require performing an explicit handshake operation. But that's a glib-networking problem. We can at least avoid the most obvious threadsafety issue here in the API layer. Note that we'll need to implement the new vfunc in glib-networking for this to actually work. Fixes #2393
This commit is contained in:
committed by
Michael Catanzaro
parent
74595ab64a
commit
5e6c2e1e2c
@@ -55,12 +55,7 @@
|
|||||||
* Since: 2.28
|
* Since: 2.28
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct _GTlsConnectionPrivate
|
G_DEFINE_ABSTRACT_TYPE (GTlsConnection, g_tls_connection, G_TYPE_IO_STREAM)
|
||||||
{
|
|
||||||
gchar *negotiated_protocol;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GTlsConnection, g_tls_connection, G_TYPE_IO_STREAM)
|
|
||||||
|
|
||||||
static void g_tls_connection_get_property (GObject *object,
|
static void g_tls_connection_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@@ -70,7 +65,6 @@ static void g_tls_connection_set_property (GObject *object,
|
|||||||
guint prop_id,
|
guint prop_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
static void g_tls_connection_finalize (GObject *object);
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ACCEPT_CERTIFICATE,
|
ACCEPT_CERTIFICATE,
|
||||||
@@ -104,7 +98,6 @@ g_tls_connection_class_init (GTlsConnectionClass *klass)
|
|||||||
|
|
||||||
gobject_class->get_property = g_tls_connection_get_property;
|
gobject_class->get_property = g_tls_connection_get_property;
|
||||||
gobject_class->set_property = g_tls_connection_set_property;
|
gobject_class->set_property = g_tls_connection_set_property;
|
||||||
gobject_class->finalize = g_tls_connection_finalize;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GTlsConnection:base-io-stream:
|
* GTlsConnection:base-io-stream:
|
||||||
@@ -413,17 +406,6 @@ g_tls_connection_set_property (GObject *object,
|
|||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
g_tls_connection_finalize (GObject *object)
|
|
||||||
{
|
|
||||||
GTlsConnection *conn = G_TLS_CONNECTION(object);
|
|
||||||
GTlsConnectionPrivate *priv = g_tls_connection_get_instance_private (conn);
|
|
||||||
|
|
||||||
g_clear_pointer (&priv->negotiated_protocol, g_free);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (g_tls_connection_parent_class)->finalize (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_tls_connection_set_use_system_certdb:
|
* g_tls_connection_set_use_system_certdb:
|
||||||
* @conn: a #GTlsConnection
|
* @conn: a #GTlsConnection
|
||||||
@@ -871,31 +853,15 @@ g_tls_connection_set_advertised_protocols (GTlsConnection *conn,
|
|||||||
const gchar *
|
const gchar *
|
||||||
g_tls_connection_get_negotiated_protocol (GTlsConnection *conn)
|
g_tls_connection_get_negotiated_protocol (GTlsConnection *conn)
|
||||||
{
|
{
|
||||||
GTlsConnectionPrivate *priv;
|
GTlsConnectionClass *class;
|
||||||
gchar *protocol;
|
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL);
|
g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL);
|
||||||
|
|
||||||
g_object_get (G_OBJECT (conn),
|
class = G_TLS_CONNECTION_GET_CLASS (conn);
|
||||||
"negotiated-protocol", &protocol,
|
if (class->get_negotiated_protocol == NULL)
|
||||||
NULL);
|
return NULL;
|
||||||
|
|
||||||
/*
|
return class->get_negotiated_protocol (conn);
|
||||||
* Cache the property internally so we can return a `const` pointer
|
|
||||||
* to the caller.
|
|
||||||
*/
|
|
||||||
priv = g_tls_connection_get_instance_private (conn);
|
|
||||||
if (g_strcmp0 (priv->negotiated_protocol, protocol) != 0)
|
|
||||||
{
|
|
||||||
g_free (priv->negotiated_protocol);
|
|
||||||
priv->negotiated_protocol = protocol;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_free (protocol);
|
|
||||||
}
|
|
||||||
|
|
||||||
return priv->negotiated_protocol;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -73,9 +73,11 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|||||||
GError **error);
|
GError **error);
|
||||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
|
|
||||||
|
const gchar *(*get_negotiated_protocol) (GTlsConnection *conn);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
/* Padding for future expansion */
|
/* Padding for future expansion */
|
||||||
gpointer padding[7];
|
gpointer padding[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
Reference in New Issue
Block a user