tracker r1237 - in trunk: . src/trackerd



Author: mr
Date: Wed Mar 26 11:35:21 2008
New Revision: 1237
URL: http://svn.gnome.org/viewvc/tracker?rev=1237&view=rev

Log:
	* src/trackerd/Makefile.am:
	* src/trackerd/tracker-process-files.[ch]:
	* src/trackerd/tracker-process-requests.[ch]: 
	* src/trackerd/trackerd.c: Added these files to split out the
	indexing functionality which was in trackerd.c. 

	* src/trackerd/tracker-utils.h: Removed two members of the Tracker
	struct which are not used globally.


Added:
   trunk/src/trackerd/tracker-process-files.c
   trunk/src/trackerd/tracker-process-files.h
   trunk/src/trackerd/tracker-process-requests.c
   trunk/src/trackerd/tracker-process-requests.h
Modified:
   trunk/ChangeLog
   trunk/src/trackerd/Makefile.am
   trunk/src/trackerd/tracker-utils.h
   trunk/src/trackerd/trackerd.c

Modified: trunk/src/trackerd/Makefile.am
==============================================================================
--- trunk/src/trackerd/Makefile.am	(original)
+++ trunk/src/trackerd/Makefile.am	Wed Mar 26 11:35:21 2008
@@ -84,6 +84,10 @@
 	tracker-email-kmail.h						\
 	tracker-metadata.c						\
 	tracker-metadata.h						\
+	tracker-process-files.c						\
+	tracker-process-files.h						\
+	tracker-process-requests.c					\
+	tracker-process-requests.h					\
 	tracker-rdf-query.c						\
 	tracker-rdf-query.h						\
 	tracker-utils.c							\

