summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2016-01-26 17:11:56 +0100
committerMilan Crha <mcrha@redhat.com>2016-01-26 17:14:19 +0100
commit7d80090be6028c1be6882ba41acade0b8e09d013 (patch)
tree5f36d8e1f57f352e1184a0c5eaca56ac73c4ba56
parent16736b1d6fb10e1862f8f32f726696efd8a41a03 (diff)
downloadevolution-data-server-7d80090be6028c1be6882ba41acade0b8e09d013.tar.gz
Bug 748996 - GNetworkAddress is not thread safe
Do not cache default connectable, rather always create it, because the object might not be thread safe.
-rw-r--r--camel/camel-network-service.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/camel/camel-network-service.c b/camel/camel-network-service.c
index 9df4265d3..c9e8202ce 100644
--- a/camel/camel-network-service.c
+++ b/camel/camel-network-service.c
@@ -730,10 +730,21 @@ camel_network_service_ref_connectable (CamelNetworkService *service)
g_mutex_lock (&priv->property_lock);
- if (priv->connectable != NULL)
+ if (priv->connectable != NULL) {
connectable = g_object_ref (priv->connectable);
+ g_mutex_unlock (&priv->property_lock);
+ } else {
+ CamelNetworkServiceInterface *iface;
- g_mutex_unlock (&priv->property_lock);
+ g_mutex_unlock (&priv->property_lock);
+
+ iface = CAMEL_NETWORK_SERVICE_GET_INTERFACE (service);
+ g_return_val_if_fail (iface->new_connectable != NULL, NULL);
+
+ /* This may return NULL if we don't have valid network
+ * settings from which to create a GSocketConnectable. */
+ connectable = iface->new_connectable (service);
+ }
return connectable;
}
@@ -753,24 +764,21 @@ void
camel_network_service_set_connectable (CamelNetworkService *service,
GSocketConnectable *connectable)
{
- CamelNetworkServiceInterface *iface;
CamelNetworkServicePrivate *priv;
g_return_if_fail (CAMEL_IS_NETWORK_SERVICE (service));
- iface = CAMEL_NETWORK_SERVICE_GET_INTERFACE (service);
- g_return_if_fail (iface->new_connectable != NULL);
-
priv = CAMEL_NETWORK_SERVICE_GET_PRIVATE (service);
g_return_if_fail (priv != NULL);
+ /* The GNetworkAddress is not thread safe, thus rather than precache it,
+ create a new instance whenever it's asked for it. Keep precached only
+ the connectable which had been explicitly set, because there cannot be
+ done exact copy of it.
+ */
if (connectable != NULL) {
g_return_if_fail (G_IS_SOCKET_CONNECTABLE (connectable));
g_object_ref (connectable);
- } else {
- /* This may return NULL if we don't have valid network
- * settings from which to create a GSocketConnectable. */
- connectable = iface->new_connectable (service);
}
g_mutex_lock (&priv->property_lock);