[evolution-data-server] Recast CamelOperation as a GCancellable subclass.



commit b79c2433782e07bba3024d10779f36e28b8070ff
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Sep 14 23:04:18 2010 -0400

    Recast CamelOperation as a GCancellable subclass.
    
    CamelOperation is now a subclass of GCancellable.  Instead of taking a
    status update callback at creation time, it now emits a "status" signal
    from an idle callback.
    
    Several functions have been modified or removed:
    
       camel_operation_new()         No longer takes any arguments.
       camel_operation_unregister()  No longer takes any arguments
                                     (and never used it when it did).
    
       camel_operation_ref()         Gone. Use g_object_ref() instead.
       camel_operation_unref()       Gone. Use g_object_unref() instead.
       camel_operation_mute()        Gone. Disconnect your signal handler.

 camel/camel-marshal.list                           |    1 +
 camel/camel-operation.c                            |  748 +++++++++-----------
 camel/camel-operation.h                            |   88 ++-
 camel/camel-service.c                              |   12 +-
 camel/camel-session.c                              |   10 +-
 camel/providers/imapx/camel-imapx-server.c         |   12 +-
 configure.ac                                       |    2 +-
 docs/reference/camel/camel-sections.txt            |    5 -
 .../reference/camel/tmpl/camel-cipher-context.sgml |    4 +
 docs/reference/camel/tmpl/camel-operation.sgml     |   66 +--
 docs/reference/camel/tmpl/camel-unused.sgml        |   39 +
 11 files changed, 483 insertions(+), 504 deletions(-)
---
diff --git a/camel/camel-marshal.list b/camel/camel-marshal.list
index b02c3c0..daee534 100644
--- a/camel/camel-marshal.list
+++ b/camel/camel-marshal.list
@@ -1 +1,2 @@
+NONE:STRING,INT
 NONE:STRING,POINTER
diff --git a/camel/camel-operation.c b/camel/camel-operation.c
index 8a5738a..028ee29 100644
--- a/camel/camel-operation.c
+++ b/camel/camel-operation.c
@@ -1,28 +1,23 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- *  Authors: Michael Zucchi <NotZed ximian com>
+ * camel-operation.c
  *
- *  Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
  *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
 
 #include <stdio.h>
 #include <unistd.h>
@@ -32,96 +27,218 @@
 #include <nspr.h>
 #endif
 
-#include "camel-list-utils.h"
-#include "camel-operation.h"
+#include "camel-marshal.h"
 #include "camel-msgport.h"
+#include "camel-operation.h"
 
-#define d(x)
+#define CAMEL_OPERATION_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), CAMEL_TYPE_OPERATION, CamelOperationPrivate))
 
-/* ********************************************************************** */
+typedef struct _StatusNode StatusNode;
 
