From: Matthew Barnes Date: Thu, 21 Feb 2013 17:26:09 +0000 (-0500) Subject: CamelNetworkService: Add a "connectable" property (GSocketConnectable). X-Git-Tag: upstream/3.7.91~107 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6c4ad7faf40100f259c88dcbe7bb01fa1a05317e;p=platform%2Fupstream%2Fevolution-data-server.git CamelNetworkService: Add a "connectable" property (GSocketConnectable). This is the socket endpoint for the network service to which the CamelNetworkService is a client. This also adds a new_connectable() method to the interface, which by default creates a new GNetworkAddress from the CamelNetworkSettings. New functions: camel_network_service_ref_connectable() camel_network_service_set_connectable() --- diff --git a/camel/camel-network-service.c b/camel/camel-network-service.c index df4e326..282a38e 100644 --- a/camel/camel-network-service.c +++ b/camel/camel-network-service.c @@ -37,7 +37,8 @@ typedef struct _CamelNetworkServicePrivate CamelNetworkServicePrivate; struct _CamelNetworkServicePrivate { - gint placeholder; + GMutex property_lock; + GSocketConnectable *connectable; }; /* Forward Declarations */ @@ -51,12 +52,22 @@ G_DEFINE_INTERFACE ( static CamelNetworkServicePrivate * network_service_private_new (CamelNetworkService *service) { - return g_slice_new0 (CamelNetworkServicePrivate); + CamelNetworkServicePrivate *priv; + + priv = g_slice_new0 (CamelNetworkServicePrivate); + + g_mutex_init (&priv->property_lock); + + return priv; } static void network_service_private_free (CamelNetworkServicePrivate *priv) { + g_clear_object (&priv->connectable); + + g_mutex_clear (&priv->property_lock); + g_slice_free (CamelNetworkServicePrivate, priv); } @@ -150,10 +161,50 @@ network_service_connect_sync (CamelNetworkService *service, return stream; } +static GSocketConnectable * +network_service_new_connectable (CamelNetworkService *service) +{ + GSocketConnectable *connectable = NULL; + CamelNetworkSettings *network_settings; + CamelSettings *settings; + guint16 port; + gchar *host; + + /* Some services might want to override this method to + * create a GNetworkService instead of a GNetworkAddress. */ + + settings = camel_service_ref_settings (CAMEL_SERVICE (service)); + g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL); + + network_settings = CAMEL_NETWORK_SETTINGS (settings); + host = camel_network_settings_dup_host (network_settings); + port = camel_network_settings_get_port (network_settings); + + if (host != NULL) + connectable = g_network_address_new (host, port); + + g_free (host); + + g_object_unref (settings); + + return connectable; +} + static void camel_network_service_default_init (CamelNetworkServiceInterface *interface) { interface->connect_sync = network_service_connect_sync; + interface->new_connectable = network_service_new_connectable; + + g_object_interface_install_property ( + interface, + g_param_spec_object ( + "connectable", + "Connectable", + "Socket endpoint of a network service", + G_TYPE_SOCKET_CONNECTABLE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } void @@ -233,6 +284,88 @@ camel_network_service_get_default_port (CamelNetworkService *service, } /** + * camel_network_service_ref_connectable: + * @service: a #CamelNetworkService + * + * Returns the socket endpoint for the network service to which @service + * is a client. + * + * The returned #GSocketConnectable is referenced for thread-safety and + * must be unreferenced with g_object_unref() when finished with it. + * + * Returns: a #GSocketConnectable + * + * Since: 3.8 + **/ +GSocketConnectable * +camel_network_service_ref_connectable (CamelNetworkService *service) +{ + CamelNetworkServicePrivate *priv; + GSocketConnectable *connectable = NULL; + + g_return_val_if_fail (CAMEL_IS_NETWORK_SERVICE (service), NULL); + + priv = CAMEL_NETWORK_SERVICE_GET_PRIVATE (service); + g_return_val_if_fail (priv != NULL, NULL); + + g_mutex_lock (&priv->property_lock); + + if (priv->connectable != NULL) + connectable = g_object_ref (priv->connectable); + + g_mutex_unlock (&priv->property_lock); + + return connectable; +} + +/** + * camel_network_service_set_connectable: + * @service: a #CamelNetworkService + * @connectable: a #GSocketConnectable, or %NULL + * + * Sets the socket endpoint for the network service to which @service is + * a client. If @connectable is %NULL, a #GSocketConnectable is derived + * from the @service's #CamelNetworkSettings. + * + * Since: 3.8 + **/ +void +camel_network_service_set_connectable (CamelNetworkService *service, + GSocketConnectable *connectable) +{ + CamelNetworkServiceInterface *interface; + CamelNetworkServicePrivate *priv; + + g_return_if_fail (CAMEL_IS_NETWORK_SERVICE (service)); + + interface = CAMEL_NETWORK_SERVICE_GET_INTERFACE (service); + g_return_if_fail (interface->new_connectable != NULL); + + priv = CAMEL_NETWORK_SERVICE_GET_PRIVATE (service); + g_return_if_fail (priv != NULL); + + 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 = interface->new_connectable (service); + } + + g_mutex_lock (&priv->property_lock); + + if (priv->connectable != NULL) + g_object_unref (priv->connectable); + + priv->connectable = connectable; + + g_mutex_unlock (&priv->property_lock); + + g_object_notify (G_OBJECT (service), "connectable"); +} + +/** * camel_network_service_connect_sync: * @service: a #CamelNetworkService * @cancellable: optional #GCancellable object, or %NULL diff --git a/camel/camel-network-service.h b/camel/camel-network-service.h index f816250..75f388b 100644 --- a/camel/camel-network-service.h +++ b/camel/camel-network-service.h @@ -70,7 +70,11 @@ struct _CamelNetworkServiceInterface { GCancellable *cancellable, GError **error); - gpointer reserved[16]; + GSocketConnectable * + (*new_connectable) + (CamelNetworkService *service); + + gpointer reserved[15]; }; GType camel_network_service_get_type (void) G_GNUC_CONST; @@ -80,6 +84,12 @@ const gchar * camel_network_service_get_service_name guint16 camel_network_service_get_default_port (CamelNetworkService *service, CamelNetworkSecurityMethod method); +GSocketConnectable * + camel_network_service_ref_connectable + (CamelNetworkService *service); +void camel_network_service_set_connectable + (CamelNetworkService *service, + GSocketConnectable *connectable); CamelStream * camel_network_service_connect_sync (CamelNetworkService *service, GCancellable *cancellable, diff --git a/camel/camel-service.c b/camel/camel-service.c index c34c07c..ad4cfb8 100644 --- a/camel/camel-service.c +++ b/camel/camel-service.c @@ -72,6 +72,8 @@ struct _CamelServicePrivate { GMutex connection_lock; ConnectionOp *connection_op; CamelServiceConnectionStatus status; + + gboolean network_service_inited; }; /* This is copied from EAsyncClosure in libedataserver. @@ -708,8 +710,10 @@ service_constructed (GObject *object) g_object_unref (session); /* The CamelNetworkService interface needs initialization. */ - if (CAMEL_IS_NETWORK_SERVICE (service)) + if (CAMEL_IS_NETWORK_SERVICE (service)) { camel_network_service_init (CAMEL_NETWORK_SERVICE (service)); + service->priv->network_service_inited = TRUE; + } } static gchar * @@ -1577,6 +1581,12 @@ camel_service_set_settings (CamelService *service, g_mutex_unlock (&service->priv->settings_lock); + /* If the service is a CamelNetworkService, it needs to + * replace its GSocketConnectable for the new settings. */ + if (service->priv->network_service_inited) + camel_network_service_set_connectable ( + CAMEL_NETWORK_SERVICE (service), NULL); + g_object_notify (G_OBJECT (service), "settings"); } diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt index 2253f39..af93f2d 100644 --- a/docs/reference/camel/camel-sections.txt +++ b/docs/reference/camel/camel-sections.txt @@ -1802,8 +1802,10 @@ camel_multipart_get_type camel-network-service CamelNetworkService CamelNetworkService -camel_network_service_get_default_port camel_network_service_get_service_name +camel_network_service_get_default_port +camel_network_service_ref_connectable +camel_network_service_set_connectable camel_network_service_connect_sync CAMEL_NETWORK_SERVICE