[evolution-data-server] CamelStore: Add a "folder-info-stale" signal.



commit af37b357c0fa539733300fa0fd1c425a445fe1e7
Author: Matthew Barnes <mbarnes redhat com>
Date:   Fri Jun 21 19:12:12 2013 -0400

    CamelStore: Add a "folder-info-stale" signal.
    
    This signal indicates significant changes have occurred to the folder
    hierarchy of the CamelStore, and that previously fetched CamelFolderInfo
    data should be considered stale.
    
    Applications should handle this signal by replacing cached
    CamelFolderInfo data for the CamelStore with fresh data by way of
    camel_store_get_folder_info().
    
    More often than not this signal will be emitted as a result of user
    preference changes rather than actual server-side changes.  For example,
    a user may change a preference that reveals a set of folders previously
    hidden from view, or that alters whether to augment the CamelStore with
    virtual Junk and Trash folders.
    
    This increases sizeof(CamelStoreClass) and its descendants, therefore
    the libcamel shared object name has been bumped.

 camel/camel-store.c                     |   98 +++++++++++++++++++++++++++++++
 camel/camel-store.h                     |    2 +
 configure.ac                            |    2 +-
 docs/reference/camel/camel-sections.txt |    1 +
 4 files changed, 102 insertions(+), 1 deletions(-)