-struct _status_stack {
-	guint32 flags;
+struct _StatusNode {
+	gboolean transient;
 	gchar *msg;
-	gint pc;				/* last pc reported */
-	guint stamp;		/* last stamp reported */
+	gint pc;		/* last percentage reported */
+	guint stamp;		/* last time stamp reported */
 };
 
-struct _CamelOperation {
-	struct _CamelOperation *next;
-	struct _CamelOperation *prev;
+struct _CamelOperationPrivate {
+	guint status_idle_id;
 
-	GThread *thread;	/* running thread */
-	guint32 flags;		/* cancelled ? */
-	gint blocked;		/* cancellation blocked depth */
-	gint refcount;
+	/* For the next 'status' signal. */
+	gchar *status_msg;
+	gint status_pc;
 
-	CamelOperationStatusFunc status;
-	gpointer status_data;
 	guint status_update;
 
-	/* stack of status messages (struct _status_stack *) */
-	GSList *status_stack;
-	struct _status_stack *lastreport;
+	GQueue status_stack;
 
 	CamelMsgPort *cancel_port;
-	gint cancel_fd;
 #ifdef CAMEL_HAVE_NSS
 	PRFileDesc *cancel_prfd;
 #endif
 };
 
-#define CAMEL_OPERATION_CANCELLED (1<<0)
-#define CAMEL_OPERATION_TRANSIENT (1<<1)
+enum {
+	STATUS,
+	LAST_SIGNAL
+};
 
 /* Delay before a transient operation has any effect on the status */
 #define CAMEL_OPERATION_TRANSIENT_DELAY (5)
 
-static GStaticMutex operation_lock = G_STATIC_MUTEX_INIT;
-#define LOCK() g_static_mutex_lock(&operation_lock)
-#define UNLOCK() g_static_mutex_unlock(&operation_lock)
+static GStaticRecMutex operation_lock = G_STATIC_REC_MUTEX_INIT;
+#define LOCK() g_static_rec_mutex_lock (&operation_lock)
+#define UNLOCK() g_static_rec_mutex_unlock (&operation_lock)
 
-static guint stamp (void);
-static CamelDList operation_list = CAMEL_DLIST_INITIALISER (operation_list);
+static GQueue operation_list = G_QUEUE_INIT;
 static GStaticPrivate operation_key = G_STATIC_PRIVATE_INIT;
 
-typedef struct _CamelOperationMsg {
-	CamelMsg msg;
-} CamelOperationMsg;
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (CamelOperation, camel_operation, G_TYPE_CANCELLABLE)
+
+static StatusNode *
+status_node_new (CamelOperation *operation)
+{
+	StatusNode *node;
+
+	node = g_slice_new0 (StatusNode);
+	g_queue_push_head (&operation->priv->status_stack, node);
+
+	return node;
+}
+
+static void
+status_node_free (StatusNode *node)
+{
+	g_free (node->msg);
+	g_slice_free (StatusNode, node);
+}
 
 static CamelOperation *
 co_getcc (void)
 {
-	return (CamelOperation *)g_static_private_get (&operation_key);
+	return (CamelOperation *) g_static_private_get (&operation_key);
+}
+
+static guint
+stamp (void)
+{
+	GTimeVal tv;
+
+	g_get_current_time (&tv);
+	/* update 4 times/second */
+	return (tv.tv_sec * 4) + tv.tv_usec / (1000000/4);
+}
+
+static gboolean
+operation_idle_cb (CamelOperation *operation)
+{
+	gchar *msg;
+	gint pc;
+
+	LOCK ();
+
+	msg = operation->priv->status_msg;
+	operation->priv->status_msg = NULL;
+
+	pc = operation->priv->status_pc;
+
+	operation->priv->status_idle_id = 0;
+
+	UNLOCK ();
+
+	if (msg != NULL) {
+		g_signal_emit (operation, signals[STATUS], 0, msg, pc);
+		g_free (msg);
+	}
+
+	return FALSE;
 }
 
 static void
-clear_status_stack (CamelOperation *cc, gboolean claim_not_empty)
+operation_queue_status_update (CamelOperation *operation,
+                               StatusNode *node)
 {
-	g_return_if_fail (cc != NULL);
+	LOCK ();
+
+	if (operation->priv->status_idle_id == 0)
+		operation->priv->status_idle_id = g_idle_add (
+			(GSourceFunc) operation_idle_cb, operation);
 
-	if (claim_not_empty && cc->status_stack != NULL)
-		g_debug ("%p CamelOperation status stack non-empty", cc);
+	g_free (operation->priv->status_msg);
+	operation->priv->status_msg = g_strdup (node->msg);
 
-	while (cc->status_stack != NULL) {
-		struct _status_stack *status;
+	operation->priv->status_pc = node->pc;
 
-		status = cc->status_stack->data;
-		if (claim_not_empty && status->msg != NULL)
-			g_debug ("%p    Status was \"%s\"", cc, status->msg);
-		g_free (status->msg);
-		g_free (status);
+	UNLOCK ();
+}
+
+static void
+operation_flush_msgport (CamelOperation *operation)
+{
+	CamelOperationPrivate *priv = operation->priv;
+	CamelMsg *msg;
 
-		cc->status_stack = g_slist_delete_link (
-			cc->status_stack, cc->status_stack);
+	LOCK ();
+
+	while ((msg = camel_msgport_try_pop (priv->cancel_port)) != NULL)
+		g_free (msg);
+
+	UNLOCK ();
+}
+
+static void
+operation_finalize (GObject *object)
+{
+	CamelOperationPrivate *priv;
+	StatusNode *node;
+
+	priv = CAMEL_OPERATION_GET_PRIVATE (object);
+
+	LOCK ();
+
+	g_queue_remove (&operation_list, object);
+
+	if (priv->status_idle_id > 0)
+		g_source_remove (priv->status_idle_id);
+
+	operation_flush_msgport (CAMEL_OPERATION (object));
+	camel_msgport_destroy (priv->cancel_port);
+
+	while ((node = g_queue_pop_head (&priv->status_stack)) != NULL) {
+		g_warning (
+			"CamelOperation status stack non-empty: %s",
+			node->msg);
+		status_node_free (node);
 	}
+
+	UNLOCK ();
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (camel_operation_parent_class)->finalize (object);
+}
+
+static void
+camel_operation_class_init (CamelOperationClass *class)
+{
+	GObjectClass *object_class;
+
+	g_type_class_add_private (class, sizeof (CamelOperationPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->finalize = operation_finalize;
+
+	signals[STATUS] = g_signal_new (
+		"status",
+		G_TYPE_FROM_CLASS (class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET (CamelOperationClass, status),
+		NULL, NULL,
+		camel_marshal_VOID__STRING_INT,
+		G_TYPE_NONE, 2,
+		G_TYPE_STRING,
+		G_TYPE_INT);
+}
+
+static void
+camel_operation_init (CamelOperation *operation)
+{
+	operation->priv = CAMEL_OPERATION_GET_PRIVATE (operation);
+
+	g_queue_init (&operation->priv->status_stack);
+	operation->priv->cancel_port = camel_msgport_new ();
+
+	LOCK ();
+	g_queue_push_tail (&operation_list, operation);
+	UNLOCK ();
 }
 
 /**
  * camel_operation_new:
- * @status: Callback for receiving status messages.  This will always
- * be called with an internal lock held.
- * @status_data: User data.
  *
  * Create a new camel operation handle.  Camel operation handles can
  * be used in a multithreaded application (or a single operation
@@ -132,42 +249,9 @@ clear_status_stack (CamelOperation *cc, gboolean claim_not_empty)
  * Returns: A new operation handle.
  **/
 CamelOperation *
-camel_operation_new (CamelOperationStatusFunc status, gpointer status_data)
-{
-	CamelOperation *cc;
-
-	cc = g_malloc0 (sizeof (*cc));
-
-	cc->flags = 0;
-	cc->blocked = 0;
-	cc->refcount = 1;
-	cc->status = status;
-	cc->status_data = status_data;
-	cc->cancel_port = camel_msgport_new ();
-	cc->cancel_fd = -1;
-
-	LOCK ();
-	camel_dlist_addtail (&operation_list, (CamelDListNode *)cc);
-	UNLOCK ();
-
-	return cc;
-}
-
-/**
- * camel_operation_mute:
- * @cc:
- *
- * mutes a camel operation permanently.  from this point on you will never
- * receive operation updates, even if more are sent.
- **/
-void
-camel_operation_mute (CamelOperation *cc)
+camel_operation_new (void)
 {
-	LOCK ();
-	cc->status = NULL;
-	cc->status_data = NULL;
-	clear_status_stack (cc, FALSE);
-	UNLOCK ();
+	return g_object_new (CAMEL_TYPE_OPERATION, NULL);
 }
 
 /**
@@ -178,102 +262,63 @@ camel_operation_mute (CamelOperation *cc)
 CamelOperation *
 camel_operation_registered (void)
 {
-	CamelOperation *cc = co_getcc ();
+	CamelOperation *operation = co_getcc ();
 
-	if (cc)
-		camel_operation_ref (cc);
+	if (operation != NULL)
+		g_object_ref (operation);
 
-	return cc;
+	return operation;
 }
 
 /**
- * camel_operation_ref:
- * @cc: operation context
+ * camel_operation_cancel:
+ * @operation: a #CamelOperation
  *
- * Add a reference to the CamelOperation @cc.
+ * Cancel a given operation.  If @operation is %NULL then all outstanding
+ * operations are cancelled.
  **/
 void
-camel_operation_ref (CamelOperation *cc)
+camel_operation_cancel (CamelOperation *operation)
 {
-	g_assert (cc->refcount > 0);
-
-	LOCK ();
-	cc->refcount++;
-	UNLOCK ();
-}
+	if (operation != NULL) {
+		CamelMsg *msg;
 
-/**
- * camel_operation_unref:
- * @cc: operation context
- *
- * Unref and potentially free @cc.
- **/
-void
-camel_operation_unref (CamelOperation *cc)
-{
-	g_assert (cc->refcount > 0);
+		g_return_if_fail (CAMEL_IS_OPERATION (operation));
 
-	LOCK ();
-	if (cc->refcount == 1) {
-		CamelOperationMsg *msg;
+		LOCK ();
 
-		camel_dlist_remove ((CamelDListNode *)cc);
+		msg = g_malloc0 (sizeof (CamelMsg));
+		camel_msgport_push (operation->priv->cancel_port, msg);
 
-		while ((msg = (CamelOperationMsg *)camel_msgport_try_pop (cc->cancel_port)))
-			g_free (msg);
+		UNLOCK ();
 
-		camel_msgport_destroy (cc->cancel_port);
+		g_cancellable_cancel (G_CANCELLABLE (operation));
 
-		clear_status_stack (cc, TRUE);
-		g_free (cc);
 	} else {
-		cc->refcount--;
-	}
-	UNLOCK ();
-}
+		GList *link;
 
-/**
- * camel_operation_cancel:
- * @cc: operation context
- *
- * Cancel a given operation.  If @cc is NULL then all outstanding
- * operations are cancelled.
- **/
-void
-camel_operation_cancel (CamelOperation *cc)
-{
-	CamelOperationMsg *msg;
+		LOCK ();
 
-	LOCK ();
+		link = g_queue_peek_head_link (&operation_list);
+
+		while (link != NULL) {
+			operation = link->data;
+
+			if (operation != NULL)
+				camel_operation_cancel (operation);
 
-	if (cc == NULL) {
-		CamelOperation *cn;
-
-		cc = (CamelOperation *)operation_list.head;
-		cn = cc->next;
-		while (cn) {
-			cc->flags |= CAMEL_OPERATION_CANCELLED;
-			msg = g_malloc0 (sizeof (*msg));
-			camel_msgport_push (cc->cancel_port, (CamelMsg *)msg);
-			cc = cn;
-			cn = cn->next;
+			link = g_list_next (link);
 		}
-	} else if ((cc->flags & CAMEL_OPERATION_CANCELLED) == 0) {
-		d(printf("cancelling thread %d\n", cc->id));
 
-		cc->flags |= CAMEL_OPERATION_CANCELLED;
-		msg = g_malloc0 (sizeof (*msg));
-		camel_msgport_push (cc->cancel_port, (CamelMsg *)msg);
+		UNLOCK ();
 	}
-
-	UNLOCK ();
 }
 
 /**
  * camel_operation_uncancel:
- * @cc: operation context
+ * @operation: a #CamelOperation
  *
- * Uncancel a cancelled operation.  If @cc is NULL then the current
+ * Uncancel a cancelled operation.  If @operation is %NULL then the current
  * operation is uncancelled.
  *
  * This is useful, if e.g. you need to do some cleaning up where a
@@ -281,96 +326,78 @@ camel_operation_cancel (CamelOperation *cc)
  * processing.
  **/
 void
-camel_operation_uncancel (CamelOperation *cc)
+camel_operation_uncancel (CamelOperation *operation)
 {
-	if (cc == NULL)
-		cc = co_getcc ();
-
-	if (cc) {
-		CamelOperationMsg *msg;
-
-		LOCK ();
-		while ((msg = (CamelOperationMsg *)camel_msgport_try_pop (cc->cancel_port)))
-			g_free (msg);
+	if (operation == NULL)
+		operation = co_getcc ();
 
-		cc->flags &= ~CAMEL_OPERATION_CANCELLED;
-		UNLOCK ();
+	if (operation != NULL) {
+		g_return_if_fail (CAMEL_IS_OPERATION (operation));
+		operation_flush_msgport (operation);
+		g_cancellable_reset (G_CANCELLABLE (operation));
 	}
 }
 
 /**
  * camel_operation_register:
- * @cc: operation context
+ * @operation: a #CamelOperation
  *
- * Register a thread or the main thread for cancellation through @cc.
- * If @cc is NULL, then a new cancellation is created for this thread.
+ * Register a thread or the main thread for cancellation through @operation.
+ * If @operation is NULL, then a new cancellation is created for this thread.
  *
- * All calls to operation_register() should save their value and call
- * operation_register again with that, to automatically stack
- * registrations.
+ * All calls to camel_operation_register() should save their value and
+ * call * camel_operation_register() again with that, to automatically
+ * stack * registrations.
  *
  * Returns: the previously registered operatoin.
- *
  **/
 CamelOperation *
-camel_operation_register (CamelOperation *cc)
+camel_operation_register (CamelOperation *operation)
 {
-	CamelOperation *oldcc = co_getcc ();
+	CamelOperation *old_operation = co_getcc ();
 
-	g_static_private_set (&operation_key, cc, NULL);
+	g_static_private_set (&operation_key, operation, NULL);
 
-	return oldcc;
+	return old_operation;
 }
 
 /**
  * camel_operation_unregister:
- * @cc: operation context
  *
  * Unregister the current thread for all cancellations.
  **/
 void
-camel_operation_unregister (CamelOperation *cc)
+camel_operation_unregister (void)
 {
 	g_static_private_set (&operation_key, NULL, NULL);
 }
 
 /**
  * camel_operation_cancel_check:
- * @cc: operation context
+ * @operation: a #CamelOperation
  *
- * Check if cancellation has been applied to @cc.  If @cc is NULL,
- * then the CamelOperation registered for the current thread is used.
+ * Check if cancellation has been applied to @operation.  If @operation is
+ * %NULL, then the #CamelOperation registered for the current thread is used.
  *
- * Returns: TRUE if the operation has been cancelled.
+ * Returns: %TRUE if the operation has been cancelled
  **/
 gboolean
-camel_operation_cancel_check (CamelOperation *cc)
+camel_operation_cancel_check (CamelOperation *operation)
 {
-	CamelOperationMsg *msg;
-	gint cancelled;
+	gboolean cancelled;
 
-	d(printf("checking for cancel in thread %p\n", g_thread_self()));
+	if (operation == NULL)
+		operation = co_getcc ();
 
-	if (cc == NULL)
-		cc = co_getcc ();
+	if (operation == NULL)
+		return FALSE;
 
 	LOCK ();
 
-	if (cc == NULL || cc->blocked > 0) {
-		d(printf("ahah!  cancellation is blocked\n"));
-		cancelled = FALSE;
-	} else if (cc->flags & CAMEL_OPERATION_CANCELLED) {
-		d(printf("previously cancelled\n"));
-		cancelled = TRUE;
-	} else if ((msg = (CamelOperationMsg *)camel_msgport_try_pop (cc->cancel_port))) {
-		d(printf("Got cancellation message\n"));
-		do {
-			g_free (msg);
-		} while ((msg = (CamelOperationMsg *)camel_msgport_try_pop (cc->cancel_port)));
-		cc->flags |= CAMEL_OPERATION_CANCELLED;
-		cancelled = TRUE;
-	} else
-		cancelled = FALSE;
+	cancelled = g_cancellable_is_cancelled (G_CANCELLABLE (operation));
+
+	if (cancelled)
+		operation_flush_msgport (operation);
 
 	UNLOCK ();
 
@@ -379,67 +406,64 @@ camel_operation_cancel_check (CamelOperation *cc)
 
 /**
  * camel_operation_cancel_fd:
- * @cc: operation context
+ * @operation: a #CamelOperation
  *
  * Retrieve a file descriptor that can be waited on (select, or poll)
  * for read, to asynchronously detect cancellation.
  *
- * Returns: The fd, or -1 if cancellation is not available
- * (blocked, or has not been registered for this thread).
+ * Returns: The fd, or -1 if cancellation has not been registered
+ * for this thread.
  **/
 gint
-camel_operation_cancel_fd (CamelOperation *cc)
+camel_operation_cancel_fd (CamelOperation *operation)
 {
-	if (cc == NULL)
-		cc = co_getcc ();
+	if (operation == NULL)
+		operation = co_getcc ();
 
-	if (cc == NULL || cc->blocked)
+	if (operation == NULL)
 		return -1;
 
-	LOCK ();
-
-	if (cc->cancel_fd == -1)
-		cc->cancel_fd = camel_msgport_fd (cc->cancel_port);
-
-	UNLOCK ();
-
-	return cc->cancel_fd;
+	return g_cancellable_get_fd (G_CANCELLABLE (operation));
 }
 
 #ifdef CAMEL_HAVE_NSS
 /**
  * camel_operation_cancel_prfd:
- * @cc: operation context
+ * @operation: a #CamelOperation
  *
  * Retrieve a file descriptor that can be waited on (select, or poll)
  * for read, to asynchronously detect cancellation.
  *
- * Returns: The fd, or NULL if cancellation is not available
- * (blocked, or has not been registered for this thread).
+ * Returns: The fd, or %NULL if cancellation has not been registered
+ * for this thread.
  **/
 PRFileDesc *
-camel_operation_cancel_prfd (CamelOperation *cc)
+camel_operation_cancel_prfd (CamelOperation *operation)
 {
-	if (cc == NULL)
-		cc = co_getcc ();
+	CamelOperationPrivate *priv;
+
+	if (operation == NULL)
+		operation = co_getcc ();
 
-	if (cc == NULL || cc->blocked)
+	if (operation == NULL)
 		return NULL;
 
 	LOCK ();
 
-	if (cc->cancel_prfd == NULL)
-		cc->cancel_prfd = camel_msgport_prfd (cc->cancel_port);
+	priv = operation->priv;
+
+	if (priv->cancel_prfd == NULL)
+		priv->cancel_prfd = camel_msgport_prfd (priv->cancel_port);
 
 	UNLOCK ();
 
-	return cc->cancel_prfd;
+	return priv->cancel_prfd;
 }
 #endif /* CAMEL_HAVE_NSS */
 
 /**
  * camel_operation_start:
- * @cc: operation context
+ * @operation: a #CamelOperation
  * @what: action being performed (printf-style format string)
  * @Varargs: varargs
  *
@@ -447,51 +471,41 @@ camel_operation_cancel_prfd (CamelOperation *cc)
  * similar end operations.
  **/
 void
-camel_operation_start (CamelOperation *cc, const gchar *what, ...)
+camel_operation_start (CamelOperation *operation,
+                       const gchar *what, ...)
 {
+	const guint signal_id = signals[STATUS];
+	StatusNode *node;
 	va_list ap;
-	gchar *msg;
-	struct _status_stack *s;
-	CamelOperationStatusFunc status_func;
-	gpointer status_data;
 
-	if (cc == NULL)
-		cc = co_getcc ();
+	if (operation == NULL)
+		operation = co_getcc ();
 
-	if (cc == NULL)
+	if (operation == NULL)
+		return;
+
+	if (!g_signal_has_handler_pending (operation, signal_id, 0, TRUE))
 		return;
 
 	LOCK ();
 
-	if (cc->status == NULL) {
-		UNLOCK ();
-		return;
-	}
+	operation->priv->status_update = 0;
 
 	va_start (ap, what);
-	msg = g_strdup_vprintf (what, ap);
-	va_end (ap);
-	cc->status_update = 0;
-	s = g_malloc0 (sizeof (*s));
-	s->msg = msg;
-	s->flags = 0;
-	cc->lastreport = s;
-	cc->status_stack = g_slist_prepend (cc->status_stack, s);
 
-	/* This avoids a race with camel_operation_mute() after we unlock. */
-	status_func = cc->status;
-	status_data = cc->status_data;
+	node = status_node_new (operation);
+	node->msg = g_strdup_vprintf (what, ap);
 
-	UNLOCK ();
+	va_end (ap);
 
-	status_func (cc, msg, CAMEL_OPERATION_START, status_data);
+	operation_queue_status_update (operation, node);
 
-	d(printf("start '%s'\n", msg, pc));
+	UNLOCK ();
 }
 
 /**
  * camel_operation_start_transient:
- * @cc: operation context
+ * @operation: a #CamelOperation
  * @what: printf-style format string describing the action being performed
  * @Varargs: varargs
  *
@@ -500,193 +514,129 @@ camel_operation_start (CamelOperation *cc, const gchar *what, ...)
  * previous state when finished.
  **/
 void
-camel_operation_start_transient (CamelOperation *cc, const gchar *what, ...)
+camel_operation_start_transient (CamelOperation *operation,
+                                 const gchar *what, ...)
 {
-	if (cc == NULL)
-		cc = co_getcc ();
+	StatusNode *node;
+	va_list ap;
+
+	if (operation == NULL)
+		operation = co_getcc ();
 
-	if (cc == NULL)
+	if (operation == NULL)
 		return;
 
 	LOCK ();
 
-	if (cc->status == NULL) {
-		UNLOCK ();
-		return;
-	}
+	operation->priv->status_update = 0;
 
-	cc->status_update = 0;
-	if (cc->status) {
-		va_list ap;
-		gchar *msg;
-		struct _status_stack *s;
-
-		va_start (ap, what);
-		msg = g_strdup_vprintf (what, ap);
-		va_end (ap);
-		s = g_malloc0 (sizeof (*s));
-		s->msg = msg;
-		s->flags = CAMEL_OPERATION_TRANSIENT;
-		s->stamp = stamp ();
-		cc->status_stack = g_slist_prepend (cc->status_stack, s);
-	}
-	d(printf("start '%s'\n", msg, pc));
+	va_start (ap, what);
 
-	UNLOCK ();
-}
+	node = status_node_new (operation);
+	node->msg = g_strdup_vprintf (what, ap);
+	node->stamp = stamp ();
+	node->transient = TRUE;
 
-static guint stamp (void)
-{
-	GTimeVal tv;
+	va_end (ap);
 
-	g_get_current_time (&tv);
-	/* update 4 times/second */
-	return (tv.tv_sec * 4) + tv.tv_usec / (1000000/4);
+	UNLOCK ();
 }
 
 /**
  * camel_operation_progress:
- * @cc: Operation to report to.
+ * @operation: a #CamelOperation
  * @pc: Percent complete, 0 to 100.
  *
- * Report progress on the current operation.  If @cc is NULL, then the
- * currently registered operation is used.  @pc reports the current
+ * Report progress on the current operation.  If @operation is %NULL, then
+ * the currently registered operation is used.  @pc reports the current
  * percentage of completion, which should be in the range of 0 to 100.
  *
  * If the total percentage is not know, then use
  * camel_operation_progress_count().
  **/
 void
-camel_operation_progress (CamelOperation *cc, gint pc)
+camel_operation_progress (CamelOperation *operation,
+                          gint pc)
 {
+	const guint signal_id = signals[STATUS];
+	CamelOperationPrivate *priv;
 	guint now;
-	struct _status_stack *s;
-	gchar *msg = NULL;
-	CamelOperationStatusFunc status_func;
-	gpointer status_data;
+	StatusNode *node;
+
+	if (operation == NULL)
+		operation = co_getcc ();
 
-	if (cc == NULL)
-		cc = co_getcc ();
+	if (operation == NULL)
+		return;
 
-	if (cc == NULL)
+	if (!g_signal_has_handler_pending (operation, signal_id, 0, TRUE))
 		return;
 
 	LOCK ();
 
-	if (cc->status == NULL || cc->status_stack == NULL) {
+	priv = operation->priv;
+
+	if (g_queue_is_empty (&priv->status_stack)) {
 		UNLOCK ();
 		return;
 	}
 
-	s = cc->status_stack->data;
-	s->pc = pc;
+	node = g_queue_peek_head (&priv->status_stack);
+	node->pc = pc;
 
 	/* Transient messages dont start updating till 4 seconds after
 	   they started, then they update every second */
 	now = stamp ();
-	if (cc->status_update == now) {
-		UNLOCK ();
-		return;
-	} else if (s->flags & CAMEL_OPERATION_TRANSIENT) {
-		if (s->stamp + CAMEL_OPERATION_TRANSIENT_DELAY > now) {
-			UNLOCK ();
-			return;
+	if (priv->status_update == now) {
+		operation = NULL;
+	} else if (node->transient) {
+		if (node->stamp + CAMEL_OPERATION_TRANSIENT_DELAY > now) {
+			operation = NULL;
 		} else {
-			cc->status_update = now;
-			cc->lastreport = s;
-			msg = g_strdup (s->msg);
+			priv->status_update = now;
 		}
 	} else {
-		s->stamp = cc->status_update = now;
-		cc->lastreport = s;
-		msg = g_strdup (s->msg);
+		node->stamp = priv->status_update = now;
 	}
 
-	/* This avoids a race with camel_operation_mute() after we unlock. */
-	status_func = cc->status;
-	status_data = cc->status_data;
+	if (operation != NULL)
+		operation_queue_status_update (operation, node);
 
 	UNLOCK ();
-
-	status_func (cc, msg, pc, status_data);
-
-	g_free (msg);
 }
 
 /**
  * camel_operation_end:
- * @cc: operation context
+ * @operation: a #CamelOperation
  *
- * Report the end of an operation.  If @cc is NULL, then the currently
- * registered operation is notified.
+ * Report the end of an operation.  If @operation is %NULL, then the
+ * currently registered operation is notified.
  **/
 void
-camel_operation_end (CamelOperation *cc)
+camel_operation_end (CamelOperation *operation)
 {
-	struct _status_stack *s, *p;
-	guint now;
-	gchar *msg = NULL;
-	gint pc = 0;
-	CamelOperationStatusFunc status_func;
-	gpointer status_data;
+	const guint signal_id = signals[STATUS];
+	GQueue *status_stack;
+	StatusNode *node;
+
+	if (operation == NULL)
+		operation = co_getcc ();
 
-	if (cc == NULL)
-		cc = co_getcc ();
+	if (operation == NULL)
+		return;
 
-	if (cc == NULL)
+	if (!g_signal_has_handler_pending (operation, signal_id, 0, TRUE))
 		return;
 
 	LOCK ();
 
-	if (cc->status == NULL || cc->status_stack == NULL) {
-		UNLOCK ();
-		return;
-	}
+	status_stack = &operation->priv->status_stack;
 
-	/* so what we do here is this.  If the operation that just
-	 * ended was transient, see if we have any other transient
-	 * messages that haven't been updated yet above us, otherwise,
-	 * re-update as a non-transient at the last reported pc */
-	now = stamp ();
-	s = cc->status_stack->data;
-	if (s->flags & CAMEL_OPERATION_TRANSIENT) {
-		if (cc->lastreport == s) {
-			GSList *l = cc->status_stack->next;
-			while (l) {
-				p = l->data;
-				if (p->flags & CAMEL_OPERATION_TRANSIENT) {
-					if (p->stamp + CAMEL_OPERATION_TRANSIENT_DELAY < now) {
-						msg = g_strdup (p->msg);
-						pc = p->pc;
-						cc->lastreport = p;
-						break;
-					}
-				} else {
-					msg = g_strdup (p->msg);
-					pc = p->pc;
-					cc->lastreport = p;
-					break;
-				}
-				l = l->next;
-			}
-		}
-		g_free (s->msg);
-	} else {
-		msg = s->msg;
-		pc = CAMEL_OPERATION_END;
-		cc->lastreport = s;
+	if ((node = g_queue_pop_head (status_stack)) != NULL) {
+		node->pc = 100;
+		operation_queue_status_update (operation, node);
+		status_node_free (node);
 	}
-	g_free (s);
-	cc->status_stack = g_slist_delete_link (cc->status_stack, cc->status_stack);
-
-	/* This avoids a race with camel_operation_mute() after we unlock. */
-	status_func = cc->status;
-	status_data = cc->status_data;
 
 	UNLOCK ();
-
-	if (msg) {
-		status_func (cc, msg, pc, status_data);
-		g_free (msg);
-	}
 }
diff --git a/camel/camel-operation.h b/camel/camel-operation.h
index 3bc080a..ec35a4f 100644
--- a/camel/camel-operation.h
+++ b/camel/camel-operation.h
@@ -1,8 +1,5 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Authors: Michael Zucchi <NotZed Ximian com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+/*
+ * camel-operation.h
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU Lesser General Public
@@ -26,45 +23,78 @@
 #ifndef CAMEL_OPERATION_H
 #define CAMEL_OPERATION_H
 
-#include <glib.h>
+#include <gio/gio.h>
 
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define CAMEL_TYPE_OPERATION \
+	(camel_operation_get_type ())
+#define CAMEL_OPERATION(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), CAMEL_TYPE_OPERATION, CamelOperation))
+#define CAMEL_OPERATION_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), CAMEL_TYPE_OPERATION, CamelOperationClass))
+#define CAMEL_IS_OPERATION(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), CAMEL_TYPE_OPERATION))
+#define CAMEL_IS_OPERATION_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), CAMEL_TYPE_OPERATION))
+#define CAMEL_OPERATION_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), CAMEL_TYPE_OPERATION, CamelOperationClass))
 
-/* cancellation helper stuff, not yet finalized */
+G_BEGIN_DECLS
 
 typedef struct _CamelOperation CamelOperation;
+typedef struct _CamelOperationClass CamelOperationClass;
+typedef struct _CamelOperationPrivate CamelOperationPrivate;
 
-typedef void (*CamelOperationStatusFunc)(struct _CamelOperation *op, const gchar *what, gint pc, gpointer data);
+struct _CamelOperation {
+	GCancellable parent;
+	CamelOperationPrivate *priv;
+};
 
-typedef enum _camel_operation_status_t {
-	CAMEL_OPERATION_START = -1,
-	CAMEL_OPERATION_END = -2
-} camel_operation_status_t;
+struct _CamelOperationClass {
+	GCancellableClass parent_class;
+
+	/* Signals */
+	void		(*status)		(CamelOperation *operation,
+						 const gchar *what,
+						 gint pc);
+};
+
+GType		camel_operation_get_type	(void);
 
 /* main thread functions */
-CamelOperation *camel_operation_new (CamelOperationStatusFunc status, gpointer status_data);
-void camel_operation_mute (CamelOperation *cc);
-void camel_operation_ref (CamelOperation *cc);
-void camel_operation_unref (CamelOperation *cc);
-void camel_operation_cancel (CamelOperation *cc);
-void camel_operation_uncancel (CamelOperation *cc);
+CamelOperation *camel_operation_new		(void);
+void		camel_operation_cancel		(CamelOperation *operation);
+void		camel_operation_uncancel	(CamelOperation *operation);
+
 /* subthread functions */
-CamelOperation *camel_operation_register (CamelOperation *cc);
-void camel_operation_unregister (CamelOperation *cc);
+CamelOperation *camel_operation_register	(CamelOperation *operation);
+void		camel_operation_unregister	(void);
 
 /* called internally by camel, for the current thread */
-gint camel_operation_cancel_check (CamelOperation *cc);
-gint camel_operation_cancel_fd (CamelOperation *cc);
+gboolean	camel_operation_cancel_check	(CamelOperation *operation);
+gint		camel_operation_cancel_fd	(CamelOperation *operation);
 #ifdef CAMEL_HAVE_NSS
-struct PRFileDesc *camel_operation_cancel_prfd (CamelOperation *cc);
+struct PRFileDesc *
+		camel_operation_cancel_prfd	(CamelOperation *operation);
 #endif
+
 /* return the registered operation for this thread, if there is one */
-CamelOperation *camel_operation_registered (void);
+CamelOperation *camel_operation_registered	(void);
 
-void camel_operation_start (CamelOperation *cc, const gchar *what, ...);
-void camel_operation_start_transient (CamelOperation *cc, const gchar *what, ...);
-void camel_operation_progress (CamelOperation *cc, gint pc);
-void camel_operation_end (CamelOperation *cc);
+void		camel_operation_start		(CamelOperation *cc,
+						 const gchar *what,
+						 ...) G_GNUC_PRINTF (2, 3);
+void		camel_operation_start_transient	(CamelOperation *cc,
+						 const gchar *what,
+						 ...) G_GNUC_PRINTF (2, 3);
+void		camel_operation_progress	(CamelOperation *operation,
+						 gint pc);
+void		camel_operation_end		(CamelOperation *operation);
 
 G_END_DECLS
 
diff --git a/camel/camel-service.c b/camel/camel-service.c
index 03d1f2d..b767db5 100644
--- a/camel/camel-service.c
+++ b/camel/camel-service.c
@@ -315,7 +315,7 @@ camel_service_connect (CamelService *service,
 	camel_service_lock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
 	service->connect_op = camel_operation_registered ();
 	if (!service->connect_op) {
-		service->connect_op = camel_operation_new (NULL, NULL);
+		service->connect_op = camel_operation_new ();
 		camel_operation_register (service->connect_op);
 		unreg = TRUE;
 	}
@@ -330,9 +330,9 @@ camel_service_connect (CamelService *service,
 	camel_service_lock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
 	if (connect_op) {
 		if (unreg && service->connect_op)
-			camel_operation_unregister (connect_op);
+			camel_operation_unregister ();
 
-		camel_operation_unref (connect_op);
+		g_object_unref (connect_op);
 		service->connect_op = NULL;
 	}
 	camel_service_unlock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
@@ -374,7 +374,7 @@ camel_service_disconnect (CamelService *service,
 		camel_service_lock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
 		service->connect_op = camel_operation_registered ();
 		if (!service->connect_op) {
-			service->connect_op = camel_operation_new (NULL, NULL);
+			service->connect_op = camel_operation_new ();
 			camel_operation_register (service->connect_op);
 			unreg = TRUE;
 		}
@@ -387,9 +387,9 @@ camel_service_disconnect (CamelService *service,
 
 		camel_service_lock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
 		if (unreg)
-			camel_operation_unregister (service->connect_op);
+			camel_operation_unregister ();
 
-		camel_operation_unref (service->connect_op);
+		g_object_unref (service->connect_op);
 		service->connect_op = NULL;
 		camel_service_unlock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
 	}
diff --git a/camel/camel-session.c b/camel/camel-session.c
index 47f570e..8a08fbe 100644
--- a/camel/camel-session.c
+++ b/camel/camel-session.c
@@ -86,9 +86,8 @@ static void
 cs_thread_status (CamelOperation *op,
                   const gchar *what,
                   gint pc,
-                  gpointer data)
+                  CamelSessionThreadMsg *msg)
 {
-	CamelSessionThreadMsg *msg = data;
 	CamelSessionClass *class;
 
 	class = CAMEL_SESSION_GET_CLASS (msg->session);
@@ -277,7 +276,10 @@ session_thread_msg_new (CamelSession *session,
 	m = g_malloc0 (size);
 	m->ops = ops;
 	m->session = g_object_ref (session);
-	m->op = camel_operation_new (cs_thread_status, m);
+	m->op = camel_operation_new ();
+	g_signal_connect (
+		m->op, "status",
+		G_CALLBACK (cs_thread_status), m);
 	camel_session_lock (session, CAMEL_SESSION_THREAD_LOCK);
 	m->id = session->priv->thread_id++;
 	g_hash_table_insert (session->priv->thread_active, GINT_TO_POINTER (m->id), m);
@@ -304,7 +306,7 @@ session_thread_msg_free (CamelSession *session,
 	if (msg->ops->free)
 		msg->ops->free (session, msg);
 	if (msg->op)
-		camel_operation_unref (msg->op);
+		g_object_unref (msg->op);
 	g_clear_error (&msg->error);
 	g_object_unref (msg->session);
 	g_free (msg);
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 941f500..8ce7111 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -3816,7 +3816,7 @@ exception:
 	camel_folder_change_info_free (ic->job->u.refresh_info.changes);
 
 	if (ic->job->op)
-		camel_operation_unref (ic->job->op);
+		g_object_unref (ic->job->op);
 
 	imapx_job_done (is, ic->job);
 	camel_imapx_command_free (ic);
@@ -4602,7 +4602,7 @@ imapx_parser_thread (gpointer d)
 	CamelOperation *op;
 	GError *local_error = NULL;
 
-	op = camel_operation_new (NULL, NULL);
+	op = camel_operation_new ();
 	op = camel_operation_register (op);
 	is->op = op;
 
@@ -4684,8 +4684,8 @@ imapx_parser_thread (gpointer d)
 	g_clear_error (&local_error);
 
 	if (op) {
-		camel_operation_unregister (op);
-		camel_operation_unref (op);
+		camel_operation_unregister ();
+		g_object_unref (op);
 	}
 	is->op = NULL;
 
@@ -4990,7 +4990,7 @@ camel_imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, const
 
 	stream = imapx_server_get_message (is, folder, op, uid, IMAPX_PRIORITY_GET_MESSAGE, error);
 	if (op)
-		camel_operation_unref (op);
+		g_object_unref (op);
 
 	return stream;
 }
@@ -5170,7 +5170,7 @@ camel_imapx_server_refresh_info (CamelIMAPXServer *is, CamelFolder *folder, GErr
 	camel_folder_change_info_free (job->u.refresh_info.changes);
 
 	if (job->op)
-		camel_operation_unref (job->op);
+		g_object_unref (job->op);
 	g_free (job);
 
 	return success;
diff --git a/configure.ac b/configure.ac
index c7e85f9..3975275 100644
--- a/configure.ac
+++ b/configure.ac
@@ -113,7 +113,7 @@ LIBEGROUPWISE_CURRENT=13
 LIBEGROUPWISE_REVISION=1
 LIBEGROUPWISE_AGE=0
 
-LIBCAMEL_CURRENT=19
+LIBCAMEL_CURRENT=20
 LIBCAMEL_REVISION=0
 LIBCAMEL_AGE=0
 
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index e374972..05afb38 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -2826,12 +2826,7 @@ camel_movemail
 <SECTION>
 <FILE>camel-operation</FILE>
 CamelOperation
-CamelOperationStatusFunc
-camel_operation_status_t
 camel_operation_new
-camel_operation_mute
-camel_operation_ref
-camel_operation_unref
 camel_operation_cancel
 camel_operation_uncancel
 camel_operation_register
diff --git a/docs/reference/camel/tmpl/camel-cipher-context.sgml b/docs/reference/camel/tmpl/camel-cipher-context.sgml
index 1e79cc0..3598217 100644
--- a/docs/reference/camel/tmpl/camel-cipher-context.sgml
+++ b/docs/reference/camel/tmpl/camel-cipher-context.sgml
@@ -474,6 +474,10 @@ CamelCipherContext
 @gpointer cert_data: 
 @gpointer cert_data:
 @gpointer cert_data: 
+ gpointer cert_data:
+ gpointer cert_data: 
+ gpointer cert_data:
+ gpointer cert_data: 
 @gpointer cert_data: 
 
 
diff --git a/docs/reference/camel/tmpl/camel-operation.sgml b/docs/reference/camel/tmpl/camel-operation.sgml
index 642452b..a2fdedc 100644
--- a/docs/reference/camel/tmpl/camel-operation.sgml
+++ b/docs/reference/camel/tmpl/camel-operation.sgml
@@ -25,66 +25,24 @@ camel-operation
 
 </para>
 
-
-<!-- ##### USER_FUNCTION CamelOperationStatusFunc ##### -->
-<para>
-
-</para>
-
- op: 
- what: 
- pc: 
- data: 
-
-
-<!-- ##### ENUM camel_operation_status_t ##### -->
-<para>
-
-</para>
-
- CAMEL_OPERATION_START: 
- CAMEL_OPERATION_END: 
+ parent: 
+ priv: 
 
 <!-- ##### FUNCTION camel_operation_new ##### -->
 <para>
 
 </para>
 
- status: 
- status_data: 
+ void: 
 @Returns: 
 
 
-<!-- ##### FUNCTION camel_operation_mute ##### -->
-<para>
-
-</para>
-
- cc: 
-
-
-<!-- ##### FUNCTION camel_operation_ref ##### -->
-<para>
-
-</para>
-
- cc: 
-
-
-<!-- ##### FUNCTION camel_operation_unref ##### -->
-<para>
-
-</para>
-
- cc: 
-
-
 <!-- ##### FUNCTION camel_operation_cancel ##### -->
 <para>
 
 </para>
 
- cc: 
+ operation: 
 
 
 <!-- ##### FUNCTION camel_operation_uncancel ##### -->
@@ -92,7 +50,7 @@ camel-operation
 
 </para>
 
- cc: 
+ operation: 
 
 
 <!-- ##### FUNCTION camel_operation_register ##### -->
@@ -100,7 +58,7 @@ camel-operation
 
 </para>
 
- cc: 
+ operation: 
 @Returns: 
 
 
@@ -109,7 +67,7 @@ camel-operation
 
 </para>
 
- cc: 
+ void: 
 
 
 <!-- ##### FUNCTION camel_operation_cancel_check ##### -->
@@ -117,7 +75,7 @@ camel-operation
 
 </para>
 
- cc: 
+ operation: 
 @Returns: 
 
 
@@ -126,7 +84,7 @@ camel-operation
 
 </para>
 
- cc: 
+ operation: 
 @Returns: 
 
 
@@ -135,7 +93,7 @@ camel-operation
 
 </para>
 
- cc: 
+ operation: 
 @Returns: 
 
 
@@ -173,7 +131,7 @@ camel-operation
 
 </para>
 
- cc: 
+ operation: 
 @pc: 
 
 
@@ -182,6 +140,6 @@ camel-operation
 
 </para>
 
- cc: 
+ operation: 
 
 
diff --git a/docs/reference/camel/tmpl/camel-unused.sgml b/docs/reference/camel/tmpl/camel-unused.sgml
index edfab65..5f8af4f 100644
--- a/docs/reference/camel/tmpl/camel-unused.sgml
+++ b/docs/reference/camel/tmpl/camel-unused.sgml
@@ -3728,6 +3728,16 @@ streams
 @CAMEL_IMAP_JOURNAL_ENTRY_APPEND: 
 @CAMEL_IMAP_JOURNAL_ENTRY_TRANSFER: 
 
+<!-- ##### USER_FUNCTION CamelOperationStatusFunc ##### -->
+<para>
+
+</para>
+
+ op: 
+ what: 
+ pc: 
+ data: 
+
 <!-- ##### STRUCT CamelPOP3Command ##### -->
 <para>
 
@@ -7286,6 +7296,13 @@ streams
 
 @cc: 
 
+<!-- ##### FUNCTION camel_operation_mute ##### -->
+<para>
+
+</para>
+
+ cc: 
+
 <!-- ##### FUNCTION camel_operation_progress_count ##### -->
 <para>
 
@@ -7294,6 +7311,28 @@ streams
 @cc: 
 @sofar: 
 
+<!-- ##### FUNCTION camel_operation_ref ##### -->
+<para>
+
+</para>
+
+ cc: 
+
+<!-- ##### ENUM camel_operation_status_t ##### -->
+<para>
+
+</para>
+
+ CAMEL_OPERATION_START: 
+ CAMEL_OPERATION_END: 
+
+<!-- ##### FUNCTION camel_operation_unref ##### -->
+<para>
+
+</para>
+
+ cc: 
+
 <!-- ##### FUNCTION camel_partition_table_get_type ##### -->
 <para>
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]