aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-service.c
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2001-09-27 22:39:39 +0800
committerDan Winship <danw@src.gnome.org>2001-09-27 22:39:39 +0800
commit5120d7098b94b95a75993be8faa3377507a50b45 (patch)
treec3f8f8a9e1e8049feb869b2084db6d032133b2c6 /camel/camel-service.c
parentf967421b532778246b6b68226c9eb42ad1eaa5d1 (diff)
downloadgsoc2013-evolution-5120d7098b94b95a75993be8faa3377507a50b45.tar
gsoc2013-evolution-5120d7098b94b95a75993be8faa3377507a50b45.tar.gz
gsoc2013-evolution-5120d7098b94b95a75993be8faa3377507a50b45.tar.bz2
gsoc2013-evolution-5120d7098b94b95a75993be8faa3377507a50b45.tar.lz
gsoc2013-evolution-5120d7098b94b95a75993be8faa3377507a50b45.tar.xz
gsoc2013-evolution-5120d7098b94b95a75993be8faa3377507a50b45.tar.zst
gsoc2013-evolution-5120d7098b94b95a75993be8faa3377507a50b45.zip
Change "gboolean connected" to "CamelServiceConnectionStatus status",
* camel-service.c: Change "gboolean connected" to "CamelServiceConnectionStatus status", which can be disconnected, connecting, connected, or disconnecting. (camel_service_init, camel_service_finalize): create/destroy the connect_op_lock. Refer to service->status rather than service->connected. (camel_service_connect): When connecting, note the current operation (and create a new one if there's none registered) and mark the connection "connecting" until we succeed or fail. (camel_service_disconnect): Likewise in reverse. (camel_service_cancel_connect): New function to cancel a connection attempt. (cancel_connect): Default implementation: Call camel_operation_cancel on the connect_op. * camel-disco-store.c (disco_connect): Only call CamelRemoteStore's connect func if we're online. (disco_cancel_connect): Fall back to offline if a connection gets cancelled. (disco_get_folder_info): Kludge: call connect explicitly before deciding whether to do the online or offline version, so if the connect fails, we fall back correctly. * camel-session.c (camel_session_get_service_connected): s/svc->connected/svc->status/ * camel-remote-store.c (camel_remote_store_finalise): Change service->connected check to service->status check. (remote_connect): Don't set service->connected here: camel_service_connect() itself does that. * camel-operation.c (camel_operation_registered): Deal with the possibility that there's no registered op. svn path=/trunk/; revision=13191
Diffstat (limited to 'camel/camel-service.c')
-rw-r--r--camel/camel-service.c82
1 files changed, 67 insertions, 15 deletions
diff --git a/camel/camel-service.c b/camel/camel-service.c
index 27d6a5bbee..cc254e1f2d 100644
--- a/camel/camel-service.c
+++ b/camel/camel-service.c
@@ -59,7 +59,7 @@ static void construct (CamelService *service, CamelSession *session,
static gboolean service_connect(CamelService *service, CamelException *ex);
static gboolean service_disconnect(CamelService *service, gboolean clean,
CamelException *ex);
-/*static gboolean is_connected (CamelService *service);*/
+static void cancel_connect (CamelService *service);
static GList * query_auth_types (CamelService *service, CamelException *ex);
static char * get_name (CamelService *service, gboolean brief);
static char * get_path (CamelService *service);
@@ -74,6 +74,7 @@ camel_service_class_init (CamelServiceClass *camel_service_class)
camel_service_class->construct = construct;
camel_service_class->connect = service_connect;
camel_service_class->disconnect = service_disconnect;
+ camel_service_class->cancel_connect = cancel_connect;
camel_service_class->query_auth_types = query_auth_types;
camel_service_class->get_name = get_name;
camel_service_class->get_path = get_path;
@@ -87,6 +88,7 @@ camel_service_init (void *o, void *k)
service->priv = g_malloc0(sizeof(*service->priv));
#ifdef ENABLE_THREADS
service->priv->connect_lock = e_mutex_new(E_MUTEX_REC);
+ service->priv->connect_op_lock = e_mutex_new(E_MUTEX_SIMPLE);
#endif
}
@@ -95,7 +97,7 @@ camel_service_finalize (CamelObject *object)
{
CamelService *service = CAMEL_SERVICE (object);
- if (service->connected) {
+ if (service->status == CAMEL_SERVICE_CONNECTED) {
CamelException ex;
camel_exception_init (&ex);
@@ -114,6 +116,7 @@ camel_service_finalize (CamelObject *object)
#ifdef ENABLE_THREADS
e_mutex_destroy (service->priv->connect_lock);
+ e_mutex_destroy (service->priv->connect_op_lock);
#endif
g_free (service->priv);
}
@@ -178,7 +181,7 @@ construct (CamelService *service, CamelSession *session,
service->session = session;
camel_object_ref (CAMEL_OBJECT (session));
- service->connected = FALSE;
+ service->status = CAMEL_SERVICE_DISCONNECTED;
}
/**
@@ -234,17 +237,30 @@ camel_service_connect (CamelService *service, CamelException *ex)
CAMEL_SERVICE_LOCK (service, connect_lock);
- if (service->connected) {
- /* But we're still connected, so no exception
- * and return true.
- */
- g_warning ("camel_service_connect: trying to connect to an already connected service");
- ret = TRUE;
- } else if (CSERV_CLASS (service)->connect (service, ex)) {
- service->connected = TRUE;
- ret = TRUE;
+ if (service->status == CAMEL_SERVICE_CONNECTED) {
+ CAMEL_SERVICE_UNLOCK (service, connect_lock);
+ return TRUE;
}
-
+
+ /* Register a separate operation for connecting, so that
+ * the offline code can cancel it.
+ */
+ CAMEL_SERVICE_LOCK (service, connect_op_lock);
+ service->connect_op = camel_operation_registered ();
+ if (!service->connect_op)
+ service->connect_op = camel_operation_new (NULL, NULL);
+ camel_operation_register (service->connect_op);
+ CAMEL_SERVICE_UNLOCK (service, connect_op_lock);
+
+ service->status = CAMEL_SERVICE_CONNECTING;
+ ret = CSERV_CLASS (service)->connect (service, ex);
+ service->status = ret ? CAMEL_SERVICE_CONNECTED : CAMEL_SERVICE_DISCONNECTED;
+
+ CAMEL_SERVICE_LOCK (service, connect_op_lock);
+ camel_operation_unref (service->connect_op);
+ service->connect_op = NULL;
+ CAMEL_SERVICE_UNLOCK (service, connect_op_lock);
+
CAMEL_SERVICE_UNLOCK (service, connect_lock);
return ret;
@@ -282,9 +298,22 @@ camel_service_disconnect (CamelService *service, gboolean clean,
CAMEL_SERVICE_LOCK (service, connect_lock);
- if (service->connected) {
+ if (service->status == CAMEL_SERVICE_CONNECTED) {
+ CAMEL_SERVICE_LOCK (service, connect_op_lock);
+ service->connect_op = camel_operation_registered ();
+ if (!service->connect_op)
+ service->connect_op = camel_operation_new (NULL, NULL);
+ camel_operation_register (service->connect_op);
+ CAMEL_SERVICE_UNLOCK (service, connect_op_lock);
+
+ service->status = CAMEL_SERVICE_DISCONNECTING;
res = CSERV_CLASS (service)->disconnect (service, clean, ex);
- service->connected = FALSE;
+ service->status = CAMEL_SERVICE_DISCONNECTED;
+
+ CAMEL_SERVICE_LOCK (service, connect_op_lock);
+ camel_operation_unref (service->connect_op);
+ service->connect_op = NULL;
+ CAMEL_SERVICE_UNLOCK (service, connect_op_lock);
}
CAMEL_SERVICE_UNLOCK (service, connect_lock);
@@ -292,6 +321,29 @@ camel_service_disconnect (CamelService *service, gboolean clean,
return res;
}
+static void
+cancel_connect (CamelService *service)
+{
+ camel_operation_cancel (service->connect_op);
+}
+
+/**
+ * camel_service_cancel_connect:
+ * @service: a service
+ *
+ * If @service is currently attempting to connect to or disconnect
+ * from a server, this causes it to stop and fail. Otherwise it is a
+ * no-op.
+ **/
+void
+camel_service_cancel_connect (CamelService *service)
+{
+ CAMEL_SERVICE_LOCK (service, connect_op_lock);
+ if (service->connect_op)
+ CSERV_CLASS (service)->cancel_connect (service);
+ CAMEL_SERVICE_UNLOCK (service, connect_op_lock);
+}
+
/**
* camel_service_get_url:
* @service: a service