Added: trunk/src/trackerd/tracker-process-files.c
==============================================================================
--- (empty file)
+++ trunk/src/trackerd/tracker-process-files.c	Wed Mar 26 11:35:21 2008
@@ -0,0 +1,1361 @@
+/* Tracker - indexer and metadata database engine
+ * Copyright (C) 2008, Mr Jamie McCracken (jamiemcc gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <signal.h>
+
+#ifdef OS_WIN32
+#include <windows.h>
+#include <pthread.h>
+#include "mingw-compat.h"
+#endif
+
+#include <glib.h>
+
+#include <libtracker-common/tracker-config.h>
+#include <libtracker-common/tracker-log.h>
+#include "../xdgmime/xdgmime.h"
+
+#include "tracker-apps.h"
+#include "tracker-db.h"
+#include "tracker-dbus.h"
+#include "tracker-dbus-methods.h"
+#include "tracker-cache.h"
+#include "tracker-email.h"
+#include "tracker-indexer.h"
+#include "tracker-os-dependant.h"
+#include "tracker-utils.h"
+#include "tracker-watch.h"
+
+static void
+process_my_yield (void)
+{
+#ifndef OS_WIN32
+	while (g_main_context_iteration (NULL, FALSE)) {
+                /* FIXME: do something here? */
+	}
+#endif
+}
+
+static void
+process_watch_list_add_dirs (Tracker  *tracker,
+                             GSList   *dir_list, 
+                             gboolean  check_dirs)
+{
+        if (!tracker->is_running) {
+		return;
+	}
+        
+	/* Add sub directories breadth first recursively to avoid
+         * running out of file handles.
+         */
+	while (dir_list) {
+                GSList *file_list = NULL;
+                GSList *tmp;
+
+		for (tmp = dir_list; tmp; tmp = tmp->next) {
+                        gchar *str;
+
+                        str = tmp->data;
+
+			if (str && !tracker_file_is_no_watched (str)) {
+				tracker->dir_list = g_slist_prepend (tracker->dir_list, g_strdup (str));
+
+				if (!tracker_config_get_enable_watches (tracker->config) || 
+                                    tracker_file_is_crawled (str)) {
+                                        continue;
+                                }
+
+				if ((tracker_count_watch_dirs () + g_slist_length (dir_list)) < tracker->watch_limit) {
+					if (!tracker_add_watch_dir (str, tracker->index_db) && tracker_is_directory (str)) {
+						tracker_debug ("Watch failed for %s", str);
+					}
+				}
+			}
+		}
+
+		g_slist_foreach (dir_list, (GFunc) tracker_get_dirs, &file_list);
+		g_slist_foreach (dir_list, (GFunc) g_free, NULL);
+		g_slist_free (dir_list);
+
+		dir_list = file_list;
+	}
+}
+
+static gboolean
+process_watch_dir (Tracker     *tracker,
+                   const gchar *dir)
+{
+	gchar *dir_utf8;
+
+	if (!tracker->is_running) {
+		return TRUE;
+	}
+
+	if (!dir) {
+		return FALSE;
+	}
+
+	if (!g_utf8_validate (dir, -1, NULL)) {
+		dir_utf8 = g_filename_to_utf8 (dir, -1, NULL,NULL,NULL);
+		if (!dir_utf8) {
+			tracker_error ("ERROR: watch_dir could not be converted to utf8 format");
+			return FALSE;
+		}
+	} else {
+		dir_utf8 = g_strdup (dir);
+	}
+
+	if (!tracker_file_is_valid (dir_utf8)) {
+		g_free (dir_utf8);
+		return FALSE;
+	}
+
+	if (!tracker_is_directory (dir_utf8)) {
+		g_free (dir_utf8);
+		return FALSE;
+	}
+
+	if (tracker_file_is_crawled (dir_utf8)) {
+		g_free (dir_utf8);
+		return FALSE;
+	}
+
+	if (!tracker_file_is_no_watched (dir_utf8)) {
+		GSList *mylist = NULL;
+
+		mylist = g_slist_prepend (mylist, dir_utf8);
+		process_watch_list_add_dirs (tracker, mylist, TRUE);
+	}
+
+	return TRUE;
+}
+
+static void
+process_watch_dir_foreach (const gchar  *dir, 
+                           Tracker      *tracker)
+{
+        process_watch_dir (tracker, dir);
+}
+
+static void
+process_schedule_dir_check_foreach (const gchar  *uri, 
+                                    Tracker      *tracker)
+{
+	if (!tracker->is_running) {
+		return;
+	}
+
+	g_return_if_fail (tracker_check_uri (uri));
+	g_return_if_fail (tracker->index_db);
+
+	tracker_db_insert_pending_file (tracker->index_db, 0, uri, NULL, "unknown", 0, 
+                                        TRACKER_ACTION_DIRECTORY_REFRESH, TRUE, FALSE, -1);
+}
+
+static inline void
+process_directory_list (Tracker  *tracker, 
+                        GSList   *list, 
+                        gboolean  recurse)
+{
+	tracker->dir_list = NULL;
+
+	if (!list) {
+		return;
+	}
+
+	g_slist_foreach (list, 
+                         (GFunc) process_watch_dir_foreach, 
+                         tracker);
+	g_slist_foreach (list, 
+                         (GFunc) process_schedule_dir_check_foreach, 
+                         tracker);
+
+	if (recurse && tracker->dir_list) {
+		g_slist_foreach (tracker->dir_list, 
+                                 (GFunc) process_schedule_dir_check_foreach, 
+                                 tracker);
+	}
+
+	if (tracker->dir_list) {
+		g_slist_foreach (tracker->dir_list, (GFunc) g_free, NULL);
+		g_slist_free (tracker->dir_list);
+                tracker->dir_list = NULL;
+	}
+}
+
+static void
+process_schedule_file_check_foreach (const gchar  *uri, 
+                                     Tracker      *tracker)
+{
+	if (!tracker->is_running) {
+		return;
+	}
+
+	g_return_if_fail (tracker_check_uri (uri));
+	g_return_if_fail (tracker->index_db);
+
+	/* Keep mainloop responsive */
+	process_my_yield ();
+
+	if (!tracker_is_directory (uri)) {
+		tracker_db_insert_pending_file (tracker->index_db, 0, uri, NULL, "unknown", 0, TRACKER_ACTION_CHECK, 0, FALSE, -1);
+	} else {
+		process_schedule_dir_check_foreach (uri, tracker);
+	}
+}
+
+static void
+process_scan_directory (Tracker     *tracker,
+                        const gchar *uri)
+{
+	GSList *file_list;
+
+	if (!tracker->is_running) {
+		return;
+	}
+
+	g_return_if_fail (tracker->index_db);
+	g_return_if_fail (tracker_check_uri (uri));
+	g_return_if_fail (tracker_is_directory (uri));
+
+	/* Keep mainloop responsive */
+	process_my_yield ();
+
+	file_list = tracker_get_files (uri, FALSE);
+	tracker_debug ("Scanning %s for %d files", uri, g_slist_length(file_list));
+
+	g_slist_foreach (file_list, 
+                         (GFunc) process_schedule_file_check_foreach, 
+                         tracker);
+	g_slist_foreach (file_list, 
+                         (GFunc) g_free, 
+                         NULL);
+	g_slist_free (file_list);
+
+	/* Recheck directory to update its mtime if its changed whilst
+         * scanning.
+         */
+	process_schedule_dir_check_foreach (uri, tracker);
+	tracker_debug ("Finished scanning");
+}
+
+static void
+process_action_verify (FileInfo *info)
+{
+        /* Determines whether an action applies to a file or a
+         * directory.
+         */
+
+	if (info->action == TRACKER_ACTION_CHECK) {
+		if (info->is_directory) {
+			info->action = TRACKER_ACTION_DIRECTORY_CHECK;
+			info->counter = 0;
+		} else {
+			info->action = TRACKER_ACTION_FILE_CHECK;
+		}
+
+	} else {
+		if (info->action == TRACKER_ACTION_DELETE || info->action == TRACKER_ACTION_DELETE_SELF) {
+
+			/* we are in trouble if we cant find the deleted uri in the DB - assume its a directory (worst case) */
+			if (info->file_id == 0) {
+				info->is_directory = TRUE;
+			}
+
+			info->counter = 0;
+			if (info->is_directory) {
+				info->action = TRACKER_ACTION_DIRECTORY_DELETED;
+			} else {
+				info->action = TRACKER_ACTION_FILE_DELETED;
+			}
+		} else {
+			if (info->action == TRACKER_ACTION_MOVED_FROM) {
+				info->counter = 1;
+				if (info->is_directory) {
+					info->action = TRACKER_ACTION_DIRECTORY_MOVED_FROM;
+				} else {
+					info->action = TRACKER_ACTION_FILE_MOVED_FROM;
+				}
+
+			} else {
+
+				if (info->action == TRACKER_ACTION_CREATE) {
+					if (info->is_directory) {
+						info->action = TRACKER_ACTION_DIRECTORY_CREATED;
+						info->counter = 0; /* do not reschedule a created directory */
+					} else {
+						info->action = TRACKER_ACTION_FILE_CREATED;
+					}
+
+				} else {
+					if (info->action == TRACKER_ACTION_FILE_MOVED_TO) {
+						info->counter = 0;
+						if (info->is_directory) {
+							info->action = TRACKER_ACTION_DIRECTORY_MOVED_TO;
+						} else {
+							info->action = TRACKER_ACTION_FILE_MOVED_TO;
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+static void
+process_index_entity (Tracker  *tracker, 
+                      FileInfo *info)
+{
+        ServiceDef *def;
+	gchar      *service_info;
+	gchar      *str;
+
+	g_return_if_fail (info);
+	g_return_if_fail (tracker_check_uri (info->uri));
+
+	if (!tracker_file_is_valid (info->uri)) {
+		return;
+	}
+
+	if (!info->is_directory) {
+		/* Sleep to throttle back indexing */
+		tracker_throttle (100);
+	}
+
+	service_info = tracker_get_service_for_uri (info->uri);
+
+	if (!service_info) {
+		tracker_error ("ERROR: cannot find service for path %s", info->uri);
+		return;
+	}
+
+        str = g_utf8_strdown (service_info, -1);
+	def = g_hash_table_lookup (tracker->service_table, str);
+	g_free (str);
+
+	if (!def) {
+		if (service_info) {
+			tracker_error ("ERROR: unknown service %s", service_info);
+		} else {
+			tracker_error ("ERROR: unknown service");
+		}
+		g_free (service_info);
+		return;
+	}
+
+	if (info->is_directory) {
+		info->is_hidden = !def->show_service_directories;
+		tracker_db_index_file (tracker->index_db, info, NULL, NULL);
+		g_free (service_info);
+		return;
+	} else {
+		info->is_hidden = !def->show_service_files;
+	}
+
+	if (g_str_has_suffix (service_info, "Emails")) {
+                DBConnection *db_con;
+
+                db_con = tracker->index_db;
+
+		if (!tracker_email_index_file (db_con, info, service_info)) {
+			g_free (service_info);
+			return;
+		}
+	} else if (strcmp (service_info, "Files") == 0) {
+		tracker_db_index_file (tracker->index_db, info, NULL, NULL);
+        } else if (strcmp (service_info, "WebHistory") ==0 ) {
+                tracker_db_index_webhistory (tracker->index_db, info);
+	} else if (g_str_has_suffix (service_info, "Conversations")) {
+		tracker_db_index_conversation (tracker->index_db, info);
+	} else if (strcmp (service_info, "Applications") == 0) {
+		tracker_db_index_application (tracker->index_db, info);
+	} else {
+		tracker_db_index_service (tracker->index_db, info, NULL, NULL, NULL, FALSE, TRUE, TRUE, TRUE);
+	}
+
+	g_free (service_info);
+}
+
+static void
+process_delete_file (Tracker  *tracker, 
+                     FileInfo *info)
+{
+	/* Info struct may have been deleted in transit here so check
+         * if still valid and intact.
+         */
+	g_return_if_fail (tracker_file_info_is_valid (info));
+
+	/* If we dont have an entry in the db for the deleted file, we
+         * ignore it.
+         */
+	if (info->file_id == 0) {
+		return;
+	}
+
+	tracker_db_delete_file (tracker->index_db, info->file_id);
+
+	tracker_log ("Deleting file %s", info->uri);
+}
+
+static void
+process_delete_dir (Tracker  *tracker, 
+                    FileInfo *info)
+{
+	/* Info struct may have been deleted in transit here so check
+         * if still valid and intact.
+         */
+	g_return_if_fail (tracker_file_info_is_valid (info));
+
+	/* If we dont have an entry in the db for the deleted
+         * directory, we ignore it.
+         */
+	if (info->file_id == 0) {
+		return;
+	}
+
+	tracker_db_delete_directory (tracker->index_db, info->file_id, info->uri);
+
+	tracker_remove_watch_dir (info->uri, TRUE, tracker->index_db);
+
+	tracker_log ("Deleting dir %s and subdirs", info->uri);
+}
+
+static void
+process_delete_dir_check (Tracker     *tracker,
+                          const gchar *uri)
+{
+	gchar **files;
+        gchar **p;
+
+	/* Check for any deletions*/
+	files = tracker_db_get_files_in_folder (tracker->index_db, uri);
+
+	for (p = files; *p; p++) {
+		gchar *str = *p;
+
+		if (!tracker_file_is_valid (str)) {
+                        FileInfo *info;
+
+			info = tracker_create_file_info (str, 1, 0, 0);
+			info = tracker_db_get_file_info (tracker->index_db, info);
+
+			if (!info->is_directory) {
+				process_delete_file (tracker, info);
+			} else {
+				process_delete_dir (tracker, info);
+			}
+			tracker_free_file_info (info);
+		}
+	}
+
+	g_strfreev (files);
+}
+
+static void
+process_add_dirs_to_list (Tracker *tracker, 
+                          GSList  *dir_list)
+{
+	GSList *new_dir_list = NULL;
+        GSList *l;
+
+	if (!tracker->is_running) {
+		return;
+	}
+
+	for (l = dir_list; l; l = l->next) {
+		if (l) {
+			new_dir_list = g_slist_prepend (new_dir_list, 
+                                                        g_strdup (l->data));
+		}
+	}
+
+	/* Add sub directories breadth first recursively to avoid
+         * running out of file handles.
+         */
+	while (new_dir_list) {
+                GSList *file_list = NULL;
+
+		for (l = new_dir_list; l; l = l->next) {
+                        gchar *str = l->data;
+
+			if (str && !tracker_file_is_no_watched (str)) {
+				tracker->dir_list = g_slist_prepend (tracker->dir_list, g_strdup (str));
+			}
+		}
+
+		g_slist_foreach (new_dir_list, (GFunc) tracker_get_dirs, &file_list);
+		g_slist_foreach (new_dir_list, (GFunc) g_free, NULL);
+		g_slist_free (new_dir_list);
+		new_dir_list = file_list;
+	}
+}
+
+static inline void
+process_queue_files_foreach (const gchar *uri, 
+                             gpointer     user_data)
+{
+        Tracker  *tracker;
+	FileInfo *info;
+        
+        tracker = (Tracker*) user_data;
+        info = tracker_create_file_info (uri, TRACKER_ACTION_CHECK, 0, 0);
+	g_async_queue_push (tracker->file_process_queue, info);
+}
+
+static void
+process_check_directory (Tracker     *tracker,
+                         const gchar *uri)
+{
+	GSList *file_list = NULL;
+
+	if (!tracker->is_running) {
+		return;
+	}
+
+	g_return_if_fail (tracker_check_uri (uri));
+	g_return_if_fail (tracker_is_directory (uri));
+
+	file_list = tracker_get_files (uri, FALSE);
+	tracker_debug ("Checking %s for %d files", uri, g_slist_length (file_list));
+
+	g_slist_foreach (file_list, (GFunc) process_queue_files_foreach, tracker);
+	g_slist_foreach (file_list, (GFunc) g_free, NULL);
+	g_slist_free (file_list);
+
+        process_queue_files_foreach (uri, tracker);
+
+	if (tracker->index_status != INDEX_EMAILS) {
+                tracker->folders_processed++;
+        }
+}
+
+/* 
+ * Actual Indexing functions 
+ */
+static void
+process_index_config (Tracker *tracker) 
+{
+        tracker_log ("Starting config indexing");
+}
+
+static void
+process_index_applications (Tracker *tracker) 
+{
+        GSList       *list;
+        DBConnection *db_con;
+
+        tracker_log ("Starting application indexing");
+       
+        db_con = tracker->index_db;
+
+        tracker_db_start_index_transaction (db_con);
+        tracker_db_start_transaction (db_con->cache);
+        
+        tracker_applications_add_service_directories ();
+        
+        list = tracker_get_service_dirs ("Applications");
+
+        tracker_add_root_directories (list);
+        process_directory_list (tracker, list, FALSE);
+
+        tracker_db_end_transaction (db_con->cache);
+        
+        g_slist_free (list);
+}
+
+static void
+process_index_files (Tracker *tracker)
+{
+        DBConnection *db_con;
+        GSList       *watch_directory_roots;
+        GSList       *no_watch_directory_roots;
+        gint          initial_sleep;
+
+        tracker_log ("Starting file indexing...");
+        
+        db_con = tracker->index_db;
+
+        initial_sleep = tracker_config_get_initial_sleep (tracker->config);
+       
+        tracker->pause_io = TRUE;
+
+        tracker_dbus_send_index_status_change_signal ();
+        tracker_db_end_index_transaction (db_con);
+
+        /* Sleep for N secs before watching/indexing any of the major services */
+        tracker_log ("Sleeping for %d secs before starting...", initial_sleep);
+        
+        while (initial_sleep > 0) {
+                g_usleep (G_USEC_PER_SEC);
+                
+                initial_sleep --;
+                
+                if (!tracker->is_running || tracker->shutdown) {
+                        return;
+                }		
+        }
+        
+        tracker->pause_io = FALSE;
+        tracker_dbus_send_index_status_change_signal ();
+        
+        tracker->dir_list = NULL;
+        
+        tracker_db_start_index_transaction (db_con);
+	
+        /* Delete all stuff in the no watch dirs */
+        watch_directory_roots = 
+                tracker_config_get_watch_directory_roots (tracker->config);
+        
+        no_watch_directory_roots = 
+                tracker_config_get_no_watch_directory_roots (tracker->config);
+        
+        if (no_watch_directory_roots) {
+                GSList *l;
+                
+                tracker_log ("Deleting entities in no watch directories...");
+                
+                for (l = no_watch_directory_roots; l; l = l->next) {
+                        guint32 f_id = tracker_db_get_file_id (db_con, l->data);
+                        
+                        if (f_id > 0) {
+                                tracker_db_delete_directory (db_con, f_id, l->data);
+                        }
+                }
+        }
+        
+        if (!watch_directory_roots) {
+                return;
+        }
+        
+        tracker_db_start_transaction (db_con->cache);
+        tracker_add_root_directories (watch_directory_roots);
+        
+        /* index watched dirs first */
+        g_slist_foreach (watch_directory_roots, 
+                         (GFunc) process_watch_dir_foreach, 
+                         tracker);
+        
+        g_slist_foreach (tracker->dir_list, 
+                         (GFunc) process_schedule_dir_check_foreach, 
+                         tracker);
+        
+        if (tracker->dir_list) {
+                g_slist_foreach (tracker->dir_list, 
+                                 (GFunc) g_free, 
+                                 NULL);
+                g_slist_free (tracker->dir_list);
+                tracker->dir_list = NULL;
+        }
+        
+        g_slist_foreach (watch_directory_roots, 
+                         (GFunc) process_schedule_dir_check_foreach, 
+                         tracker);
+        
+        if (tracker->dir_list) {
+                g_slist_foreach (tracker->dir_list, 
+                                 (GFunc) g_free, 
+                                 NULL);
+                g_slist_free (tracker->dir_list);
+                tracker->dir_list = NULL;
+        }
+        
+        tracker_db_end_transaction (db_con->cache);
+        tracker_dbus_send_index_progress_signal ("Files", "");
+}
+
+static void
+process_index_crawl_files (Tracker *tracker)
+{
+        DBConnection *db_con;
+        GSList       *crawl_directory_roots;
+        
+        db_con = tracker->index_db;
+
+        tracker_log ("Starting directory crawling...");
+        tracker->dir_list = NULL;
+        
+        crawl_directory_roots = 
+                tracker_config_get_crawl_directory_roots (tracker->config);
+        
+        if (!crawl_directory_roots) {
+                return;
+        }
+        
+        tracker_db_start_transaction (db_con->cache);
+        tracker_add_root_directories (crawl_directory_roots);
+        
+        process_add_dirs_to_list (tracker, crawl_directory_roots);
+        
+        g_slist_foreach (tracker->dir_list, 
+                         (GFunc) process_schedule_dir_check_foreach, 
+                         tracker);
+        
+        if (tracker->dir_list) {
+                g_slist_foreach (tracker->dir_list, (GFunc) g_free, NULL);
+                g_slist_free (tracker->dir_list);
+                tracker->dir_list = NULL;
+        }
+        
+        g_slist_foreach (crawl_directory_roots, 
+                         (GFunc) process_schedule_dir_check_foreach, 
+                         tracker);
+        
+        if (tracker->dir_list) {
+                g_slist_foreach (tracker->dir_list, (GFunc) g_free, NULL);
+                g_slist_free (tracker->dir_list);
+                tracker->dir_list = NULL;
+        }
+        
+        tracker_db_end_transaction (db_con->cache);
+}
+
+static void
+process_index_conversations (Tracker *tracker)
+{
+        gchar    *gaim, *purple;
+        gboolean  has_logs = FALSE;
+        GSList   *list = NULL;
+        
+        gaim = g_build_filename (g_get_home_dir(), ".gaim", "logs", NULL);
+        purple = g_build_filename (g_get_home_dir(), ".purple", "logs", NULL);
+        
+        if (tracker_file_is_valid (gaim)) {
+                has_logs = TRUE;
+                tracker_add_service_path ("GaimConversations", gaim);
+                list = g_slist_prepend (NULL, gaim);
+        }
+
+        if (tracker_file_is_valid (purple)) {
+                has_logs = TRUE;
+                tracker_add_service_path ("GaimConversations", purple);
+                list = g_slist_prepend (NULL, purple);
+        }
+        
+        if (has_logs) {
+                DBConnection *db_con;
+                
+                db_con = tracker->index_db;
+
+                tracker_log ("Starting chat log indexing...");
+                tracker_db_start_transaction (db_con->cache);
+                tracker_add_root_directories (list);
+                process_directory_list (tracker, list, TRUE);
+                tracker_db_end_transaction (db_con->cache);
+                g_slist_free (list);
+        }
+        
+        g_free (gaim);
+        g_free (purple);
+}
+
+static void
+process_index_webhistory (Tracker *tracker)
+{
+        GSList *list = NULL;
+        gchar  *firefox_dir;
+
+        firefox_dir = g_build_filename (g_get_home_dir(), ".xesam/Firefox/ToIndex", NULL);
+
+        if (tracker_file_is_valid (firefox_dir)) {
+                DBConnection *db_con;
+                
+                db_con = tracker->index_db;
+
+                list = g_slist_prepend( NULL, firefox_dir);
+                
+                tracker_log ("Starting Firefox web history indexing...");
+                tracker_add_service_path ("WebHistory", firefox_dir);
+                
+                tracker_db_start_transaction (db_con->cache);		
+                tracker_add_root_directories (list);
+                process_directory_list (tracker, list, TRUE);
+                tracker_db_end_transaction (db_con->cache);
+                g_slist_free (list);
+        }
+
+        g_free (firefox_dir);
+} 
+
+static void
+process_index_emails (Tracker *tracker)
+{
+        DBConnection  *db_con;
+        TrackerConfig *config;
+        gboolean       index_evolution_emails;
+        gboolean       index_kmail_emails;
+        gboolean       index_thunderbird_emails;
+       
+        db_con = tracker->index_db;
+        config = tracker->config;
+
+        tracker_db_end_index_transaction (db_con);
+        tracker_cache_flush_all ();
+	
+        tracker_indexer_merge_indexes (INDEX_TYPE_FILES);
+	
+        if (tracker->shutdown) {
+                return;
+        }
+	
+        tracker->index_status = INDEX_EMAILS;
+        
+        tracker_dbus_send_index_progress_signal ("Emails", "");
+        
+        if (tracker->word_update_count > 0) {
+                tracker_indexer_apply_changes (tracker->file_index, tracker->file_update_index, TRUE);
+        }
+        
+        tracker_db_start_index_transaction (tracker->index_db);
+              
+        index_evolution_emails = tracker_config_get_index_evolution_emails (config);
+        index_kmail_emails = tracker_config_get_index_kmail_emails (config);
+        index_thunderbird_emails = tracker_config_get_index_thunderbird_emails (config);
+        
+        if (index_evolution_emails ||
+            index_kmail_emails ||
+            index_thunderbird_emails) {
+                tracker_email_add_service_directories (db_con->emails);
+                tracker_log ("Starting email indexing...");
+                
+                tracker_db_start_transaction (db_con->cache);
+                
+                if (index_evolution_emails) {
+                        GSList *list;
+
+                        list = tracker_get_service_dirs ("EvolutionEmails");
+                        tracker_add_root_directories (list);
+                        process_directory_list (tracker, list, TRUE);
+                        g_slist_free (list);
+                        
+                        /* If initial indexing has not finished reset
+                         * mtime on all email stuff so they are
+                         * rechecked 
+                         */
+                        if (tracker_db_get_option_int (db_con->common, "InitialIndex") == 1) {
+                                gchar *sql;
+
+                                sql = g_strdup_printf ("update Services set mtime = 0 where path like '%s/.evolution/%%'", 
+                                                       g_get_home_dir ());
+                                tracker_exec_sql (tracker->index_db, sql);
+                                g_free (sql);
+                        }
+                }
+                
+                if (index_kmail_emails) {
+                        GSList *list;
+
+                        list = tracker_get_service_dirs ("KMailEmails");
+                        tracker_add_root_directories (list);
+                        process_directory_list (tracker, list, TRUE);
+                        g_slist_free (list);
+                }
+                
+                if (index_thunderbird_emails) {
+                        GSList *list;
+
+                        list = tracker_get_service_dirs ("ThunderbirdEmails");
+                        tracker_add_root_directories (list);
+                        process_directory_list (tracker, list, TRUE);
+                        g_slist_free (list);
+                }
+                
+                tracker_db_end_transaction (db_con->cache);
+        }
+}
+
+static gboolean
+process_files (Tracker *tracker)
+{
+        DBConnection *db_con;
+
+        db_con = tracker->index_db;
+
+        /* Check dir_queue in case there are
+         * directories waiting to be indexed.
+         */
+        if (g_async_queue_length (tracker->dir_queue) > 0) {
+                gchar *uri;
+                
+                uri = g_async_queue_try_pop (tracker->dir_queue);
+                
+                if (uri) {
+                        process_check_directory (tracker, uri);
+                        g_free (uri);
+                        return TRUE;
+                }
+        }
+        
+        if (tracker->index_status != INDEX_FINISHED) {
+                g_mutex_unlock (tracker->files_check_mutex);
+                
+                switch (tracker->index_status) {
+                case INDEX_CONFIG:
+                        process_index_config (tracker);
+                        break;
+                        
+                case INDEX_APPLICATIONS: 
+                        process_index_applications (tracker);
+                        break;
+                        
+                case INDEX_FILES: 
+                        process_index_files (tracker);
+                        break;
+                        
+                case INDEX_CRAWL_FILES:
+                        process_index_crawl_files (tracker);
+                        break;
+                        
+                case INDEX_CONVERSATIONS:
+                        process_index_conversations (tracker);
+                        break;
+                        
+                case INDEX_WEBHISTORY: 
+                        process_index_webhistory (tracker);
+                        break;
+                        
+                case INDEX_EXTERNAL:
+                        break;
+                        
+                case INDEX_EMAILS:
+                        process_index_emails (tracker);
+                        break;
+			
+                case INDEX_FINISHED:
+                        break;
+                }
+                
+                tracker->index_status++;
+                return TRUE;
+        }
+        
+        tracker_db_end_index_transaction (db_con);
+        tracker_cache_flush_all ();
+        tracker_db_refresh_all (db_con);
+        tracker_indexer_merge_indexes (INDEX_TYPE_FILES);
+	
+        if (tracker->shutdown) {
+                return FALSE;
+        }
+        
+        if (tracker->word_update_count > 0) {
+                tracker_indexer_apply_changes (tracker->file_index, 
+                                               tracker->file_update_index, 
+                                               TRUE);
+        }
+        
+        tracker_indexer_merge_indexes (INDEX_TYPE_EMAILS);
+        
+        if (tracker->shutdown) {
+                return FALSE;
+        }
+        
+        tracker->index_status = INDEX_FILES;
+        tracker_dbus_send_index_progress_signal ("Files","");
+        tracker->index_status = INDEX_FINISHED;
+        
+        if (tracker->is_running && tracker->first_time_index) {
+                tracker->status = STATUS_OPTIMIZING;
+                tracker->do_optimize = FALSE;
+                
+                tracker->first_time_index = FALSE;
+		
+                tracker_dbus_send_index_finished_signal ();
+                tracker_db_set_option_int (db_con, "InitialIndex", 0);
+                
+                tracker->update_count = 0;
+                
+                tracker_log ("Updating database stats, please wait...");
+                
+                tracker_db_start_transaction (db_con);
+                tracker_db_exec_no_reply (db_con, "ANALYZE");
+                tracker_db_end_transaction (db_con);
+                
+                tracker_db_start_transaction (db_con->emails);
+                tracker_db_exec_no_reply (db_con->emails, "ANALYZE");
+                tracker_db_end_transaction (db_con->emails);
+                
+                tracker_log ("Finished optimizing, waiting for new events...");
+        }
+        
+        /* We have no stuff to process so
+         * sleep until awoken by a new
+         * signal.
+         */
+        tracker->status = STATUS_IDLE;
+        tracker_dbus_send_index_status_change_signal ();
+        
+        g_cond_wait (tracker->file_thread_signal, 
+                     tracker->files_signal_mutex);
+        
+        tracker->grace_period = 0;
+        
+        /* Determine if wake up call is new
+         * stuff or a shutdown signal.
+         */
+        if (!tracker->shutdown) {
+                tracker_db_start_index_transaction (db_con);
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+static gboolean 
+process_action (Tracker  *tracker,
+                FileInfo *info)
+{
+        DBConnection *db_con;
+        gboolean      need_index;
+
+        db_con = tracker->index_db;
+        need_index = info->mtime > info->indextime;
+        
+        switch (info->action) {
+        case TRACKER_ACTION_FILE_CHECK:
+                break;
+                
+        case TRACKER_ACTION_FILE_CHANGED:
+        case TRACKER_ACTION_FILE_CREATED:
+        case TRACKER_ACTION_WRITABLE_FILE_CLOSED:
+                need_index = TRUE;
+                break;
+                
+        case TRACKER_ACTION_FILE_MOVED_FROM:
+                need_index = FALSE;
+                tracker_log ("Starting moving file %s to %s", info->uri, info->moved_to_uri);
+                tracker_db_move_file (db_con, info->uri, info->moved_to_uri);
+                break;
+                
+        case TRACKER_ACTION_DIRECTORY_REFRESH:
+                if (need_index && !tracker_file_is_no_watched (info->uri)) {
+                        g_async_queue_push (tracker->dir_queue, g_strdup (info->uri));
+                        
+                        if (tracker->index_status != INDEX_EMAILS) {
+                                tracker->folders_count++;
+                        }
+                }
+                
+                need_index = FALSE;
+                break;
+                
+        case TRACKER_ACTION_DIRECTORY_CHECK:
+                if (need_index && !tracker_file_is_no_watched (info->uri)) {
+                        g_async_queue_push (tracker->dir_queue, g_strdup (info->uri));
+			
+                        if (info->indextime > 0) {
+                                process_delete_dir_check (tracker, info->uri);
+                        }
+                }
+                
+                break;
+                
+        case TRACKER_ACTION_DIRECTORY_MOVED_FROM:
+                tracker_db_move_directory (db_con, info->uri, info->moved_to_uri);
+                need_index = FALSE;
+                break;
+                
+        case TRACKER_ACTION_DIRECTORY_CREATED:
+                need_index = TRUE;
+                tracker_debug ("Processing created directory %s", info->uri);
+                
+                /* Schedule a rescan for all files in folder
+                 * to avoid race conditions.
+                 */
+                if (!tracker_file_is_no_watched (info->uri)) {
+                        /* Add to watch folders (including
+                         * subfolders).
+                         */
+                        process_watch_dir (tracker, info->uri);
+                        process_scan_directory (tracker, info->uri);
+                } else {
+                        tracker_debug ("Blocked scan of directory %s as its in the no watch list", 
+                                       info->uri);
+                }
+                
+                break;
+                
+        default:
+                break;
+        }
+
+        return need_index;
+}
+
+static gboolean
+process_action_prechecks (Tracker  *tracker, 
+                          FileInfo *info)
+{
+        DBConnection *db_con;
+
+        /* Info struct may have been deleted in transit here
+         * so check if still valid and intact.
+         */
+        if (!tracker_file_info_is_valid (info)) {
+                return TRUE;
+        }
+
+        db_con = tracker->index_db;
+        
+        if (info->file_id == 0 && 
+            info->action != TRACKER_ACTION_CREATE &&
+            info->action != TRACKER_ACTION_DIRECTORY_CREATED && 
+            info->action != TRACKER_ACTION_FILE_CREATED) {
+                info = tracker_db_get_file_info (db_con, info);
+                
+                /* Get more file info if db retrieval returned nothing */
+                if (info->file_id == 0) {
+                        info = tracker_get_file_info (info);
+                        info->is_new = TRUE;
+                } else {
+                        info->is_new = FALSE;
+                }
+        } else {
+                info->is_new = TRUE;
+        }
+        
+        tracker_debug ("Processing %s with action %s and counter %d ",
+                       info->uri, 
+                       tracker_actions[info->action], 
+                       info->counter);
+        
+        /* Preprocess ambiguous actions when we need to work
+         * out if its a file or a directory that the action
+         * relates to.
+         */
+        process_action_verify (info);
+        
+        if (info->action != TRACKER_ACTION_DELETE &&
+            info->action != TRACKER_ACTION_DIRECTORY_DELETED &&
+            info->action != TRACKER_ACTION_FILE_DELETED) {
+                if (!tracker_file_is_valid (info->uri) ) {
+                        gboolean invalid = TRUE;
+                        
+                        if (info->moved_to_uri) {
+                                invalid = !tracker_file_is_valid (info->moved_to_uri);
+                        }
+                        
+                        if (invalid) {
+                                tracker_free_file_info (info);
+                                return TRUE;
+                        }
+                }
+                
+                /* Get file ID and other interesting fields
+                 * from Database if not previously fetched or
+                 * is newly created.
+                 */
+        } else {
+                if (info->action == TRACKER_ACTION_FILE_DELETED) {
+                        process_delete_file (tracker, info);
+                        info = tracker_dec_info_ref (info);
+                        return TRUE;
+                } else {
+                        if (info->action == TRACKER_ACTION_DIRECTORY_DELETED) {
+                                process_delete_file (tracker, info);
+                                process_delete_dir (tracker, info);
+                                info = tracker_dec_info_ref (info);
+                                return TRUE;
+                        }
+                }
+        }	
+        
+        /* Get latest file info from disk */
+        if (info->mtime == 0) {
+                info = tracker_get_file_info (info);
+        }
+
+        return FALSE;
+}
+
+static void
+process_block_signals (void)
+{
+	sigset_t signal_set;
+
+        /* Block all signals in this thread */
+        sigfillset (&signal_set);
+        
+#ifndef OS_WIN32
+        pthread_sigmask (SIG_BLOCK, &signal_set, NULL);
+#endif
+}
+
+/* This is the thread entry point for the indexer to start processing
+ * files and all other categories for processing.
+ */
+gpointer
+tracker_process_files (gpointer data)
+{
+	Tracker      *tracker;
+        DBConnection *db_con;
+	GSList	     *moved_from_list; /* List to hold moved_from
+                                        * events whilst waiting for a
+                                        * matching moved_to event.
+                                        */
+	gboolean      pushed_events;
+        gboolean      first_run;
+
+        tracker = (Tracker*) data;
+
+        process_block_signals ();
+
+	g_mutex_lock (tracker->files_signal_mutex);
+	g_mutex_lock (tracker->files_stopped_mutex);
+
+	/* Set thread safe DB connection */
+	tracker_db_thread_init ();
+
+	tracker->index_db = tracker_db_connect_all (TRUE);
+	tracker->index_status = INDEX_CONFIG;
+
+	pushed_events = FALSE;
+	first_run = TRUE;
+	moved_from_list = NULL;
+
+	tracker_log ("Starting indexing...");
+
+	tracker->index_time_start = time (NULL);
+
+	while (TRUE) {
+		FileInfo *info;
+		gboolean  need_index;
+
+		db_con = tracker->index_db;
+
+		if (!tracker_cache_process_events (tracker->index_db, TRUE) ) {
+			tracker->status = STATUS_SHUTDOWN;
+			tracker_dbus_send_index_status_change_signal ();
+			break;	
+		}
+
+		if (tracker->status != STATUS_INDEXING) {
+			tracker->status = STATUS_INDEXING;
+			tracker_dbus_send_index_status_change_signal ();
+		}
+						
+		info = g_async_queue_try_pop (tracker->file_process_queue);
+
+		/* Check pending table if we haven't got anything */
+		if (!info) {
+			gchar ***res;
+			gint     k;
+
+			if (!tracker_db_has_pending_files (tracker->index_db)) {
+                                gboolean should_continue;
+
+                                /* Set mutex to indicate we are in "check" state */
+                                g_mutex_lock (tracker->files_check_mutex);
+                                should_continue = process_files (tracker);
+                                g_mutex_unlock (tracker->files_check_mutex);
+                                
+                                if (should_continue) {
+                                        continue;
+                                }
+
+                                if (tracker->shutdown) {
+                                        break;
+                                }
+                        }
+
+			res = tracker_db_get_pending_files (tracker->index_db);
+
+			k = 0;
+			pushed_events = FALSE;
+
+			if (res) {
+				gchar **row;
+
+				tracker->status = STATUS_PENDING;
+
+				while ((row = tracker_db_get_row (res, k))) {
+					FileInfo	    *info_tmp;
+					TrackerChangeAction  tmp_action;
+
+					if (!tracker->is_running) {
+						tracker_db_free_result (res);
+						break;
+					}
+
+					k++;
+
+					tmp_action = atoi (row[2]);
+
+					info_tmp = tracker_create_file_info (row[1], tmp_action, 0, WATCH_OTHER);
+					g_async_queue_push (tracker->file_process_queue, info_tmp);
+					pushed_events = TRUE;
+				}
+
+				tracker_db_free_result (res);
+			}
+
+			if (!tracker->is_running) {
+				continue;
+			}
+
+			tracker_db_remove_pending_files (tracker->index_db);
+
+			/* Pending files are present but not yet ready
+                         * as we are waiting til they stabilize so we
+                         * should sleep for 100ms (only occurs when
+                         * using FAM or inotify move/create). 
+                         */
+			if (!pushed_events && k == 0) {
+				g_usleep (100000);
+			}
+
+			continue;
+		}
+
+		tracker->status = STATUS_INDEXING;
+
+                if (process_action_prechecks (tracker, info)) {
+                        continue;
+                }
+                
+		/* Check if file needs indexing */
+                need_index = process_action (tracker, info);
+
+		if (need_index) {
+			if (tracker_db_regulate_transactions (tracker->index_db, 250)) {
+				if (tracker_config_get_verbosity (tracker->config) == 1) {
+					tracker_log ("indexing #%d - %s", tracker->index_count, info->uri);
+				}
+
+				tracker_dbus_send_index_progress_signal ("Files", info->uri);
+			}
+
+			process_index_entity (tracker, info);
+			tracker->index_db = tracker->index_db;	
+		}
+
+		tracker_dec_info_ref (info);
+	}
+
+	xdg_mime_shutdown ();
+
+	tracker_db_close_all (tracker->index_db);
+	tracker_db_thread_end ();
+
+	g_mutex_unlock (tracker->files_stopped_mutex);
+
+        return NULL;
+}

Added: trunk/src/trackerd/tracker-process-files.h
==============================================================================
--- (empty file)
+++ trunk/src/trackerd/tracker-process-files.h	Wed Mar 26 11:35:21 2008
@@ -0,0 +1,25 @@
+/* Tracker - indexer and metadata database engine
+ * Copyright (C) 2008, Mr Jamie McCracken (jamiemcc gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __TRACKER_PROCESS_FILES_H__
+#define __TRACKER_PROCESS_FILES_H__
+
+gpointer tracker_process_files (gpointer data);
+
+#endif /* __TRACKER_PROCESS_FILES_H__ */

Added: trunk/src/trackerd/tracker-process-requests.c
==============================================================================
--- (empty file)
+++ trunk/src/trackerd/tracker-process-requests.c	Wed Mar 26 11:35:21 2008
@@ -0,0 +1,404 @@
+/* Tracker - indexer and metadata database engine
+ * Copyright (C) 2008, Mr Jamie McCracken (jamiemcc gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <signal.h>
+
+#ifdef OS_WIN32
+#include <windows.h>
+#include <pthread.h>
+#include "mingw-compat.h"
+#endif
+
+#include <glib.h>
+
+#include <libtracker-common/tracker-log.h>
+
+#include "tracker-db.h"
+#include "tracker-dbus.h"
+#include "tracker-dbus-files.h"
+#include "tracker-dbus-keywords.h"
+#include "tracker-dbus-methods.h"
+#include "tracker-dbus-metadata.h"
+#include "tracker-dbus-search.h"
+#include "tracker-utils.h"
+
+static void
+process_block_signals (void)
+{
+	sigset_t signal_set;
+
+        /* Block all signals in this thread */
+        sigfillset (&signal_set);
+        
+#ifndef OS_WIN32
+        pthread_sigmask (SIG_BLOCK, &signal_set, NULL);
+#endif
+}
+
+/* This is the thread entry function for handing DBus requests by the
+ * daemon to any clients connected.
+ */
+gpointer
+tracker_process_requests (gpointer data)
+{
+	Tracker      *tracker;
+	DBConnection *db_con;
+
+        tracker = (Tracker*) data;
+
+        process_block_signals ();
+
+	g_mutex_lock (tracker->request_signal_mutex);
+	g_mutex_lock (tracker->request_stopped_mutex);
+
+	/* Set thread safe DB connection */
+	tracker_db_thread_init ();
+
+	db_con = tracker_db_connect_all (FALSE);
+
+	tracker_db_prepare_queries (db_con);
+
+	while (TRUE) {
+		DBusRec	    *rec;
+		DBusMessage *reply;
+                gboolean     result;
+
+		/* Make thread sleep if first part of the shutdown
+                 * process has been activated.
+                 */
+		if (!tracker->is_running) {
+			g_cond_wait (tracker->request_thread_signal, 
+                                     tracker->request_signal_mutex);
+
+			/* Determine if wake up call is new stuff or a
+                         * shutdown signal.
+                         */
+			if (!tracker->shutdown) {
+				continue;
+			} else {
+				break;
+			}
+		}
+
+		/* Lock check mutex to prevent race condition when a
+                 * request is submitted after popping queue but prior
+                 * to sleeping.
+                 */
+		g_mutex_lock (tracker->request_check_mutex);
+		rec = g_async_queue_try_pop (tracker->user_request_queue);
+
+		if (!rec) {
+			g_cond_wait (tracker->request_thread_signal, 
+                                     tracker->request_signal_mutex);
+			g_mutex_unlock (tracker->request_check_mutex);
+
+			/* Determine if wake up call is new stuff or a
+                         * shutdown signal.
+                         */
+			if (!tracker->shutdown) {
+				continue;
+			} else {
+				break;
+			}
+		}
+
+		/* Thread will not sleep without another iteration so
+                 * race condition no longer applies.
+                 */
+		g_mutex_unlock (tracker->request_check_mutex);
+	
+		rec->user_data = db_con;
+
+		switch (rec->action) {
+                case DBUS_ACTION_PING:      
+                        result = TRUE;
+
+                        reply = dbus_message_new_method_return (rec->message);
+                        dbus_message_append_args (reply,
+                                                  DBUS_TYPE_BOOLEAN, &result,
+                                                  DBUS_TYPE_INVALID);
+                        
+                        dbus_connection_send (rec->connection, reply, NULL);
+                        dbus_message_unref (reply);
+                        break;
+                        
+                case DBUS_ACTION_GET_STATS:
+                        tracker_dbus_method_get_stats (rec);
+                        break;
+                        
+                case DBUS_ACTION_GET_SERVICES:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_get_services (rec);
+                        break;
+                        
+                case DBUS_ACTION_GET_VERSION:
+                        tracker_dbus_method_get_version (rec);
+                        break;
+                        
+                case DBUS_ACTION_GET_STATUS:
+                        tracker_dbus_method_get_status (rec);
+                        break;
+                        
+                case DBUS_ACTION_SET_BOOL_OPTION:
+                        tracker_dbus_method_set_bool_option (rec);
+                        break;
+                        
+                case DBUS_ACTION_SET_INT_OPTION:
+                        tracker_dbus_method_set_int_option (rec);
+                        break;
+                        
+                case DBUS_ACTION_SHUTDOWN:
+                        tracker_dbus_method_shutdown (rec);
+                        break;
+                        
+                case DBUS_ACTION_PROMPT_INDEX_SIGNALS:
+                        tracker_dbus_method_prompt_index_signals (rec);
+                        break;
+                        
+                case DBUS_ACTION_METADATA_GET:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_metadata_get (rec);
+                        break;
+                        
+                case DBUS_ACTION_METADATA_SET:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_metadata_set(rec);
+                        break;
+                        
+                case DBUS_ACTION_METADATA_REGISTER_TYPE:
+                        tracker_dbus_method_metadata_register_type (rec);
+                        break;
+                        
+                case DBUS_ACTION_METADATA_GET_TYPE_DETAILS:
+                        tracker_dbus_method_metadata_get_type_details (rec);
+                        break;
+                        
+                case DBUS_ACTION_METADATA_GET_REGISTERED_TYPES:
+                        tracker_dbus_method_metadata_get_registered_types (rec);
+                        break;
+                        
+                case DBUS_ACTION_METADATA_GET_WRITEABLE_TYPES:
+                        tracker_dbus_method_metadata_get_writeable_types (rec);
+                        break;
+                        
+                case DBUS_ACTION_METADATA_GET_REGISTERED_CLASSES:
+                        tracker_dbus_method_metadata_get_registered_classes (rec);
+                        break;
+                        
+                case DBUS_ACTION_KEYWORDS_GET_LIST:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_keywords_get_list (rec);
+                        break;
+                        
+                case DBUS_ACTION_KEYWORDS_GET:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_keywords_get (rec);
+                        break;
+                        
+                case DBUS_ACTION_KEYWORDS_ADD:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_keywords_add (rec);
+                        break;
+                        
+                case DBUS_ACTION_KEYWORDS_REMOVE:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_keywords_remove (rec);
+                        break;
+                        
+                case DBUS_ACTION_KEYWORDS_REMOVE_ALL:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_keywords_remove_all (rec);
+                        break;
+                        
+                case DBUS_ACTION_KEYWORDS_SEARCH:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_keywords_search (rec);
+                        break;
+                        
+                case DBUS_ACTION_SEARCH_GET_HIT_COUNT:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_search_get_hit_count (rec);
+                        break;
+                        
+                case DBUS_ACTION_SEARCH_GET_HIT_COUNT_ALL:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_search_get_hit_count_all (rec);
+                        break;
+                        
+                case DBUS_ACTION_SEARCH_TEXT:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_search_text (rec);
+                        break;
+                        
+                case DBUS_ACTION_SEARCH_TEXT_DETAILED:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_search_text_detailed (rec);
+                        break;
+                        
+                case DBUS_ACTION_SEARCH_GET_SNIPPET:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_search_get_snippet (rec);
+                        break;
+                        
+                case DBUS_ACTION_SEARCH_FILES_BY_TEXT:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_search_files_by_text (rec);
+                        break;
+                        
+                case DBUS_ACTION_SEARCH_METADATA:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_search_metadata (rec);
+                        break;
+                        
+                case DBUS_ACTION_SEARCH_MATCHING_FIELDS:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_search_matching_fields (rec);
+                        break;
+                        
+                case DBUS_ACTION_SEARCH_QUERY:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_search_query (rec);
+                        break;
+                        
+                case DBUS_ACTION_SEARCH_SUGGEST:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_search_suggest (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_EXISTS:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_files_exists (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_CREATE:
+                        tracker_dbus_method_files_create (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_DELETE:
+                        tracker_dbus_method_files_delete (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_GET_SERVICE_TYPE:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_files_get_service_type (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_GET_TEXT_CONTENTS:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_files_get_text_contents (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_SEARCH_TEXT_CONTENTS:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_files_search_text_contents (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_GET_BY_SERVICE_TYPE:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_files_get_by_service_type (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_GET_BY_MIME_TYPE:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_files_get_by_mime_type (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_GET_BY_MIME_TYPE_VFS:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_files_get_by_mime_type_vfs (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_GET_MTIME:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_files_get_mtime (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_GET_METADATA_FOLDER_FILES:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_files_get_metadata_for_files_in_folder (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_SEARCH_BY_TEXT_MIME:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_files_search_by_text_mime (rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_SEARCH_BY_TEXT_MIME_LOCATION:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_files_search_by_text_mime_location(rec);
+                        break;
+                        
+                case DBUS_ACTION_FILES_SEARCH_BY_TEXT_LOCATION:
+                        tracker->request_waiting = TRUE;
+                        tracker->grace_period = 2;
+                        tracker_dbus_method_files_search_by_text_location (rec);
+                        break;
+                        
+                default:
+                        break;
+		}
+
+		dbus_message_unref (rec->message);
+		g_free (rec);
+	}
+
+	tracker_db_close_all (db_con);
+        tracker_db_thread_end ();
+
+	tracker_debug ("Request thread has exited successfully");
+
+	/* Ulock mutex so we know thread has exited */
+	g_mutex_unlock (tracker->request_check_mutex);
+	g_mutex_unlock (tracker->request_stopped_mutex);
+
+        return NULL;
+}

Added: trunk/src/trackerd/tracker-process-requests.h
==============================================================================
--- (empty file)
+++ trunk/src/trackerd/tracker-process-requests.h	Wed Mar 26 11:35:21 2008
@@ -0,0 +1,25 @@
+/* Tracker - indexer and metadata database engine
+ * Copyright (C) 2008, Mr Jamie McCracken (jamiemcc gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __TRACKER_PROCESS_REQUESTS_H__
+#define __TRACKER_PROCESS_REQUESTS_H__
+
+gpointer tracker_process_requests (gpointer data);
+
+#endif /* __TRACKER_PROCESS_REQUESTS_H__ */

Modified: trunk/src/trackerd/tracker-utils.h
==============================================================================
--- trunk/src/trackerd/tracker-utils.h	(original)
+++ trunk/src/trackerd/tracker-utils.h	Wed Mar 26 11:35:21 2008
@@ -370,8 +370,6 @@
 	GMutex		*request_stopped_mutex;
 
 	GThread 	*file_metadata_thread;
-	GThread 	*file_process_thread;
-	GThread 	*user_request_thread;
 
 	GCond 		*file_thread_signal;
 	GCond 		*metadata_thread_signal;

Modified: trunk/src/trackerd/trackerd.c
==============================================================================
--- trunk/src/trackerd/trackerd.c	(original)
+++ trunk/src/trackerd/trackerd.c	Wed Mar 26 11:35:21 2008
@@ -23,24 +23,19 @@
 
 #define I_AM_MAIN
 
+#include "config.h"
+
 #include <signal.h>
 #include <errno.h>
 #include <locale.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <time.h>
+
 #include <glib/gstdio.h>
 #include <glib/gi18n.h>
 #include <glib/gpattern.h>
 
-#include "config.h"
-
-#include "../xdgmime/xdgmime.h"
-
 #ifdef IOPRIO_SUPPORT
 #include "tracker-ioprio.h"
 #endif
@@ -58,27 +53,19 @@
 #include <libtracker-common/tracker-language.h>
 #include <libtracker-common/tracker-log.h>
 
-#include "tracker-dbus-methods.h"
-#include "tracker-dbus-metadata.h"
-#include "tracker-dbus-keywords.h"
-#include "tracker-dbus-search.h"
-#include "tracker-dbus-files.h"
+#include "tracker-dbus.h"
 #include "tracker-email.h"
-#include "tracker-email-utils.h"
-#include "tracker-cache.h"
 #include "tracker-indexer.h"
+#include "tracker-process-files.h"
+#include "tracker-process-requests.h"
 #include "tracker-watch.h"
 
-#include "tracker-os-dependant.h"
-  
 #ifdef OS_WIN32
 #include <windows.h>
 #include <pthread.h>
 #include "mingw-compat.h"
 #endif
 
-#include "tracker-apps.h"
-
 typedef struct {
 	gchar	*uri;
 	gint	mtime;
@@ -123,16 +110,6 @@
 
 gchar *type_array[] =   {"index", "string", "numeric", "date", NULL};
 
-
-static void schedule_file_check (const gchar *uri, DBConnection *db_con);
-
-static void delete_directory (DBConnection *db_con, FileInfo *info);
-
-static void delete_file (DBConnection *db_con, FileInfo *info);
-
-static void scan_directory (const gchar *uri, DBConnection *db_con);
-
-
 static gchar **ignore_pattern = NULL; 
 static gchar **no_watch_dirs = NULL;
 static gchar **watch_dirs = NULL;
@@ -162,17 +139,6 @@
 };
 
 
-static void
-my_yield (void)
-{
-#ifndef OS_WIN32
-	while (g_main_context_iteration (NULL, FALSE)) {
-		;
-	}
-#endif
-}
-
-
 static gint
 get_update_count (DBConnection *db_con)
 {
@@ -192,1957 +158,361 @@
 
 #ifdef HAVE_HAL
 
-static void
-property_callback (LibHalContext *ctx, const char *udi, const char *key,
-                   dbus_bool_t is_removed, dbus_bool_t is_added)
-{
-
-	tracker_log ("HAL property change detected for udi %s and key %s", udi, key);
-
-	gboolean current_state = tracker->pause_battery;
-
-	if (strcmp (udi, tracker->battery_udi) == 0) {
-
-		tracker->pause_battery = !libhal_device_get_property_bool (ctx, tracker->battery_udi, BATTERY_OFF, NULL);
-		
-		char *bat_state[2] = {"off","on"};
-		tracker_log ("Battery power is now %s", bat_state[tracker->pause_battery]);
-
-	} else {
-		return;
-	}
-
-	/* if we have come off battery power wakeup index thread */
-	if (current_state && !tracker->pause_battery) {
-		tracker_notify_file_data_available ();
-	}
-
-}
-
-
-LibHalContext *
-tracker_hal_init ()
-{
-	LibHalContext *ctx;
-  	char **devices;
-  	int num;
-	DBusError error;
-	DBusConnection *connection;
-
-	dbus_error_init (&error);
-
-	connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
-
-	g_print ("starting HAL detection for ac adaptors...");
-
-	if (!connection) {
-		if (dbus_error_is_set (&error)) {
-			tracker_error ("Could not connect to system bus due to %s", error.message);
-			dbus_error_free (&error);
-		} else {
-			tracker_error ("Could not connect to system bus");
-		}			
-
-		return NULL;
-	}
-
-  	dbus_connection_setup_with_g_main (connection, NULL);
-
-	ctx = libhal_ctx_new ();
-		
-	if (!ctx) {
-		tracker_error ("Could not create HAL context");
-		return NULL;
-	}
-
-  	
-
-  	libhal_ctx_set_dbus_connection (ctx, connection);
-
-	if (!libhal_ctx_init (ctx, &error)) {
-
-		if (dbus_error_is_set (&error)) {
-			tracker_error ("Could not initialise HAL connection due to %s", error.message);
-			dbus_error_free (&error);
-		} else {
-			tracker_error ("Could not initialise HAL connection -is hald running?");
-		}
-
-	 	libhal_ctx_free (ctx);
-
-		return NULL;
-	}
-  
-  	devices = libhal_find_device_by_capability (ctx, AC_ADAPTER, &num, &error);
-
-	if (dbus_error_is_set (&error)) {
-		tracker_error ("Could not get HAL devices due to %s", error.message);
-		dbus_error_free (&error);
-		return NULL;
-	}
-
-  	if (!devices || !devices[0]) {
-		tracker->pause_battery = FALSE;
-		tracker->battery_udi = NULL;
-		g_print ("none found\n");
-		return ctx;
-	}
-  
-	/* there should only be one ac-adaptor so use first one */
-	tracker->battery_udi = g_strdup (devices[0]);
-	g_print ("found %s\n", devices[0]);
-
-	libhal_ctx_set_device_property_modified (ctx, property_callback);
-
-	libhal_device_add_property_watch (ctx, devices[0], &error);
-	if (dbus_error_is_set (&error)) {
-		tracker_error ("Could not set watch on HAL device %s due to %s", devices[0], error.message);
-		dbus_error_free (&error);
-		return NULL;
-	}
-
-
-	tracker->pause_battery = !libhal_device_get_property_bool (ctx, tracker->battery_udi, BATTERY_OFF, NULL);
-
-	if (tracker->pause_battery) {
-		tracker_log ("system is on battery");
-	} else {
-		tracker_log ("system is on AC power");
-	}
-
-  	dbus_free_string_array (devices);
-
-  	return ctx;
-
-}
-
-#endif /* HAVE_HAL */
-
-
-gboolean
-tracker_die ()
-{
-	tracker_error ("trackerd has failed to exit on time - terminating...");
-	exit (EXIT_FAILURE);
-}
-
-
-void
-free_file_change (FileChange **user_data)
-{
-	FileChange *change = *user_data;
-	g_free (change->uri);
-	change->uri = NULL;
-	change = NULL;
-}
-
-static void
-free_file_change_queue (gpointer data, gpointer user_data)
-{
-	FileChange *change = (FileChange *)data;
-	free_file_change (&change);
-}
-
-
-static void
-reset_blacklist_file (char *uri)
-{
-
-	char *parent = g_path_get_dirname (uri);
-	if (!parent) return;
-
-	char *parent_name = g_path_get_basename (parent);
-	if (!parent_name) return;
-	
-	char *parent_path = g_path_get_dirname (parent);
-	if (!parent_path) return;	
-	
-	tracker_log ("resetting black list file %s", uri);
-	
-	/* reset mtime on parent folder of all outstanding black list files so they get indexed when next restarted */
-	tracker_exec_proc (main_thread_db_con, "UpdateFileMTime", 3, "0", parent_path, parent_name);
-	
-	g_free (parent);
-	g_free (parent_name);
-	g_free (parent_path);		 
-	 
-	
-}
-
-gboolean
-tracker_do_cleanup (const gchar *sig_msg)
-{
-	tracker->status = STATUS_SHUTDOWN;
-
-	if (sig_msg) {
-		tracker_log ("Received signal '%s' so now shutting down", sig_msg);
-
-		tracker_print_object_allocations ();
-	}
-
-	/* set kill timeout */
-	g_timeout_add_full (G_PRIORITY_LOW,
-	     		    20000,
- 	    		    (GSourceFunc) tracker_die,
-	     		    NULL, NULL
-	   		    );
-
-
-	/* stop threads from further processing of events if possible */
-
-	tracker->in_flush = TRUE;
-
-	//set_update_count (main_thread_db_con, tracker->update_count);
-
-	/* wait for files thread to sleep */
-	while (!g_mutex_trylock (tracker->files_signal_mutex)) {
-		g_usleep (100);
-	}
-
-	g_mutex_unlock (tracker->files_signal_mutex);
-
-	while (!g_mutex_trylock (tracker->metadata_signal_mutex)) {
-		g_usleep (100);
-	}
-
-	g_mutex_unlock (tracker->metadata_signal_mutex);
-
-	tracker_log ("shutting down threads");
-
-	/* send signals to each thread to wake them up and then stop them */
-
-	
-	tracker->shutdown = TRUE;
-	
-	g_mutex_lock (tracker->request_signal_mutex);
-	g_cond_signal (tracker->request_thread_signal);
-	g_mutex_unlock (tracker->request_signal_mutex);
-
-	g_mutex_lock (tracker->metadata_signal_mutex);
-	g_cond_signal (tracker->metadata_thread_signal);
-	g_mutex_unlock (tracker->metadata_signal_mutex);
-
-	g_mutex_unlock (tracker->files_check_mutex);
-
-	g_mutex_lock (tracker->files_signal_mutex);
-	g_cond_signal (tracker->file_thread_signal);
-	g_mutex_unlock (tracker->files_signal_mutex);
-
-
-	/* wait for threads to exit and unlock check mutexes to prevent any deadlocks*/
-
-	g_mutex_unlock (tracker->request_check_mutex);
-	g_mutex_lock (tracker->request_stopped_mutex);
-
-	g_mutex_unlock (tracker->metadata_check_mutex);
-	g_mutex_lock (tracker->metadata_stopped_mutex);
-
-	g_mutex_unlock (tracker->files_check_mutex);
-	g_mutex_lock (tracker->files_stopped_mutex);
-
-
-	tracker_indexer_close (tracker->file_index);
-	tracker_indexer_close (tracker->file_update_index);
-	tracker_indexer_close (tracker->email_index);
-
-	tracker_email_end_email_watching ();
-
-	/* reset integrity status as threads have closed cleanly */
-	tracker_db_set_option_int (main_thread_db_con, "IntegrityCheck", 0);
-	
-	
-	/* reset black list files */
-	g_slist_foreach (tracker->tmp_black_list, (GFunc) reset_blacklist_file, NULL);
-
-	tracker_db_close (main_thread_db_con);
-
-	/* This must be called after all other db functions */
-	tracker_db_finalize ();
-
-	
-	if (tracker->reindex) {
-		tracker_remove_dirs (tracker->data_dir);
-		g_mkdir_with_parents (tracker->data_dir, 00755);
-	}
-
-	tracker_debug ("Shutting down main thread");
-
-	tracker_log_term ();
-
-	/* remove sys tmp directory */
-	if (tracker->sys_tmp_root_dir) {
-		tracker_remove_dirs (tracker->sys_tmp_root_dir);
-	}
-
-	/* remove file change queue */
-	if (tracker->file_change_queue) {
-		g_queue_foreach (tracker->file_change_queue,
-				 free_file_change_queue, NULL);
-		g_queue_free (tracker->file_change_queue);
-		tracker->file_change_queue = NULL;
-	}
-
-        if (tracker->language) {
-                tracker_language_free (tracker->language);
-        }
-
-        if (tracker->config) {
-                g_object_unref (tracker->config);
-        }
-
-	g_main_loop_quit (tracker->loop);
-
-	exit (EXIT_SUCCESS);
-
-	return FALSE;
-}
-
-
-static void
-check_dir_for_deletions (DBConnection *db_con, const gchar *uri)
-{
-	gchar **files, **files_p;
-
-	/* check for any deletions*/
-	files = tracker_db_get_files_in_folder (db_con, uri);
-
-	for (files_p = files; *files_p; files_p++) {
-		gchar *str = *files_p;
-
-		if (!tracker_file_is_valid (str)) {
-                        FileInfo *info;
-			info = tracker_create_file_info (str, 1, 0, 0);
-			info = tracker_db_get_file_info (db_con, info);
-
-			if (!info->is_directory) {
-				delete_file (db_con, info);
-			} else {
-				delete_directory (db_con, info);
-			}
-			tracker_free_file_info (info);
-		}
-	}
-
-	g_strfreev (files);
-}
-
-
-static void
-schedule_dir_check (const gchar *uri, DBConnection *db_con)
-{
-	if (!tracker->is_running) {
-		return;
-	}
-
-	g_return_if_fail (tracker_check_uri (uri));
-	g_return_if_fail (db_con);
-
-	tracker_db_insert_pending_file (db_con, 0, uri, NULL, "unknown", 0, TRACKER_ACTION_DIRECTORY_REFRESH, TRUE, FALSE, -1);
-}
-
-
-static void
-add_dirs_to_list (GSList *my_list, DBConnection *db_con)
-{
-	if (!tracker->is_running) {
-		return;
-	}
-
-	GSList *dir_list = NULL, *lst;
-
-	for (lst = my_list; lst; lst = lst->next) {
-                gchar *dir = lst->data;
-		if (dir) {
-			dir_list = g_slist_prepend (dir_list, g_strdup (dir));
-		}
-	}
-
-	/* add sub directories breadth first recursively to avoid running out of file handles */
-	while (dir_list) {
-                GSList *file_list = NULL, *tmp;
-
-		for (tmp = dir_list; tmp; tmp = tmp->next) {
-                        gchar *str = tmp->data;
-
-			if (str && !tracker_file_is_no_watched (str)) {
-				tracker->dir_list = g_slist_prepend (tracker->dir_list, g_strdup (str));
-			}
-		}
-
-		g_slist_foreach (dir_list, (GFunc) tracker_get_dirs, &file_list);
-		g_slist_foreach (dir_list, (GFunc) g_free, NULL);
-		g_slist_free (dir_list);
-
-		dir_list = file_list;
-	}
-}
-
-
-static void
-add_dirs_to_watch_list (GSList *dir_list, gboolean check_dirs, DBConnection *db_con)
-{
-	if (!tracker->is_running) {
-		return;
-	}
-
-	/* add sub directories breadth first recursively to avoid running out of file handles */
-	while (dir_list) {
-                GSList *file_list = NULL, *tmp;
-
-		for (tmp = dir_list; tmp; tmp = tmp->next) {
-                        gchar *str = tmp->data;
-
-			if (str && !tracker_file_is_no_watched (str)) {
-
-				tracker->dir_list = g_slist_prepend (tracker->dir_list, g_strdup (str));
-
-				if (!tracker_config_get_enable_watches (tracker->config) || 
-                                    tracker_file_is_crawled (str)) {
-                                        continue;
-                                }
-
-				if ( ((tracker_count_watch_dirs () + g_slist_length (dir_list)) < tracker->watch_limit)) {
-
-					if (!tracker_add_watch_dir (str, db_con) && tracker_is_directory (str)) {
-						tracker_debug ("Watch failed for %s", str);
-					}
-				}
-			}
-		}
-
-		g_slist_foreach (dir_list, (GFunc) tracker_get_dirs, &file_list);
-		g_slist_foreach (dir_list, (GFunc) g_free, NULL);
-		g_slist_free (dir_list);
-
-		dir_list = file_list;
-	}
-}
-
-
-static gboolean
-watch_dir (const gchar* dir, DBConnection *db_con)
-{
-	gchar *dir_utf8;
-
-	if (!tracker->is_running) {
-		return TRUE;
-	}
-
-	if (!dir) {
-		return FALSE;
-	}
-
-	if (!g_utf8_validate (dir, -1, NULL)) {
-
-		dir_utf8 = g_filename_to_utf8 (dir, -1, NULL,NULL,NULL);
-		if (!dir_utf8) {
-			tracker_error ("ERROR: watch_dir could not be converted to utf8 format");
-			return FALSE;
-		}
-	} else {
-		dir_utf8 = g_strdup (dir);
-	}
-
-	if (!tracker_file_is_valid (dir_utf8)) {
-		g_free (dir_utf8);
-		return FALSE;
-	}
-
-	if (!tracker_is_directory (dir_utf8)) {
-		g_free (dir_utf8);
-		return FALSE;
-	}
-
-	if (tracker_file_is_crawled (dir_utf8)) {
-		g_free (dir_utf8);
-		return FALSE;
-	}
-
-	if (!tracker_file_is_no_watched (dir_utf8)) {
-		GSList *mylist = NULL;
-
-		mylist = g_slist_prepend (mylist, dir_utf8);
-
-		add_dirs_to_watch_list (mylist, TRUE, db_con);
-	}
-
-	return TRUE;
-}
-
-
-static void
-signal_handler (gint signo)
-{
-	static gboolean in_loop = FALSE;
-
-  	/* die if we get re-entrant signals handler calls */
-	if (in_loop) {
-		exit (EXIT_FAILURE);
-	}
-
-  	switch (signo) {
-
-  		case SIGSEGV:
-
-			/* we are screwed if we get this so exit immediately! */
-			exit (EXIT_FAILURE);
-
-	  	case SIGBUS:
-		case SIGILL:
-  		case SIGFPE:
-  		case SIGPIPE:
-		case SIGABRT:
-		case SIGTERM:
-		case SIGINT:
-
-		  	in_loop = TRUE;
-
-			tracker->is_running = FALSE;
-			tracker_end_watching ();
-
-			g_timeout_add_full (G_PRIORITY_LOW,
-			     		    1,
-		 	    		    (GSourceFunc) tracker_do_cleanup,
-			     		    g_strdup (g_strsignal (signo)), NULL
-			   		    );
-
-
-		default:
-			if (g_strsignal (signo)) {
-	   			tracker_log ("Received signal %s ", g_strsignal (signo));
-			}
-			break;
-  	}
-}
-
-
-
-static void
-delete_file (DBConnection *db_con, FileInfo *info)
-{
-	/* info struct may have been deleted in transit here so check if still valid and intact */
-	g_return_if_fail (tracker_file_info_is_valid (info));
-
-	/* if we dont have an entry in the db for the deleted file, we ignore it */
-	if (info->file_id == 0) {
-		return;
-	}
-
-	tracker_db_delete_file (db_con, info->file_id);
-
-	tracker_log ("deleting file %s", info->uri);
-}
-
-
-static void
-delete_directory (DBConnection *db_con, FileInfo *info)
-{
-	/* info struct may have been deleted in transit here so check if still valid and intact */
-	g_return_if_fail (tracker_file_info_is_valid (info));
-
-	/* if we dont have an entry in the db for the deleted directory, we ignore it */
-	if (info->file_id == 0) {
-		return;
-	}
-
-	tracker_db_delete_directory (db_con, info->file_id, info->uri);
-
-	tracker_remove_watch_dir (info->uri, TRUE, db_con);
-
-	tracker_log ("deleting directory %s and subdirs", info->uri);
-}
-
-
-static void
-schedule_file_check (const gchar *uri, DBConnection *db_con)
-{
-	if (!tracker->is_running) {
-		return;
-	}
-
-	g_return_if_fail (tracker_check_uri (uri));
-	g_return_if_fail (db_con);
-
-	/* keep mainloop responsive */
-	my_yield ();
-
-	if (!tracker_is_directory (uri)) {
-		tracker_db_insert_pending_file (db_con, 0, uri, NULL, "unknown", 0, TRACKER_ACTION_CHECK, 0, FALSE, -1);
-	} else {
-		schedule_dir_check (uri, db_con);
-	}
-}
-
-
-static inline void
-queue_dir (const gchar *uri)
-{
-	FileInfo *info = tracker_create_file_info (uri, TRACKER_ACTION_DIRECTORY_CHECK, 0, 0);
-	g_async_queue_push (tracker->file_process_queue, info);
-}
-
-
-static inline void
-queue_file (const gchar *uri)
-{
-	FileInfo *info = tracker_create_file_info (uri, TRACKER_ACTION_CHECK, 0, 0);
-	g_async_queue_push (tracker->file_process_queue, info);
-}
-
-
-static void
-check_directory (const gchar *uri)
-{
-	GSList *file_list = NULL;
-
-	if (!tracker->is_running) {
-		return;
-	}
-
-	g_return_if_fail (tracker_check_uri (uri));
-	g_return_if_fail (tracker_is_directory (uri));
-
-	file_list = tracker_get_files (uri, FALSE);
-	tracker_debug ("checking %s for %d files", uri, g_slist_length (file_list));
-
-	g_slist_foreach (file_list, (GFunc) queue_file, NULL);
-	g_slist_foreach (file_list, (GFunc) g_free, NULL);
-	g_slist_free (file_list);
-
-	queue_file (uri);
-
-	if (tracker->index_status != INDEX_EMAILS) tracker->folders_processed++;
-}
-
-
-
-static void
-scan_directory (const gchar *uri, DBConnection *db_con)
-{
-	GSList *file_list;
-
-	if (!tracker->is_running) {
-		return;
-	}
-
-	g_return_if_fail (db_con);
-	g_return_if_fail (tracker_check_uri (uri));
-	g_return_if_fail (tracker_is_directory (uri));
-
-	/* keep mainloop responsive */
-	my_yield ();
-
-	file_list = tracker_get_files (uri, FALSE);
-	tracker_debug ("scanning %s for %d files", uri, g_slist_length(file_list));
-
-	g_slist_foreach (file_list, (GFunc) schedule_file_check, db_con);
-	g_slist_foreach (file_list, (GFunc) g_free, NULL);
-	g_slist_free (file_list);
-
-	/* recheck directory to update its mtime if its changed whilst scanning */
-	schedule_dir_check (uri, db_con);
-	tracker_debug ("finished scanning");
-}
-
-
-/* determines whether an action applies to a file or a directory */
-static void
-verify_action (FileInfo *info)
-{
-	if (info->action == TRACKER_ACTION_CHECK) {
-		if (info->is_directory) {
-			info->action = TRACKER_ACTION_DIRECTORY_CHECK;
-			info->counter = 0;
-		} else {
-			info->action = TRACKER_ACTION_FILE_CHECK;
-		}
-
-	} else {
-		if (info->action == TRACKER_ACTION_DELETE || info->action == TRACKER_ACTION_DELETE_SELF) {
-
-			/* we are in trouble if we cant find the deleted uri in the DB - assume its a directory (worst case) */
-			if (info->file_id == 0) {
-				info->is_directory = TRUE;
-			}
-
-			info->counter = 0;
-			if (info->is_directory) {
-				info->action = TRACKER_ACTION_DIRECTORY_DELETED;
-			} else {
-				info->action = TRACKER_ACTION_FILE_DELETED;
-			}
-		} else {
-			if (info->action == TRACKER_ACTION_MOVED_FROM) {
-				info->counter = 1;
-				if (info->is_directory) {
-					info->action = TRACKER_ACTION_DIRECTORY_MOVED_FROM;
-				} else {
-					info->action = TRACKER_ACTION_FILE_MOVED_FROM;
-				}
-
-			} else {
-
-				if (info->action == TRACKER_ACTION_CREATE) {
-					if (info->is_directory) {
-						info->action = TRACKER_ACTION_DIRECTORY_CREATED;
-						info->counter = 0; /* do not reschedule a created directory */
-					} else {
-						info->action = TRACKER_ACTION_FILE_CREATED;
-					}
-
-				} else {
-					if (info->action == TRACKER_ACTION_FILE_MOVED_TO) {
-						info->counter = 0;
-						if (info->is_directory) {
-							info->action = TRACKER_ACTION_DIRECTORY_MOVED_TO;
-						} else {
-							info->action = TRACKER_ACTION_FILE_MOVED_TO;
-						}
-					}
-				}
-			}
-		}
-	}
-}
-
-
-static void
-index_entity (DBConnection *db_con, FileInfo *info)
-{
-	gchar *service_info;
-
-	g_return_if_fail (info);
-	g_return_if_fail (tracker_check_uri (info->uri));
-
-	if (!tracker_file_is_valid (info->uri)) {
-		//tracker_debug ("Warning - file %s in not valid or could not be read - abandoning index on this file", info->uri);
-		return;
-	}
-
-	if (!info->is_directory) {
-		/* sleep to throttle back indexing */
-		tracker_throttle (100);
-	}
-
-	service_info = tracker_get_service_for_uri (info->uri);
-
-	if (!service_info) {
-		tracker_error ("ERROR: cannot find service for path %s", info->uri);
-		return;
-	}
-
-	//tracker_debug ("indexing %s with service %s", info->uri, service_info);
-
-	gchar *str = g_utf8_strdown  (service_info, -1);
-
-	ServiceDef *def = g_hash_table_lookup (tracker->service_table, str);
-
-	g_free (str);
-
-	if (!def) {
-		if (service_info) {
-			tracker_error ("ERROR: unknown service %s", service_info);
-		} else {
-			tracker_error ("ERROR: unknown service");
-		}
-		g_free (service_info);
-		return;
-	}
-
-	if (info->is_directory) {
-		info->is_hidden = !def->show_service_directories;
-		tracker_db_index_file (db_con, info, NULL, NULL);
-		g_free (service_info);
-		return;
-
-	} else {
-		info->is_hidden = !def->show_service_files;
-	}
-
-
-	if (g_str_has_suffix (service_info, "Emails")) {
-		if (!tracker_email_index_file (db_con->emails, info, service_info)) {
-			g_free (service_info);
-			return;
-		}
-
-	} else if (strcmp (service_info, "Files") == 0) {
-		tracker_db_index_file (db_con, info, NULL, NULL);
-
-        } else if (strcmp (service_info, "WebHistory") ==0 ) {
-                tracker_db_index_webhistory (db_con, info);
-
-	} else if (g_str_has_suffix (service_info, "Conversations")) {
-		tracker_db_index_conversation (db_con, info);
-
-	} else if (strcmp (service_info, "Applications") == 0) {
-		tracker_db_index_application (db_con, info);
-
-	} else {
-		tracker_db_index_service (db_con, info, NULL, NULL, NULL, FALSE, TRUE, TRUE, TRUE);
-	}
-
-	g_free (service_info);
-}
-
-
-static inline void
-process_directory_list (DBConnection *db_con, GSList *list, gboolean recurse)
-{
-	tracker->dir_list = NULL;
-
-	if (!list) {
-		return;
-	}
-
-	g_slist_foreach (list, (GFunc) watch_dir, db_con);
-
-	g_slist_foreach (list, (GFunc) schedule_dir_check, db_con);
-
-	if (recurse && tracker->dir_list) {
-		g_slist_foreach (tracker->dir_list, (GFunc) schedule_dir_check, db_con);
-	}
-
-	if (tracker->dir_list) {
-		g_slist_foreach (tracker->dir_list, (GFunc) g_free, NULL);
-		g_slist_free (tracker->dir_list);
-                tracker->dir_list = NULL;
-	}
-}
-
-
-static void
-process_files_thread (void)
-{
-	sigset_t     signal_set;
-
-	DBConnection *db_con;
-
-	GSList	     *moved_from_list; /* list to hold moved_from events whilst waiting for a matching moved_to event */
-	gboolean pushed_events, first_run;
-
-        /* block all signals in this thread */
-        sigfillset (&signal_set);
-#ifndef OS_WIN32
-        pthread_sigmask (SIG_BLOCK, &signal_set, NULL);
-#endif
-
-	g_mutex_lock (tracker->files_signal_mutex);
-	g_mutex_lock (tracker->files_stopped_mutex);
-
-	/* set thread safe DB connection */
-	tracker_db_thread_init ();
-
-	tracker->index_db = tracker_db_connect_all (TRUE);
-
-	tracker->index_status = INDEX_CONFIG;
-
-	pushed_events = FALSE;
-
-	first_run = TRUE;
-
-	moved_from_list = NULL;
-
-	tracker_log ("starting indexing...");
-
-	tracker->index_time_start = time (NULL);
-
-	while (TRUE) {
-		FileInfo *info;
-		gboolean need_index;
-
-		need_index = FALSE;
-
-		db_con = tracker->index_db;
-
-		if (!tracker_cache_process_events (db_con, TRUE) ) {
-			tracker->status = STATUS_SHUTDOWN;
-			tracker_dbus_send_index_status_change_signal ();
-			break;	
-		}
-
-		if (tracker->status != STATUS_INDEXING) {
-			tracker->status = STATUS_INDEXING;
-			tracker_dbus_send_index_status_change_signal ();
-		}
-		
-				
-		info = g_async_queue_try_pop (tracker->file_process_queue);
-
-		/* check pending table if we haven't got anything */
-		if (!info) {
-			gchar ***res;
-			gint  k;
-
-			/* set mutex to indicate we are in "check" state */
-			g_mutex_lock (tracker->files_check_mutex);
-
-
-			if (tracker_db_has_pending_files (db_con)) {
-				g_mutex_unlock (tracker->files_check_mutex);
-
-			} else {
-
-				/* check dir_queue in case there are directories waiting to be indexed */
-
-				if (g_async_queue_length (tracker->dir_queue) > 0) {
-
-					
-
-					gchar *uri = g_async_queue_try_pop (tracker->dir_queue);
-
-					if (uri) {
-						
-						check_directory (uri);
-
-						g_free (uri);
-
-						g_mutex_unlock (tracker->files_check_mutex);
-
-						continue;
-					}
-				}
-
-				if (tracker->index_status != INDEX_FINISHED) {
-
-					g_mutex_unlock (tracker->files_check_mutex);
-
-					switch (tracker->index_status) {
-
-
-						case INDEX_CONFIG:
-							tracker_log ("Starting config indexing");
-							break;
-
-						case INDEX_APPLICATIONS: {
-								GSList *list;
-
-								tracker_db_start_index_transaction (db_con);
-								tracker_db_start_transaction (db_con->cache);
-								tracker_log ("Starting application indexing");
-
-								tracker_applications_add_service_directories ();
-
-								list = tracker_get_service_dirs ("Applications");
-
-								tracker_add_root_directories (list);
-
-								process_directory_list (db_con, list, FALSE);
-
-								tracker_db_end_transaction (db_con->cache);
-
-								g_slist_free (list);
-										
-			
-
-							}
-							break;
-
-						case INDEX_FILES: {
-                                                                GSList *watch_directory_roots;
-                                                                GSList *no_watch_directory_roots;
-                                                                gint    initial_sleep;
-
-                                                                initial_sleep = tracker_config_get_initial_sleep (tracker->config);
-
-								/* sleep for N secs before watching/indexing any of the major services */
-								tracker_log ("Sleeping for %d secs...", 
-                                                                             initial_sleep);
-								tracker->pause_io = TRUE;
-								tracker_dbus_send_index_status_change_signal ();
-								tracker_db_end_index_transaction (db_con);
-								
-
-								while (initial_sleep > 0) {
-									g_usleep (1000 * 1000);
-
-									initial_sleep --;
-
-									if (!tracker->is_running || tracker->shutdown) {
-										break;
-									}		
-								}
-
-								tracker->pause_io = FALSE;
-								tracker_dbus_send_index_status_change_signal ();
-
-								tracker_log ("Starting file indexing...");
-								tracker->dir_list = NULL;
-
-								tracker_db_start_index_transaction (db_con);
-								
-								/* delete all stuff in the no watch dirs */
-
-                                                                watch_directory_roots = 
-                                                                        tracker_config_get_watch_directory_roots (tracker->config);
-
-                                                                no_watch_directory_roots = 
-                                                                        tracker_config_get_no_watch_directory_roots (tracker->config);
-
-								if (no_watch_directory_roots) {
-									GSList *l;
-
-									tracker_log ("Deleting entities in no watch directories...");
-
-									for (l = no_watch_directory_roots; l; l = l->next) {
-                                                                                guint32 f_id = tracker_db_get_file_id (db_con, l->data);
-
-											if (f_id > 0) {
-                                                                                        tracker_db_delete_directory (db_con, f_id, l->data);
-										}
-									}
-								}
-
-								if (!watch_directory_roots) {
-									break;
-								}
-
-								tracker_db_start_transaction (db_con->cache);
-
-								tracker_add_root_directories (watch_directory_roots);
-
-								/* index watched dirs first */
-								g_slist_foreach (watch_directory_roots, 
-                                                                                 (GFunc) watch_dir, 
-                                                                                 db_con);
-
-								g_slist_foreach (tracker->dir_list, 
-                                                                                 (GFunc) schedule_dir_check, 
-                                                                                 db_con);
-
-								if (tracker->dir_list) {
-									g_slist_foreach (tracker->dir_list, 
-                                                                                         (GFunc) g_free, 
-                                                                                         NULL);
-									g_slist_free (tracker->dir_list);
-									tracker->dir_list = NULL;
-								}
-
-								g_slist_foreach (watch_directory_roots, 
-                                                                                 (GFunc) schedule_dir_check, 
-                                                                                 db_con);
-
-								if (tracker->dir_list) {
-									g_slist_foreach (tracker->dir_list, 
-                                                                                         (GFunc) g_free, 
-                                                                                         NULL);
-									g_slist_free (tracker->dir_list);
-									tracker->dir_list = NULL;
-								}
-
-								tracker_db_end_transaction (db_con->cache);
-
-								tracker_dbus_send_index_progress_signal ("Files", "");
-			
-							}
-							break;
-
-						case INDEX_CRAWL_FILES: {
-                                                        GSList *crawl_directory_roots;
-                                                        
-								tracker_log ("Indexing directories to be crawled...");
-								tracker->dir_list = NULL;
-
-                                                                crawl_directory_roots = 
-                                                                        tracker_config_get_crawl_directory_roots (tracker->config);
-
-								if (!crawl_directory_roots) {
-									break;
-								}
-
-								tracker_db_start_transaction (db_con->cache);
-
-								tracker_add_root_directories (crawl_directory_roots);
-
-								add_dirs_to_list (crawl_directory_roots, db_con);
-
-								g_slist_foreach (tracker->dir_list, (GFunc) schedule_dir_check, db_con);
-
-								if (tracker->dir_list) {
-									g_slist_foreach (tracker->dir_list, (GFunc) g_free, NULL);
-									g_slist_free (tracker->dir_list);
-									tracker->dir_list = NULL;
-								}
-
-								g_slist_foreach (crawl_directory_roots, 
-                                                                                 (GFunc) schedule_dir_check, 
-                                                                                 db_con);
-
-								if (tracker->dir_list) {
-									g_slist_foreach (tracker->dir_list, (GFunc) g_free, NULL);
-									g_slist_free (tracker->dir_list);
-									tracker->dir_list = NULL;
-								}
-
-								tracker_db_end_transaction (db_con->cache);
-							}
-							break;
-
-						case INDEX_CONVERSATIONS: {
-								gchar    *gaim, *purple;
-								gboolean has_logs = FALSE;
-								GSList   *list    = NULL;
-
-		
-								gaim = g_build_filename (g_get_home_dir(), ".gaim", "logs", NULL);
-								purple = g_build_filename (g_get_home_dir(), ".purple", "logs", NULL);
-
-								if (tracker_file_is_valid (gaim)) {
-
-									has_logs = TRUE;
-
-									tracker_add_service_path ("GaimConversations", gaim);
-
-									list = g_slist_prepend (NULL, gaim);
-								}
-
-								if (tracker_file_is_valid (purple)) {
-
-									has_logs = TRUE;
-
-									tracker_add_service_path ("GaimConversations", purple);
-
-									list = g_slist_prepend (NULL, purple);
-								}
-
-								if (has_logs) {
-									tracker_log ("Starting chat log indexing...");
-									tracker_db_start_transaction (db_con->cache);
-									tracker_add_root_directories (list);
-			 						process_directory_list (db_con, list, TRUE);
-									tracker_db_end_transaction (db_con->cache);
-									g_slist_free (list);
-								}
-
-								g_free (gaim);
-								g_free (purple);
-
-								
-							}
-							break;
-
-
-					        case INDEX_WEBHISTORY: {
-
-                                                                gchar *firefox_dir;
-                                                                GSList *list = NULL;
-                                                                firefox_dir = g_build_filename(g_get_home_dir(),".xesam/Firefox/ToIndex",NULL);
-                                                                if (tracker_file_is_valid(firefox_dir)) {
-                                                                     list = g_slist_prepend( NULL, firefox_dir);
- 
-                                                                     tracker_log("Starting firefox web history indexing...");
-                                                                     tracker_add_service_path("WebHistory",firefox_dir);
-
-							             tracker_db_start_transaction (db_con->cache);		
-                                                                     tracker_add_root_directories(list);
-                                                                     process_directory_list(db_con,list, TRUE);
-                                                                     tracker_db_end_transaction (db_con->cache);
-                                                                     g_slist_free(list);
-                                         
-                                                                 }
-                                                        	g_free(firefox_dir);
-                                                        }
-                                                        break;
-
-						case INDEX_EXTERNAL:
-							break;
-
-
-						case INDEX_EMAILS:  {
-
-								tracker_db_end_index_transaction (db_con);
-								tracker_cache_flush_all ();
-								
-								tracker_indexer_merge_indexes (INDEX_TYPE_FILES);
-								
-								if (tracker->shutdown) break;
-								
-								tracker->index_status = INDEX_EMAILS;
-
-								tracker_dbus_send_index_progress_signal ("Emails", "");
-
-								if (tracker->word_update_count > 0) {
-									tracker_indexer_apply_changes (tracker->file_index, tracker->file_update_index, TRUE);
-								}
-
-								tracker_db_start_index_transaction (db_con);
-
-                                                                gboolean index_evolution_emails;
-                                                                gboolean index_kmail_emails;
-                                                                gboolean index_thunderbird_emails;
-
-                                                                index_evolution_emails = tracker_config_get_index_evolution_emails (tracker->config);
-                                                                index_kmail_emails = tracker_config_get_index_kmail_emails (tracker->config);
-                                                                index_thunderbird_emails = tracker_config_get_index_thunderbird_emails (tracker->config);
-                                                                
-								if (index_evolution_emails ||
-                                                                    index_kmail_emails ||
-                                                                    index_thunderbird_emails) {
-									tracker_email_add_service_directories (db_con->emails);
-									tracker_log ("Starting email indexing...");
-
-									tracker_db_start_transaction (db_con->cache);
-
-									if (index_evolution_emails) {
-										GSList *list = tracker_get_service_dirs ("EvolutionEmails");
-										tracker_add_root_directories (list);
-										process_directory_list (db_con, list, TRUE);
-										g_slist_free (list);
-
-										/* if initial indexing has not finished reset mtime on all email stuff so they are rechecked */
-
-										if (tracker_db_get_option_int (db_con->common, "InitialIndex") == 1) {
-
-											char *sql = g_strdup_printf ("update Services set mtime = 0 where path like '%s/.evolution/%s'", g_get_home_dir (), "%");
-
-											tracker_exec_sql (db_con, sql);
-
-											g_free (sql);
-										}
-
-									}
-
-									if (index_kmail_emails) {
-										GSList *list = tracker_get_service_dirs ("KMailEmails");
-										tracker_add_root_directories (list);
-										process_directory_list (db_con, list, TRUE);
-										g_slist_free (list);
-									}
-                                                                        
-                                                                        if (index_thunderbird_emails) {
-										GSList *list = tracker_get_service_dirs ("ThunderbirdEmails");
-										tracker_add_root_directories (list);
-										process_directory_list (db_con, list, TRUE);
-										g_slist_free (list);
-									}
-
-									tracker_db_end_transaction (db_con->cache);
-							
-								}
-
-							}
-							break;
-				
-						case INDEX_FINISHED:
-							break;
-
-
-					}
-
-					tracker->index_status++;
-
-					continue;
-				}
-
-				tracker_db_end_index_transaction (db_con);
-
-				tracker_cache_flush_all ();
-
-				tracker_db_refresh_all (db_con);
-
-				tracker_indexer_merge_indexes (INDEX_TYPE_FILES);
-				
-				if (tracker->shutdown) break;
-								
-
-				if (tracker->word_update_count > 0) {
-					tracker_indexer_apply_changes (tracker->file_index, tracker->file_update_index, TRUE);
-				}
-
-				tracker_indexer_merge_indexes (INDEX_TYPE_EMAILS);
-
-				if (tracker->shutdown) break;
-
-				tracker->index_status = INDEX_FILES;
-				tracker_dbus_send_index_progress_signal ("Files","");
-				tracker->index_status = INDEX_FINISHED;
-
-				if (tracker->is_running && tracker->first_time_index) {
-
-					tracker->status = STATUS_OPTIMIZING;
-					
-					tracker->do_optimize = FALSE;
-					tracker->first_time_index = FALSE;
-					
-					tracker_dbus_send_index_finished_signal ();
-
-					tracker_db_set_option_int (db_con, "InitialIndex", 0);
-
-					tracker->update_count = 0;
-
-					tracker_log ("Updating database stats...please wait...");
-
-					tracker_db_start_transaction (db_con);
-					tracker_db_exec_no_reply (db_con, "ANALYZE");
-					tracker_db_end_transaction (db_con);
-
-					tracker_db_start_transaction (db_con->emails);
-					tracker_db_exec_no_reply (db_con->emails, "ANALYZE");
-					tracker_db_end_transaction (db_con->emails);
-		
-					tracker_log ("Finished optimizing. Waiting for new events...");
-				}
-
-				/* we have no stuff to process so sleep until awoken by a new signal */
-
-				tracker->status = STATUS_IDLE;
-				tracker_dbus_send_index_status_change_signal ();
-
-				g_cond_wait (tracker->file_thread_signal, tracker->files_signal_mutex);
-				g_mutex_unlock (tracker->files_check_mutex);
-
-				tracker->grace_period = 0;
-				
-
-				/* determine if wake up call is new stuff or a shutdown signal */
-				if (!tracker->shutdown) {
-					tracker_db_start_index_transaction (db_con);
-					continue;
-				} else {
-					break;
-				}
-			}
-
-			res = tracker_db_get_pending_files (db_con);
-
-			k = 0;
-			pushed_events = FALSE;
-
-			if (res) {
-				gchar **row;
-
-				tracker->status = STATUS_PENDING;
-
-				while ((row = tracker_db_get_row (res, k))) {
-					FileInfo	    *info_tmp;
-					TrackerChangeAction tmp_action;
-
-					if (!tracker->is_running) {
-						tracker_db_free_result (res);
-						break;
-					}
-
-					k++;
-
-					tmp_action = atoi (row[2]);
-
-					info_tmp = tracker_create_file_info (row[1], tmp_action, 0, WATCH_OTHER);
-					g_async_queue_push (tracker->file_process_queue, info_tmp);
-					pushed_events = TRUE;
-				}
-
-				tracker_db_free_result (res);
-			}
-
-			if (!tracker->is_running) {
-				continue;
-			}
-
-			tracker_db_remove_pending_files (db_con);
-
-			/* pending files are present but not yet ready as we are waiting til they stabilize
-                           so we should sleep for 100ms (only occurs when using FAM or inotify move/create) */
-			if (!pushed_events && (k == 0)) {
-				g_usleep (100000);
-			}
-
-			continue;
-		}
-
-
-		tracker->status = STATUS_INDEXING;
-
-		/* info struct may have been deleted in transit here so check if still valid and intact */
-		if (!tracker_file_info_is_valid (info)) {
-			continue;
-		}
-
-
-		if (info->file_id == 0 && info->action != TRACKER_ACTION_CREATE &&
-			    info->action != TRACKER_ACTION_DIRECTORY_CREATED && info->action != TRACKER_ACTION_FILE_CREATED) {
-
-       	                info = tracker_db_get_file_info (db_con, info);
-	
-			/* Get more file info if db retrieval returned nothing */
-			if (info->file_id == 0) {
-
-				info = tracker_get_file_info (info);
-
-				info->is_new = TRUE;
-
-			} else {
-				info->is_new = FALSE;
-			}
-		} else {
-			info->is_new = TRUE;
-		}
-
-		tracker_debug ("processing %s with action %s and counter %d ", info->uri, tracker_actions[info->action], info->counter);
-
-		/* preprocess ambiguous actions when we need to work out if its a file or a directory that the action relates to */
-		verify_action (info);
-
-		if (info->action != TRACKER_ACTION_DELETE &&
-		    info->action != TRACKER_ACTION_DIRECTORY_DELETED && info->action != TRACKER_ACTION_FILE_DELETED) {
-
-
-			if (!tracker_file_is_valid (info->uri) ) {
-
-				gboolean invalid = TRUE;
-
-				if (info->moved_to_uri) {
-					invalid = !tracker_file_is_valid (info->moved_to_uri);
-				}
-
-				if (invalid) {
-					tracker_free_file_info (info);
-					continue;
-				}
-			}
-
-			/* get file ID and other interesting fields from Database if not previously fetched or is newly created */
-
-			
-
-		} else {
-
-			if (info->action == TRACKER_ACTION_FILE_DELETED) {
-
-				delete_file (db_con, info);
-	
-				info = tracker_dec_info_ref (info);
-	
-				continue;
-
-			} else {
-				if (info->action == TRACKER_ACTION_DIRECTORY_DELETED) {
-				
-					delete_file (db_con, info);
-	
-					delete_directory (db_con, info);
-	
-					info = tracker_dec_info_ref (info);
-
-					continue;
-				}
-			}
-			
-
-		}	
-
-		
-
-		/* get latest file info from disk */
-		if (info->mtime == 0) {
-			info = tracker_get_file_info (info);
-		}
-
-		/* check if file needs indexing */
-		need_index = (info->mtime > info->indextime);
-
-		switch (info->action) {
-
-			case TRACKER_ACTION_FILE_CHECK:
-
-				break;
-
-			case TRACKER_ACTION_FILE_CHANGED:
-			case TRACKER_ACTION_FILE_CREATED:
-			case TRACKER_ACTION_WRITABLE_FILE_CLOSED:
-
-				need_index = TRUE;
-
-				break;
-
-			case TRACKER_ACTION_FILE_MOVED_FROM :
-
-				need_index = FALSE;
-                                tracker_log ("starting moving file %s to %s", info->uri, info->moved_to_uri);
-				tracker_db_move_file (db_con, info->uri, info->moved_to_uri);
-
-				break;
-
-			case TRACKER_ACTION_DIRECTORY_REFRESH:
-
-				if (need_index && !tracker_file_is_no_watched (info->uri)) {
-					g_async_queue_push (tracker->dir_queue, g_strdup (info->uri));
-
-					if (tracker->index_status != INDEX_EMAILS) tracker->folders_count++;
-				}
-				need_index = FALSE;
-
-				break;
-
-			case TRACKER_ACTION_DIRECTORY_CHECK:
-
-				if (need_index && !tracker_file_is_no_watched (info->uri)) {
-					g_async_queue_push (tracker->dir_queue, g_strdup (info->uri));
-					
-					if (info->indextime > 0) {
-						check_dir_for_deletions (db_con, info->uri);
-					}
-				}
-
-				break;
-
-
-			case TRACKER_ACTION_DIRECTORY_MOVED_FROM:
-					
-				tracker_db_move_directory (db_con, info->uri, info->moved_to_uri);
-				need_index = FALSE;
-
-				break;
-
-
-			case TRACKER_ACTION_DIRECTORY_CREATED:
-
-				need_index = TRUE;
-				tracker_debug ("processing created directory %s", info->uri);
-
-				/* schedule a rescan for all files in folder to avoid race conditions */
-				if (!tracker_file_is_no_watched (info->uri)) {
-					/* add to watch folders (including subfolders) */
-					watch_dir (info->uri, db_con);
-					scan_directory (info->uri, db_con);
-				} else {
-					tracker_debug ("blocked scan of directory %s as its in the no watch list", info->uri);
-				}
-
-				break;
-
-			default:
-				break;
-		}
-
-		if (need_index) {
-					
-
-			if (tracker_db_regulate_transactions (db_con, 250)) {
-				if (tracker_config_get_verbosity (tracker->config) == 1) {
-					tracker_log ("indexing #%d - %s", tracker->index_count, info->uri);
-				}
-
-				tracker_dbus_send_index_progress_signal ("Files", info->uri);
-			}
-
-			index_entity (db_con, info);
-			db_con = tracker->index_db;	
-		}
-
-		tracker_dec_info_ref (info);
-	}
-	xdg_mime_shutdown ();
-	tracker_db_close_all (db_con);
-
-
-	tracker_db_thread_end ();
-	g_mutex_unlock (tracker->files_stopped_mutex);
-}
-
-
-static void
-process_user_request_queue_thread (void)
-{
-	sigset_t     signal_set;
-	DBConnection *db_con;
-
-        /* block all signals in this thread */
-        sigfillset (&signal_set);
-#ifndef OS_WIN32
-        pthread_sigmask (SIG_BLOCK, &signal_set, NULL);
-#endif
-	g_mutex_lock (tracker->request_signal_mutex);
-	g_mutex_lock (tracker->request_stopped_mutex);
-
-	/* set thread safe DB connection */
-	tracker_db_thread_init ();
-
-	db_con = tracker_db_connect_all (FALSE);
-
-	tracker_db_prepare_queries (db_con);
-
-	while (TRUE) {
-		DBusRec	    *rec;
-		DBusMessage *reply;
-
-		/* make thread sleep if first part of the shutdown process has been activated */
-		if (!tracker->is_running) {
-
-			g_cond_wait (tracker->request_thread_signal, tracker->request_signal_mutex);
-
-			/* determine if wake up call is new stuff or a shutdown signal */
-			if (!tracker->shutdown) {
-				continue;
-			} else {
-				break;
-			}
-		}
-
-		/* lock check mutex to prevent race condition when a request is submitted after popping queue but prior to sleeping */
-		g_mutex_lock (tracker->request_check_mutex);
-
-		rec = g_async_queue_try_pop (tracker->user_request_queue);
-
-		if (!rec) {
-			g_cond_wait (tracker->request_thread_signal, tracker->request_signal_mutex);
-			g_mutex_unlock (tracker->request_check_mutex);
-
-			/* determine if wake up call is new stuff or a shutdown signal */
-			if (!tracker->shutdown) {
-				continue;
-			} else {
-				break;
-			}
-		}
-
-		/* thread will not sleep without another iteration so race condition no longer applies */
-		g_mutex_unlock (tracker->request_check_mutex);
-	
-
-		rec->user_data = db_con;
-
-		switch (rec->action) {
-
-			case DBUS_ACTION_PING:
-
-				reply = dbus_message_new_method_return (rec->message);
-
-				gboolean result = TRUE;
-
-				dbus_message_append_args (reply,
-				  			  DBUS_TYPE_BOOLEAN, &result,
-				  			  DBUS_TYPE_INVALID);
-
-				dbus_connection_send (rec->connection, reply, NULL);
-				dbus_message_unref (reply);
-
-				break;
-
-			case DBUS_ACTION_GET_STATS:
-
-				tracker_dbus_method_get_stats (rec);
-
-				break;
+static void
+property_callback (LibHalContext *ctx, const char *udi, const char *key,
+                   dbus_bool_t is_removed, dbus_bool_t is_added)
+{
 
-			case DBUS_ACTION_GET_SERVICES:
+	tracker_log ("HAL property change detected for udi %s and key %s", udi, key);
 
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
+	gboolean current_state = tracker->pause_battery;
 
-				tracker_dbus_method_get_services (rec);
+	if (strcmp (udi, tracker->battery_udi) == 0) {
 
-				break;
+		tracker->pause_battery = !libhal_device_get_property_bool (ctx, tracker->battery_udi, BATTERY_OFF, NULL);
+		
+		char *bat_state[2] = {"off","on"};
+		tracker_log ("Battery power is now %s", bat_state[tracker->pause_battery]);
 
-			case DBUS_ACTION_GET_VERSION:
+	} else {
+		return;
+	}
 
-				tracker_dbus_method_get_version (rec);
+	/* if we have come off battery power wakeup index thread */
+	if (current_state && !tracker->pause_battery) {
+		tracker_notify_file_data_available ();
+	}
 
-				break;
+}
 
-                        case DBUS_ACTION_GET_STATUS:
 
-				tracker_dbus_method_get_status (rec);
+LibHalContext *
+tracker_hal_init ()
+{
+	LibHalContext *ctx;
+  	char **devices;
+  	int num;
+	DBusError error;
+	DBusConnection *connection;
 
-                                break;
+	dbus_error_init (&error);
 
-                        case DBUS_ACTION_SET_BOOL_OPTION:
+	connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
 
-				tracker_dbus_method_set_bool_option (rec);
+	g_print ("starting HAL detection for ac adaptors...");
 
-                                break;
+	if (!connection) {
+		if (dbus_error_is_set (&error)) {
+			tracker_error ("Could not connect to system bus due to %s", error.message);
+			dbus_error_free (&error);
+		} else {
+			tracker_error ("Could not connect to system bus");
+		}			
 
-                        case DBUS_ACTION_SET_INT_OPTION:
+		return NULL;
+	}
 
-				tracker_dbus_method_set_int_option (rec);
+  	dbus_connection_setup_with_g_main (connection, NULL);
 
-                                break;
+	ctx = libhal_ctx_new ();
+		
+	if (!ctx) {
+		tracker_error ("Could not create HAL context");
+		return NULL;
+	}
 
-                        case DBUS_ACTION_SHUTDOWN:
                                            	
 
-				tracker_dbus_method_shutdown (rec);
+  	libhal_ctx_set_dbus_connection (ctx, connection);
 
-                                break;
+	if (!libhal_ctx_init (ctx, &error)) {
 
-                        case DBUS_ACTION_PROMPT_INDEX_SIGNALS:
+		if (dbus_error_is_set (&error)) {
+			tracker_error ("Could not initialise HAL connection due to %s", error.message);
+			dbus_error_free (&error);
+		} else {
+			tracker_error ("Could not initialise HAL connection -is hald running?");
+		}
 
-				tracker_dbus_method_prompt_index_signals (rec);
+	 	libhal_ctx_free (ctx);
 
-                                break;
+		return NULL;
+	}
 
-			case DBUS_ACTION_METADATA_GET:
+  	devices = libhal_find_device_by_capability (ctx, AC_ADAPTER, &num, &error);
 
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_metadata_get (rec);
+	if (dbus_error_is_set (&error)) {
+		tracker_error ("Could not get HAL devices due to %s", error.message);
+		dbus_error_free (&error);
+		return NULL;
+	}
 
-				break;
+  	if (!devices || !devices[0]) {
+		tracker->pause_battery = FALSE;
+		tracker->battery_udi = NULL;
+		g_print ("none found\n");
+		return ctx;
+	}
 
-			case DBUS_ACTION_METADATA_SET:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_metadata_set(rec);
+	/* there should only be one ac-adaptor so use first one */
+	tracker->battery_udi = g_strdup (devices[0]);
+	g_print ("found %s\n", devices[0]);
 
-				break;
+	libhal_ctx_set_device_property_modified (ctx, property_callback);
 
-			case DBUS_ACTION_METADATA_REGISTER_TYPE:
+	libhal_device_add_property_watch (ctx, devices[0], &error);
+	if (dbus_error_is_set (&error)) {
+		tracker_error ("Could not set watch on HAL device %s due to %s", devices[0], error.message);
+		dbus_error_free (&error);
+		return NULL;
+	}
 
-				tracker_dbus_method_metadata_register_type (rec);
 
-				break;
+	tracker->pause_battery = !libhal_device_get_property_bool (ctx, tracker->battery_udi, BATTERY_OFF, NULL);
 
-			case DBUS_ACTION_METADATA_GET_TYPE_DETAILS:
+	if (tracker->pause_battery) {
+		tracker_log ("system is on battery");
+	} else {
+		tracker_log ("system is on AC power");
+	}
 
-				tracker_dbus_method_metadata_get_type_details (rec);
+  	dbus_free_string_array (devices);
 
-				break;
+  	return ctx;
 
-			case DBUS_ACTION_METADATA_GET_REGISTERED_TYPES:
+}
 
-				tracker_dbus_method_metadata_get_registered_types (rec);
+#endif /* HAVE_HAL */
 
-				break;
 
-			case DBUS_ACTION_METADATA_GET_WRITEABLE_TYPES:
+gboolean
+tracker_die ()
+{
+	tracker_error ("trackerd has failed to exit on time - terminating...");
+	exit (EXIT_FAILURE);
+}
 
-				tracker_dbus_method_metadata_get_writeable_types (rec);
 
-				break;
+void
+free_file_change (FileChange **user_data)
+{
+	FileChange *change = *user_data;
+	g_free (change->uri);
+	change->uri = NULL;
+	change = NULL;
+}
 
-			case DBUS_ACTION_METADATA_GET_REGISTERED_CLASSES:
+static void
+free_file_change_queue (gpointer data, gpointer user_data)
+{
+	FileChange *change = (FileChange *)data;
+	free_file_change (&change);
+}
 
-				tracker_dbus_method_metadata_get_registered_classes (rec);
 
-				break;
+static void
+reset_blacklist_file (char *uri)
+{
 
-			case DBUS_ACTION_KEYWORDS_GET_LIST:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_keywords_get_list (rec);
+	char *parent = g_path_get_dirname (uri);
+	if (!parent) return;
 
-				break;
+	char *parent_name = g_path_get_basename (parent);
+	if (!parent_name) return;
 
-			case DBUS_ACTION_KEYWORDS_GET:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_keywords_get (rec);
+	char *parent_path = g_path_get_dirname (parent);
+	if (!parent_path) return;	
 
-				break;
+	tracker_log ("resetting black list file %s", uri);
 
-			case DBUS_ACTION_KEYWORDS_ADD:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_keywords_add (rec);
+	/* reset mtime on parent folder of all outstanding black list files so they get indexed when next restarted */
+	tracker_exec_proc (main_thread_db_con, "UpdateFileMTime", 3, "0", parent_path, parent_name);
 
-				break;
+	g_free (parent);
+	g_free (parent_name);
+	g_free (parent_path);		 
 
-			case DBUS_ACTION_KEYWORDS_REMOVE:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_keywords_remove (rec);
 
-				break;
+}
 
-			case DBUS_ACTION_KEYWORDS_REMOVE_ALL:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_keywords_remove_all (rec);
+gboolean
+tracker_do_cleanup (const gchar *sig_msg)
+{
+	tracker->status = STATUS_SHUTDOWN;
 
-				break;
+	if (sig_msg) {
+		tracker_log ("Received signal '%s' so now shutting down", sig_msg);
 
-			case DBUS_ACTION_KEYWORDS_SEARCH:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_keywords_search (rec);
+		tracker_print_object_allocations ();
+	}
 
-				break;
+	/* set kill timeout */
+	g_timeout_add_full (G_PRIORITY_LOW,
+	     		    20000,
+ 	    		    (GSourceFunc) tracker_die,
+	     		    NULL, NULL
+	   		    );
 
-			case DBUS_ACTION_SEARCH_GET_HIT_COUNT:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_search_get_hit_count (rec);
 
-				break;
+	/* stop threads from further processing of events if possible */
 
-			case DBUS_ACTION_SEARCH_GET_HIT_COUNT_ALL:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_search_get_hit_count_all (rec);
+	tracker->in_flush = TRUE;
 
-				break;
+	//set_update_count (main_thread_db_con, tracker->update_count);
 
-			case DBUS_ACTION_SEARCH_TEXT:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_search_text (rec);
+	/* wait for files thread to sleep */
+	while (!g_mutex_trylock (tracker->files_signal_mutex)) {
+		g_usleep (100);
+	}
 
-				break;
+	g_mutex_unlock (tracker->files_signal_mutex);
 
-			case DBUS_ACTION_SEARCH_TEXT_DETAILED:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_search_text_detailed (rec);
+	while (!g_mutex_trylock (tracker->metadata_signal_mutex)) {
+		g_usleep (100);
+	}
 
-				break;
+	g_mutex_unlock (tracker->metadata_signal_mutex);
 
-			case DBUS_ACTION_SEARCH_GET_SNIPPET:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_search_get_snippet (rec);
+	tracker_log ("shutting down threads");
 
-				break;
+	/* send signals to each thread to wake them up and then stop them */
 
-			case DBUS_ACTION_SEARCH_FILES_BY_TEXT:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_search_files_by_text (rec);
 
-				break;
+	tracker->shutdown = TRUE;
 
-			case DBUS_ACTION_SEARCH_METADATA:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_search_metadata (rec);
+	g_mutex_lock (tracker->request_signal_mutex);
+	g_cond_signal (tracker->request_thread_signal);
+	g_mutex_unlock (tracker->request_signal_mutex);
 
-				break;
+	g_mutex_lock (tracker->metadata_signal_mutex);
+	g_cond_signal (tracker->metadata_thread_signal);
+	g_mutex_unlock (tracker->metadata_signal_mutex);
 
-			case DBUS_ACTION_SEARCH_MATCHING_FIELDS:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_search_matching_fields (rec);
+	g_mutex_unlock (tracker->files_check_mutex);
 
-				break;
+	g_mutex_lock (tracker->files_signal_mutex);
+	g_cond_signal (tracker->file_thread_signal);
+	g_mutex_unlock (tracker->files_signal_mutex);
 
-			case DBUS_ACTION_SEARCH_QUERY:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_search_query (rec);
 
-				break;
+	/* wait for threads to exit and unlock check mutexes to prevent any deadlocks*/
 
-			case DBUS_ACTION_SEARCH_SUGGEST:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_search_suggest (rec);
+	g_mutex_unlock (tracker->request_check_mutex);
+	g_mutex_lock (tracker->request_stopped_mutex);
 
-				break;
+	g_mutex_unlock (tracker->metadata_check_mutex);
+	g_mutex_lock (tracker->metadata_stopped_mutex);
 
-			case DBUS_ACTION_FILES_EXISTS:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_files_exists (rec);
+	g_mutex_unlock (tracker->files_check_mutex);
+	g_mutex_lock (tracker->files_stopped_mutex);
 
-				break;
 
-			case DBUS_ACTION_FILES_CREATE:
+	tracker_indexer_close (tracker->file_index);
+	tracker_indexer_close (tracker->file_update_index);
+	tracker_indexer_close (tracker->email_index);
 
-				tracker_dbus_method_files_create (rec);
+	tracker_email_end_email_watching ();
 
-				break;
+	/* reset integrity status as threads have closed cleanly */
+	tracker_db_set_option_int (main_thread_db_con, "IntegrityCheck", 0);
 
-			case DBUS_ACTION_FILES_DELETE:
 
-				tracker_dbus_method_files_delete (rec);
+	/* reset black list files */
+	g_slist_foreach (tracker->tmp_black_list, (GFunc) reset_blacklist_file, NULL);
 
-				break;
+	tracker_db_close (main_thread_db_con);
 
-			case DBUS_ACTION_FILES_GET_SERVICE_TYPE:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_files_get_service_type (rec);
+	/* This must be called after all other db functions */
+	tracker_db_finalize ();
 
-				break;
 
-			case DBUS_ACTION_FILES_GET_TEXT_CONTENTS:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_files_get_text_contents (rec);
+	if (tracker->reindex) {
+		tracker_remove_dirs (tracker->data_dir);
+		g_mkdir_with_parents (tracker->data_dir, 00755);
+	}
 
-				break;
+	tracker_debug ("Shutting down main thread");
 
-			case DBUS_ACTION_FILES_SEARCH_TEXT_CONTENTS:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_files_search_text_contents (rec);
+	tracker_log_term ();
 
-				break;
+	/* remove sys tmp directory */
+	if (tracker->sys_tmp_root_dir) {
+		tracker_remove_dirs (tracker->sys_tmp_root_dir);
+	}
 
-			case DBUS_ACTION_FILES_GET_BY_SERVICE_TYPE:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_files_get_by_service_type (rec);
+	/* remove file change queue */
+	if (tracker->file_change_queue) {
+		g_queue_foreach (tracker->file_change_queue,
+				 free_file_change_queue, NULL);
+		g_queue_free (tracker->file_change_queue);
+		tracker->file_change_queue = NULL;
+	}
 
-				break;
+        if (tracker->language) {
+                tracker_language_free (tracker->language);
+        }
 
-			case DBUS_ACTION_FILES_GET_BY_MIME_TYPE:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_files_get_by_mime_type (rec);
+        if (tracker->config) {
+                g_object_unref (tracker->config);
+        }
 
-				break;
+	g_main_loop_quit (tracker->loop);
 
-			case DBUS_ACTION_FILES_GET_BY_MIME_TYPE_VFS:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_files_get_by_mime_type_vfs (rec);
+	exit (EXIT_SUCCESS);
 
-				break;
+	return FALSE;
+}
 
-			case DBUS_ACTION_FILES_GET_MTIME:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_files_get_mtime (rec);
+static void
+signal_handler (gint signo)
+{
+	static gboolean in_loop = FALSE;
 
-				break;
+  	/* die if we get re-entrant signals handler calls */
+	if (in_loop) {
+		exit (EXIT_FAILURE);
+	}
 
-			case DBUS_ACTION_FILES_GET_METADATA_FOLDER_FILES:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_files_get_metadata_for_files_in_folder (rec);
+  	switch (signo) {
 
-				break;
+  		case SIGSEGV:
 
-			case DBUS_ACTION_FILES_SEARCH_BY_TEXT_MIME:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_files_search_by_text_mime (rec);
+			/* we are screwed if we get this so exit immediately! */
+			exit (EXIT_FAILURE);
 
-				break;
+	  	case SIGBUS:
+		case SIGILL:
+  		case SIGFPE:
+  		case SIGPIPE:
+		case SIGABRT:
+		case SIGTERM:
+		case SIGINT:
 
-			case DBUS_ACTION_FILES_SEARCH_BY_TEXT_MIME_LOCATION:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_files_search_by_text_mime_location(rec);
+		  	in_loop = TRUE;
 
-				break;
+			tracker->is_running = FALSE;
+			tracker_end_watching ();
 
-			case DBUS_ACTION_FILES_SEARCH_BY_TEXT_LOCATION:
-				tracker->request_waiting = TRUE;
-				tracker->grace_period = 2;
-				tracker_dbus_method_files_search_by_text_location (rec);
+			g_timeout_add_full (G_PRIORITY_LOW,
+			     		    1,
+		 	    		    (GSourceFunc) tracker_do_cleanup,
+			     		    g_strdup (g_strsignal (signo)), NULL
+			   		    );
 
-				break;
 
 			default:
-				break;
+			if (g_strsignal (signo)) {
+	   			tracker_log ("Received signal %s ", g_strsignal (signo));
 		}
-
-		dbus_message_unref (rec->message);
-
-		g_free (rec);
-
-		
+			break;
 	}
+}
 
-	tracker_db_close_all (db_con);
-	
-	tracker_db_thread_end ();
-
-	tracker_debug ("request thread has exited successfully");
-
-	/* unlock mutex so we know thread has exited */
-	g_mutex_unlock (tracker->request_check_mutex);
-	g_mutex_unlock (tracker->request_stopped_mutex);
+static inline void
+queue_dir (const gchar *uri)
+{
+	FileInfo *info = tracker_create_file_info (uri, TRACKER_ACTION_DIRECTORY_CHECK, 0, 0);
+	g_async_queue_push (tracker->file_process_queue, info);
 }
 
 
@@ -2511,8 +881,6 @@
 	tracker->request_stopped_mutex = g_mutex_new ();
 
 	tracker->file_metadata_thread = NULL;
-	tracker->file_process_thread = NULL;
-	tracker->user_request_thread = NULL;;
 
 	tracker->file_thread_signal = g_cond_new ();
 	tracker->metadata_thread_signal = g_cond_new ();
@@ -2841,23 +1209,28 @@
 	/* this var is used to tell the threads when to quit */
 	tracker->is_running = TRUE;
 
-	tracker->user_request_thread = g_thread_create_full ((GThreadFunc) process_user_request_queue_thread, NULL,
-							     (gulong) tracker_config_get_thread_stack_size (tracker->config),
-							     FALSE, FALSE, G_THREAD_PRIORITY_NORMAL,  NULL);
-
-	
+        g_thread_create_full ((GThreadFunc) tracker_process_requests, 
+                              tracker,
+                              (gulong) tracker_config_get_thread_stack_size (tracker->config),
+                              FALSE, 
+                              FALSE, 
+                              G_THREAD_PRIORITY_NORMAL,  
+                              NULL);
 
 	if (!tracker->readonly) {
-
 		if (!tracker_start_watching ()) {
 			tracker_error ("ERROR: file monitoring failed to start");
 			tracker_do_cleanup ("File watching failure");
 			exit (1);
 		}
 
-		tracker->file_process_thread = g_thread_create_full ((GThreadFunc) process_files_thread, NULL,
-								     (gulong) tracker_config_get_thread_stack_size (tracker->config),
-								     FALSE, FALSE, G_THREAD_PRIORITY_NORMAL, NULL);
+                g_thread_create_full ((GThreadFunc) tracker_process_files, 
+                                      tracker,
+                                      (gulong) tracker_config_get_thread_stack_size (tracker->config),
+                                      FALSE, 
+                                      FALSE, 
+                                      G_THREAD_PRIORITY_NORMAL, 
+                                      NULL);
 	}
 	
 	g_main_loop_run (tracker->loop);



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