[tracker] Fixed various things about the plugin running in Evolution's process
- From: Philip Van Hoof <pvanhoof src gnome org>
- To: svn-commits-list gnome org
- Subject: [tracker] Fixed various things about the plugin running in Evolution's process
- Date: Tue, 16 Jun 2009 10:50:13 -0400 (EDT)
commit 579bb1876782c130b4a1599ea0d42157d0a5121d
Author: Philip Van Hoof <philip codeminded be>
Date: Tue Jun 16 14:19:58 2009 +0200
Fixed various things about the plugin running in Evolution's process
src/plugins/evolution/tracker-evolution-plugin.c | 398 +++++++++++++++++-----
1 files changed, 305 insertions(+), 93 deletions(-)
---
diff --git a/src/plugins/evolution/tracker-evolution-plugin.c b/src/plugins/evolution/tracker-evolution-plugin.c
index 7bd4a59..8639797 100644
--- a/src/plugins/evolution/tracker-evolution-plugin.c
+++ b/src/plugins/evolution/tracker-evolution-plugin.c
@@ -62,13 +62,24 @@
* access to the CamelSession using the external variable 'session'. The header
* mail/mail-session.h makes this variable public */
-#define MAX_BEFORE_SEND 2000
+/* Note to people who are scared about this plugin using the CamelDB directly:
+ * The code uses camel_db_clone to create a new connection to the DB. We hope
+ * that's sufficient for not having to lock the store instances (sqlite3 has
+ * its own locks, and we only clone the db_r instance, we also only ever do
+ * reads, never writes). We hope that's sufficient for not having to get our
+ * code involved in Camel's cruel inneryard of having to lock the db_r ptr. */
+
+#define MAX_BEFORE_SEND 200
G_DEFINE_TYPE (TrackerEvolutionPlugin, tracker_evolution_plugin, G_TYPE_OBJECT)
#define TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_EVOLUTION_PLUGIN, TrackerEvolutionPluginPrivate))
-/* Some helper-defines */
+/* Some helper-defines (Copied from cruel Camel code, might be wrong as soon as
+ * the cruel and nasty Camel coders decide to change the format of the fields in
+ * the database) - guys, encoding things in fields of a table in a database is
+ * cruel and prone to error. Anyway). */
+
#define CAMEL_CALLBACK(func) ((CamelObjectEventHookFunc) func)
#define EXTRACT_STRING(val) if (*part) part++; len=strtoul (part, &part, 10); if (*part) part++; val=g_strndup (part, len); part+=len;
#define EXTRACT_FIRST_DIGIT(val) val=strtoul (part, &part, 10);
@@ -77,12 +88,13 @@ G_DEFINE_TYPE (TrackerEvolutionPlugin, tracker_evolution_plugin, G_TYPE_OBJECT)
* fashion. Therefore it's necessary to guard against concurrent access of
* memory. Especially given that both the mainloop and the Camel-threads will
* be accessing the memory (mainloop for DBus calls, and Camel-threads mostly
- * during registration of accounts and folders) */
+ * during registration of accounts and folders). I know this is cruel. I know. */
typedef struct {
guint64 last_checkout;
DBusGProxy *registrar;
guint signal;
+ gchar *sender;
} ClientRegistry;
typedef struct {
@@ -132,9 +144,11 @@ enum {
PROP_CONNECTION
};
+static GHashTable *registrars = NULL;
static DBusGProxy *dbus_proxy = NULL;
static TrackerEvolutionPlugin *manager = NULL;
static GStaticRecMutex glock = G_STATIC_REC_MUTEX_INIT;
+static guint register_count = 0;
/* Prototype declarations */
static void register_account (TrackerEvolutionPlugin *self, EAccount *account);
@@ -143,6 +157,9 @@ int e_plugin_lib_enable (EPluginLib *ep, int enable);
static void metadata_set_many (TrackerEvolutionPlugin *self, GStrv subjects, GPtrArray *predicates, GPtrArray *values);
static void metadata_unset_many (TrackerEvolutionPlugin *self, GStrv subjects);
+
+/* First a bunch of helper functions. */
+
static GList *
get_recipient_list (const gchar *str)
{
@@ -284,7 +301,9 @@ process_fields (GPtrArray *predicates_temp,
/* When new messages arrive to- or got deleted from the summary, called in
* mainloop or by a thread (unknown, depends on Camel and Evolution code that
- * executes the reason why this signal gets emitted) */
+ * executes the reason why this signal gets emitted).
+ *
+ * This one is the reason why we registered all those folders during init below. */
static void
on_folder_summary_changed (CamelFolder *folder,
@@ -469,6 +488,7 @@ on_folder_summary_changed (CamelFolder *folder,
g_free (em_uri);
}
+/* Info about this many_queue can be found in introduce_walk_folders_in_folder */
#define QUEUED_SETS_PER_MAINLOOP 2
@@ -477,6 +497,8 @@ typedef struct {
GPtrArray *values_array;
GPtrArray *predicates_array;
DBusGProxy *registrar;
+ GObject *self;
+ gchar *sender;
} QueuedSet;
static GQueue *many_queue = NULL;
@@ -494,6 +516,8 @@ queued_set_free (QueuedSet *queued_set)
g_strfreev (queued_set->predicates_array->pdata[i]);
g_ptr_array_free (queued_set->predicates_array, TRUE);
g_object_unref (queued_set->registrar);
+ g_object_unref (queued_set->self);
+ g_free (queued_set->sender);
g_slice_free (QueuedSet, queued_set);
}
@@ -514,14 +538,27 @@ many_idle_handler (gpointer user_data)
if (queued_set) {
- dbus_g_proxy_call_no_reply (queued_set->registrar,
- "SetMany",
- G_TYPE_STRV, queued_set->subjects,
- TRACKER_TYPE_G_STRV_ARRAY, queued_set->predicates_array,
- TRACKER_TYPE_G_STRV_ARRAY, queued_set->values_array,
- G_TYPE_UINT, (guint) time (NULL),
- G_TYPE_INVALID,
- G_TYPE_INVALID);
+ TrackerEvolutionPlugin *self = queued_set->self;
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
+
+ /* During initial introduction the client-registrar might
+ * decide to crash, disconnect, stop listening. That
+ * would result in critical warnings so we start ignoring
+ * as soon as service_gone has removed the registrar.
+ *
+ * We nonetheless need to handle these items to clean up
+ * the queue properly, of course. */
+
+ if (priv->registrars && g_hash_table_lookup (priv->registrars, queued_set->sender)) {
+ dbus_g_proxy_call_no_reply (queued_set->registrar,
+ "SetMany",
+ G_TYPE_STRV, queued_set->subjects,
+ TRACKER_TYPE_G_STRV_ARRAY, queued_set->predicates_array,
+ TRACKER_TYPE_G_STRV_ARRAY, queued_set->values_array,
+ G_TYPE_UINT, (guint) time (NULL),
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ }
queued_set_free (queued_set);
}
@@ -540,6 +577,9 @@ many_idle_destroy (gpointer user_data)
static void
start_many_handler (void)
{
+ /* We just slow it down to 'once per second' (for now, we can tweak this
+ * afterward, of course, but once per second seems to work great) */
+
g_timeout_add_seconds_full (G_PRIORITY_LOW, 1,
many_idle_handler,
NULL,
@@ -559,11 +599,24 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
while (iter) {
guint i, ret = SQLITE_OK;
- CamelDB *cdb_r = store->cdb_r;
+ CamelDB *cdb_r;
gchar *query;
sqlite3_stmt *stmt = NULL;
gboolean more = TRUE;
+ /* This query is the culprint of the functionality: it fetches
+ * all the metadata from the summary table where modified is
+ * more recent than the client-registry's modseq. Note that we
+ * pass time(NULL) to all methods, which is why comparing
+ * against the modified column that Evolution > 2.25.5 stores
+ * works (otherwise this wouldn't work, of course).
+ *
+ * The idea is that only the changes must initially be pushed,
+ * not everything each time (which would be unefficient). The
+ * specification (http://live.gnome.org/Evolution/Metadata)
+ * allows this 'modseq' optimization (is in fact recommending
+ * it over using Cleanup() each time) */
+
query = sqlite3_mprintf ("SELECT uid, flags, read, deleted, " /* 0 - 3 */
"replied, important, junk, attachment, " /* 4 - 7 */
"size, dsent, dreceived, subject, " /* 8 - 11 */
@@ -575,7 +628,7 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
iter->full_name,
info->last_checkout);
- g_mutex_lock (cdb_r->lock);
+ cdb_r = camel_db_clone (store->cdb_r, NULL);
ret = sqlite3_prepare_v2 (cdb_r->db, query, -1, &stmt, NULL);
@@ -724,12 +777,21 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
subjects[i] = g_ptr_array_index (subjects_a, i);
subjects[i] = NULL;
+ /* The many_queue stuff:
+ * Why is this? Ah! Good question and glad you ask.
+ * We noticed that hammering the DBus isn't exactly
+ * a truly good idea. This many-handler will
+ * slow it all down to a N items per N seconds
+ * thing. */
+
queued_set = g_slice_new (QueuedSet);
queued_set->subjects = subjects;
queued_set->predicates_array = predicates_array;
queued_set->values_array = values_array;
queued_set->registrar = g_object_ref (info->registrar);
+ queued_set->self = g_object_ref (self);
+ queued_set->sender = g_strdup (info->sender);
if (!many_queue) {
many_queue = g_queue_new ();
@@ -761,7 +823,7 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
sqlite3_finalize (stmt);
sqlite3_free (query);
- g_mutex_unlock (cdb_r->lock);
+ camel_db_clone (cdb_r, NULL);
if (iter->child) {
introduce_walk_folders_in_folder (self, iter->child, store, account_uri, info);
@@ -793,9 +855,7 @@ introduce_store_deal_with_deleted (TrackerEvolutionPlugin *self,
query = sqlite3_mprintf ("SELECT uid, mailbox FROM Deletes WHERE modified > %" PRIu64,
info->last_checkout);
- cdb_r = store->cdb_r;
-
- g_mutex_lock (cdb_r->lock);
+ cdb_r = camel_db_clone (store->cdb_r, NULL);
sqlite3_prepare_v2 (cdb_r->db, query, -1, &stmt, NULL);
@@ -875,12 +935,13 @@ introduce_store_deal_with_deleted (TrackerEvolutionPlugin *self,
sqlite3_finalize (stmt);
sqlite3_free (query);
- g_mutex_unlock (cdb_r->lock);
+ camel_db_close (cdb_r);
g_free (em_uri);
}
-/* Get the oldest date in all of the deleted-tables, called in the mainloop */
+/* Get the oldest date in all of the deleted-tables, called in the mainloop. We
+ * need this to test whether we should use Cleanup() or not. */
static guint64
get_last_deleted_time (TrackerEvolutionPlugin *self)
@@ -913,34 +974,35 @@ get_last_deleted_time (TrackerEvolutionPlugin *self)
continue;
}
- if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
+ if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE)) {
continue;
+ }
if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) {
camel_exception_clear (&ex);
continue;
}
- cdb_r = store->cdb_r;
+ cdb_r = camel_db_clone (store->cdb_r, NULL);
query = sqlite3_mprintf ("SELECT time FROM Deletes ORDER BY time LIMIT 1");
- g_mutex_lock (cdb_r->lock);
-
ret = sqlite3_prepare_v2 (cdb_r->db, query, -1, &stmt, NULL);
ret = sqlite3_step (stmt);
- if (ret == SQLITE_OK || ret == SQLITE_ROW)
+
+ if (ret == SQLITE_OK || ret == SQLITE_ROW) {
latest = sqlite3_column_int64 (stmt, 0);
+ }
- if (latest < smallest)
+ if (latest < smallest) {
smallest = latest;
+ }
sqlite3_finalize (stmt);
sqlite3_free (query);
- g_mutex_unlock (cdb_r->lock);
-
+ camel_db_close (cdb_r);
}
g_object_unref (it);
@@ -949,6 +1011,58 @@ get_last_deleted_time (TrackerEvolutionPlugin *self)
return smallest;
}
+typedef struct {
+ TrackerEvolutionPlugin *self;
+ gchar *account_uri;
+ CamelFolderInfo *iter;
+} GetFolderInfo;
+
+static void
+register_on_get_folder (gchar *uri, CamelFolder *folder, gpointer user_data)
+{
+ GetFolderInfo *info = user_data;
+ gchar *account_uri = info->account_uri;
+ CamelFolderInfo *iter = info->iter;
+ TrackerEvolutionPlugin *self = info->self;
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
+ guint hook_id;
+ FolderRegistry *registry;
+
+ if (!folder) {
+ goto fail_register;
+ }
+
+ registry = folder_registry_new (account_uri, folder, self);
+
+ g_static_rec_mutex_lock (priv->mutex);
+
+ if (!priv->registered_folders || !priv->cached_folders) {
+ goto not_ready;
+ }
+
+ hook_id = camel_object_hook_event (folder, "folder_changed",
+ CAMEL_CALLBACK (on_folder_summary_changed),
+ registry->hook_info);
+ registry->hook_info->hook_id = hook_id;
+
+ g_hash_table_replace (priv->registered_folders, &hook_id,
+ registry);
+ g_hash_table_replace (priv->cached_folders, g_strdup (iter->full_name),
+ folder);
+
+ not_ready:
+
+ g_static_rec_mutex_unlock (priv->mutex);
+
+ fail_register:
+
+ camel_folder_info_free (info->iter);
+ g_free (info->account_uri);
+ g_object_unref (info->self);
+ g_free (info);
+
+ register_count--;
+}
static void
register_walk_folders_in_folder (TrackerEvolutionPlugin *self,
@@ -958,42 +1072,35 @@ register_walk_folders_in_folder (TrackerEvolutionPlugin *self,
{
TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
- while (iter) {
- CamelFolder *folder;
-
- folder = camel_store_get_folder (store, iter->full_name, 0, NULL);
+ g_static_rec_mutex_lock (priv->mutex);
- if (folder) {
- guint hook_id;
- FolderRegistry *registry;
+ if (!priv->registered_folders) {
+ priv->registered_folders = g_hash_table_new_full (g_int_hash, g_int_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) folder_registry_free);
+ priv->cached_folders = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
+ }
- registry = folder_registry_new (account_uri, folder, self);
+ g_static_rec_mutex_unlock (priv->mutex);
- g_static_rec_mutex_lock (priv->mutex);
+ /* Recursively walks all the folders in store */
- if (!priv->registered_folders) {
- priv->registered_folders = g_hash_table_new_full (g_int_hash, g_int_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) folder_registry_free);
- priv->cached_folders = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) NULL);
- }
+ while (iter) {
+ GetFolderInfo *info = g_new0 (GetFolderInfo, 1);
- hook_id = camel_object_hook_event (folder, "folder_changed",
- CAMEL_CALLBACK (on_folder_summary_changed),
- registry->hook_info);
- registry->hook_info->hook_id = hook_id;
+ info->self = g_object_ref (self);
+ info->account_uri = g_strdup (account_uri);
+ info->iter = camel_folder_info_clone (iter);
- g_hash_table_replace (priv->registered_folders, &hook_id,
- registry);
- g_hash_table_replace (priv->cached_folders, g_strdup (iter->full_name),
- folder);
+ register_count++;
- g_static_rec_mutex_unlock (priv->mutex);
+ /* This is asynchronous and hooked to the mail/ API, so nicely
+ * integrated with the Evolution UI application */
- camel_object_unref (folder);
- }
+ mail_get_folder (iter->uri, 0, register_on_get_folder, info,
+ mail_msg_main_loop_push);
if (iter->child) {
register_walk_folders_in_folder (self, iter->child, store,
@@ -1006,38 +1113,67 @@ register_walk_folders_in_folder (TrackerEvolutionPlugin *self,
static void
+unregister_on_get_folder (gchar *uri, CamelFolder *folder, gpointer user_data)
+{
+ GetFolderInfo *info = user_data;
+ CamelFolderInfo *titer = info->iter;
+ TrackerEvolutionPlugin *self = info->self;
+ TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
+ GHashTableIter iter;
+ gpointer key, value;
+
+ if (!folder) {
+ goto fail_unregister;
+ }
+
+ g_static_rec_mutex_lock (priv->mutex);
+
+ if (!priv->registered_folders) {
+ goto no_folders;
+ }
+
+ g_hash_table_iter_init (&iter, priv->registered_folders);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ FolderRegistry *registry = value;
+
+ if (folder == registry->folder) {
+ g_hash_table_remove (priv->cached_folders, titer->full_name);
+ g_hash_table_iter_remove (&iter);
+ break;
+ }
+ }
+
+ no_folders:
+
+ g_static_rec_mutex_unlock (priv->mutex);
+
+ fail_unregister:
+
+ camel_folder_info_free (info->iter);
+ g_free (info->account_uri);
+ g_object_unref (info->self);
+ g_free (info);
+}
+static void
unregister_walk_folders_in_folder (TrackerEvolutionPlugin *self,
CamelFolderInfo *titer,
CamelStore *store,
gchar *account_uri)
{
- TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
+ /* Recursively walks all the folders in store */
while (titer) {
- CamelFolder *folder;
- GHashTableIter iter;
- gpointer key, value;
-
- folder = camel_store_get_folder (store, titer->full_name, 0, NULL);
-
- if (folder) {
- g_static_rec_mutex_lock (priv->mutex);
-
- g_hash_table_iter_init (&iter, priv->registered_folders);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- FolderRegistry *registry = value;
+ GetFolderInfo *info = g_new0 (GetFolderInfo, 1);
- if (folder == registry->folder) {
- g_hash_table_remove (priv->cached_folders, titer->full_name);
- g_hash_table_iter_remove (&iter);
- break;
- }
- }
+ info->self = g_object_ref (self);
+ info->account_uri = g_strdup (account_uri);
+ info->iter = camel_folder_info_clone (titer);
- camel_object_unref (folder);
+ /* This is asynchronous and hooked to the mail/ API, so nicely
+ * integrated with the Evolution UI application */
- g_static_rec_mutex_unlock (priv->mutex);
- }
+ mail_get_folder (titer->uri, 0, unregister_on_get_folder, info,
+ mail_msg_main_loop_push);
if (titer->child) {
unregister_walk_folders_in_folder (self, titer->child, store,
@@ -1054,6 +1190,7 @@ client_registry_info_free (ClientRegistry *info)
if (info->signal != 0) /* known (see below) */
g_signal_handler_disconnect (info->registrar, info->signal);
g_object_unref (info->registrar);
+ g_free (info->sender);
g_slice_free (ClientRegistry, info);
}
@@ -1063,27 +1200,94 @@ client_registry_info_copy (ClientRegistry *info)
ClientRegistry *ninfo = g_slice_new0 (ClientRegistry);
ninfo->signal = 0; /* known */
+ ninfo->sender = g_strdup (info->sender);
ninfo->last_checkout = info->last_checkout;
ninfo->registrar = g_object_ref (info->registrar);
return ninfo;
}
+/* For info about this try-again stuff, look at on_got_folderinfo_introduce */
+
+typedef struct {
+ IntroductionInfo *intro_info;
+ CamelStore *store;
+ CamelFolderInfo *iter;
+} TryAgainInfo;
+
+static gboolean
+try_again (gpointer user_data)
+{
+ if (register_count == 0) {
+ TryAgainInfo *info = user_data;
+ IntroductionInfo *intro_info = info->intro_info;
+
+ introduce_walk_folders_in_folder (intro_info->self,
+ info->iter,
+ info->store,
+ intro_info->account_uri,
+ intro_info->info);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+try_again_d (gpointer user_data)
+{
+ TryAgainInfo *info = user_data;
+
+ camel_object_unref (info->store);
+ camel_folder_info_free (info->iter);
+
+ client_registry_info_free (info->intro_info->info);
+ g_free (info->intro_info->account_uri);
+ g_object_unref (info->intro_info->self);
+ g_free (info->intro_info);
+
+ g_free (info);
+}
+
static gboolean
on_got_folderinfo_introduce (CamelStore *store,
CamelFolderInfo *iter,
void *data)
{
- IntroductionInfo *intro_info = data;
-
- introduce_walk_folders_in_folder (intro_info->self, iter, store,
- intro_info->account_uri,
- intro_info->info);
-
- client_registry_info_free (intro_info->info);
- g_free (intro_info->account_uri);
- g_object_unref (intro_info->self);
- g_free (intro_info);
+ TryAgainInfo *info = g_new0 (TryAgainInfo, 1);
+
+ camel_object_ref (store);
+ info->store = store;
+
+ info->iter = camel_folder_info_clone (iter);
+ info->intro_info = data;
+
+ /* If a registrar is running while Evolution is starting up, we decide
+ * not to slow down Evolution's startup by immediately going through
+ * all CamelFolder instances (the UI is doing the same thing, we can
+ * better allow the UI to do this first, and cache the folders that
+ * way)
+ *
+ * Regretfully doesn't Evolution's plugin interfaces give me a better
+ * hook to detect the startup of the UI application of Evolution, else
+ * it would of course be better to use that instead.
+ *
+ * The register_count is the amount of folders that we register, a
+ * registry has been made asynchronous using the high-level API
+ * mail_get_folder, so in the callback we decrement the number, before
+ * the call we increment the number. If we're at zero, it means we're
+ * fully initialized. If not, we wait ten seconds and retry until
+ * finally we're fully initialized. (it's not as magic as it looks) */
+
+ if (register_count != 0) {
+ g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, 10,
+ try_again, info,
+ try_again_d);
+ } else {
+ try_again (info);
+ try_again_d (info);
+ }
return TRUE;
}
@@ -1166,20 +1370,24 @@ introduce_accounts_to (TrackerEvolutionPlugin *self,
g_object_unref (it);
}
-
static void
register_client (TrackerEvolutionPlugin *self,
guint64 last_checkout,
DBusGProxy *registrar,
+ gchar *sender,
guint dsignal)
{
TrackerEvolutionPluginPrivate *priv = TRACKER_EVOLUTION_PLUGIN_GET_PRIVATE (self);
guint64 too_old = get_last_deleted_time (self);
ClientRegistry *info = g_slice_new0 (ClientRegistry);
+ info->sender = g_strdup (sender);
info->signal = dsignal;
info->registrar = g_object_ref (registrar);
+ /* If registrar's modseq is too old, send Cleanup (). This means that
+ * we tell it to start over (it must invalidate what it has). */
+
if (last_checkout < too_old) {
dbus_g_proxy_call_no_reply (registrar,
"Cleanup",
@@ -1187,8 +1395,9 @@ register_client (TrackerEvolutionPlugin *self,
G_TYPE_INVALID,
G_TYPE_INVALID);
info->last_checkout = 0;
- } else
+ } else {
info->last_checkout = last_checkout;
+ }
introduce_accounts_to (self, info);
@@ -1321,12 +1530,15 @@ on_got_folderinfo_register (CamelStore *store,
gchar *uri = reg_info->uri;
guint hook_id;
+ /* This is where it all starts for a registrar registering itself */
+
g_static_rec_mutex_lock (priv->mutex);
- if (!priv->registered_stores)
+ if (!priv->registered_stores) {
priv->registered_stores = g_hash_table_new_full (g_int_hash, g_int_equal,
(GDestroyNotify) NULL,
(GDestroyNotify) store_registry_free);
+ }
/* Hook up catching folder changes in the store */
registry = store_registry_new (store, account, self);
@@ -1352,7 +1564,7 @@ on_got_folderinfo_register (CamelStore *store,
g_static_rec_mutex_unlock (priv->mutex);
- /* Register each folder to hook folder_changed everywhere */
+ /* Register each folder to hook folder_changed everywhere (recursive) */
register_walk_folders_in_folder (self, iter, store, uri);
g_object_unref (reg_info->account);
@@ -1666,7 +1878,7 @@ tracker_evolution_plugin_register (TrackerEvolutionPlugin *plugin,
g_static_rec_mutex_unlock (priv->mutex);
/* Passing uint64 over DBus ain't working :-\ */
- register_client (plugin, (guint64) last_checkout, registrar, dsignal);
+ register_client (plugin, (guint64) last_checkout, registrar, sender, dsignal);
dbus_g_method_return (context);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]