---
diff --git a/camel/camel-store.c b/camel/camel-store.c
index 14224c4..238a9cc 100644
--- a/camel/camel-store.c
+++ b/camel/camel-store.c
@@ -55,6 +55,9 @@ typedef struct _SignalClosure SignalClosure;
 
 struct _CamelStorePrivate {
        GRecMutex folder_lock;  /* for locking folder operations */
+
+       GMutex signal_emission_lock;
+       gboolean folder_info_stale_scheduled;
 };
 
 struct _AsyncContext {
@@ -79,6 +82,7 @@ struct _SignalClosure {
 enum {
        FOLDER_CREATED,
        FOLDER_DELETED,
+       FOLDER_INFO_STALE,
        FOLDER_OPENED,
        FOLDER_RENAMED,
        LAST_SIGNAL
@@ -202,6 +206,27 @@ store_emit_folder_renamed_cb (gpointer user_data)
        return FALSE;
 }
 
+static gboolean
+store_emit_folder_info_stale_cb (gpointer user_data)
+{
+       SignalClosure *signal_closure = user_data;
+       CamelStore *store;
+
+       store = g_weak_ref_get (&signal_closure->store);
+
+       if (store != NULL) {
+               g_mutex_lock (&store->priv->signal_emission_lock);
+               store->priv->folder_info_stale_scheduled = FALSE;
+               g_mutex_unlock (&store->priv->signal_emission_lock);
+
+               g_signal_emit (store, signals[FOLDER_INFO_STALE], 0);
+
+               g_object_unref (store);
+       }
+
+       return FALSE;
+}
+
 /**
  * ignore_no_such_table_exception:
  * Clears the exception 'ex' when it's the 'no such table' exception.
@@ -1218,6 +1243,31 @@ camel_store_class_init (CamelStoreClass *class)
                G_TYPE_NONE, 1,
                G_TYPE_POINTER);
 
+       /**
+        * CamelStore::folder-info-stale:
+        * @store: the #CamelStore that received the signal
+        *
+        * This signal indicates significant changes have occurred to
+        * the folder hierarchy of @store, and that previously fetched
+        * #CamelFolderInfo data should be considered stale.
+        *
+        * Applications should handle this signal by replacing cached
+        * #CamelFolderInfo data for @store with fresh data by way of
+        * camel_store_get_folder_info().
+        *
+        * More often than not this signal will be emitted as a result of
+        * user preference changes rather than actual server-side changes.
+        * For example, a user may change a preference that reveals a set
+        * of folders previously hidden from view, or that alters whether
+        * to augment the @store with virtual Junk and Trash folders. */
+       signals[FOLDER_INFO_STALE] = g_signal_new (
+               "folder-info-stale",
+               G_OBJECT_CLASS_TYPE (class),
+               G_SIGNAL_RUN_FIRST,
+               G_STRUCT_OFFSET (CamelStoreClass, folder_info_stale),
+               NULL, NULL, NULL,
+               G_TYPE_NONE, 0);
+
        signals[FOLDER_OPENED] = g_signal_new (
                "folder-opened",
                G_OBJECT_CLASS_TYPE (class),
@@ -1425,6 +1475,54 @@ camel_store_folder_renamed (CamelStore *store,
        g_object_unref (session);
 }
 
+/**
+ * camel_store_folder_info_stale:
+ * @store: a #CamelStore
+ *
+ * Emits the #CamelStore::folder-info-stale signal from an idle source
+ * on the main loop.  The idle source's priority is #G_PRIORITY_LOW.
+ *
+ * See the #CamelStore::folder-info-stale documentation for details on
+ * when to use this signal.
+ *
+ * This function is only intended for Camel providers.
+ *
+ * Since: 3.10
+ **/
+void
+camel_store_folder_info_stale (CamelStore *store)
+{
+       CamelSession *session;
+
+       g_return_if_fail (CAMEL_IS_STORE (store));
+
+       session = camel_service_ref_session (CAMEL_SERVICE (store));
+
+       g_mutex_lock (&store->priv->signal_emission_lock);
+
+       /* Handling this signal is probably going to be expensive for
+        * applications so try and accumulate multiple calls into one
+        * signal emission if we can.  Hence the G_PRIORITY_LOW. */
+       if (!store->priv->folder_info_stale_scheduled) {
+               SignalClosure *signal_closure;
+
+               signal_closure = g_slice_new0 (SignalClosure);
+               g_weak_ref_set (&signal_closure->store, store);
+
+               camel_session_idle_add (
+                       session, G_PRIORITY_LOW,
+                       store_emit_folder_info_stale_cb,
+                       signal_closure,
+                       (GDestroyNotify) signal_closure_free);
+
+               store->priv->folder_info_stale_scheduled = TRUE;
+       }
+
+       g_mutex_unlock (&store->priv->signal_emission_lock);
+
+       g_object_unref (session);
+}
+
 static void
 add_special_info (CamelStore *store,
                   CamelFolderInfo *info,
diff --git a/camel/camel-store.h b/camel/camel-store.h
index 449230e..e5ee40f 100644
--- a/camel/camel-store.h
+++ b/camel/camel-store.h
@@ -306,6 +306,7 @@ struct _CamelStoreClass {
        void            (*folder_renamed)       (CamelStore *store,
                                                 const gchar *old_name,
                                                 CamelFolderInfo *folder_info);
+       void            (*folder_info_stale)    (CamelStore *store);
 };
 
 GType          camel_store_get_type            (void);
@@ -319,6 +320,7 @@ void                camel_store_folder_opened       (CamelStore *store,
 void           camel_store_folder_renamed      (CamelStore *store,
                                                 const gchar *old_name,
                                                 CamelFolderInfo *folder_info);
+void           camel_store_folder_info_stale   (CamelStore *store);
 void           camel_store_free_folder_info    (CamelStore *store,
                                                 CamelFolderInfo *fi);
 void           camel_store_free_folder_info_full
diff --git a/configure.ac b/configure.ac
index f1e8661..96aedb1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -130,7 +130,7 @@ LIBEBOOK_CONTACTS_CURRENT=0
 LIBEBOOK_CONTACTS_REVISION=0
 LIBEBOOK_CONTACTS_AGE=0
 
-LIBCAMEL_CURRENT=43
+LIBCAMEL_CURRENT=44
 LIBCAMEL_REVISION=0
 LIBCAMEL_AGE=0
 
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index 17cf6cb..667152b 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -2482,6 +2482,7 @@ camel_store_folder_created
 camel_store_folder_deleted
 camel_store_folder_opened
 camel_store_folder_renamed
+camel_store_folder_info_stale
 camel_store_free_folder_info
 camel_store_free_folder_info_full
 camel_store_free_folder_info_nop


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