tracker r1379 - in branches/indexer-split: . src/libtracker-common src/trackerd
- From: mr svn gnome org
- To: svn-commits-list gnome org
- Subject: tracker r1379 - in branches/indexer-split: . src/libtracker-common src/trackerd
- Date: Thu, 8 May 2008 17:39:43 +0100 (BST)
Author: mr
Date: Thu May 8 16:39:43 2008
New Revision: 1379
URL: http://svn.gnome.org/viewvc/tracker?rev=1379&view=rev
Log:
* src/libtracker-common/tracker-nfs-lock.c: Improve logging.
* src/trackerd/tracker-dbus-daemon.c: Renamed _do_cleanup() to
_shutdown() and make it ONLY stop the main loop so we clean up
every time after the mainloop stops.
* src/trackerd/tracker-process-files.c: Removed
tracker->update_count since it was redundant.
Modified:
branches/indexer-split/ChangeLog
branches/indexer-split/src/libtracker-common/tracker-nfs-lock.c
branches/indexer-split/src/trackerd/tracker-dbus-daemon.c
branches/indexer-split/src/trackerd/tracker-main.c
branches/indexer-split/src/trackerd/tracker-main.h
branches/indexer-split/src/trackerd/tracker-process-files.c
Modified: branches/indexer-split/src/libtracker-common/tracker-nfs-lock.c
==============================================================================
--- branches/indexer-split/src/libtracker-common/tracker-nfs-lock.c (original)
+++ branches/indexer-split/src/libtracker-common/tracker-nfs-lock.c Thu May 8 16:39:43 2008
@@ -79,7 +79,7 @@
}
if (!is_initialized()) {
- tracker_error ("Trying to use NFS Lock. It is NOT initialized\n");
+ tracker_error ("Could not initialise NFS lock");
return FALSE;
}
@@ -119,7 +119,7 @@
}
error:
- tracker_error ("ERROR: lock failure");
+ tracker_error ("Could not get NFS lock state");
g_free (tmp_file);
return FALSE;
@@ -135,7 +135,7 @@
}
if (!is_initialized()) {
- tracker_error ("Trying to use NFS Lock. It is NOT initialized\n");
+ tracker_error ("Could not initialise NFS lock");
return;
}
@@ -151,7 +151,7 @@
tracker_nfs_lock_init (const gchar *root_dir)
{
if (is_initialized ()) {
- tracker_error ("Trying to initialize tracker_db_lock for second time");
+ return;
}
if (lock_file == NULL) {
@@ -162,15 +162,15 @@
tmp_filepath = g_build_filename (root_dir, g_get_host_name (), NULL);
}
- tracker_log ("Initialized NFS lock %s",
- use_nfs_safe_locking ? "" : "(Not in use)");
+ tracker_log ("NFS lock initialised %s",
+ use_nfs_safe_locking ? "" : "(safe locking not in use)");
}
void
tracker_nfs_lock_term (void)
{
if (!is_initialized ()) {
- tracker_error ("Trying to term tracker_db_lock not initialized");
+ return;
}
if (lock_file) {
@@ -181,5 +181,5 @@
g_free (tmp_filepath);
}
- tracker_log ("Tracker db NFS lock finalized");
+ tracker_log ("NFS lock finalised");
}
Modified: branches/indexer-split/src/trackerd/tracker-dbus-daemon.c
==============================================================================
--- branches/indexer-split/src/trackerd/tracker-dbus-daemon.c (original)
+++ branches/indexer-split/src/trackerd/tracker-dbus-daemon.c Thu May 8 16:39:43 2008
@@ -543,7 +543,7 @@
priv->tracker->reindex = reindex;
- g_timeout_add (500, (GSourceFunc) tracker_do_cleanup, NULL);
+ g_timeout_add (500, (GSourceFunc) tracker_shutdown, NULL);
tracker_dbus_request_success (request_id);
Modified: branches/indexer-split/src/trackerd/tracker-main.c
==============================================================================
--- branches/indexer-split/src/trackerd/tracker-main.c (original)
+++ branches/indexer-split/src/trackerd/tracker-main.c Thu May 8 16:39:43 2008
@@ -62,116 +62,134 @@
#include "mingw-compat.h"
#endif
-#define ABOUT \
- "Tracker " VERSION "\n" \
- "Copyright (c) 2005-2008 Jamie McCracken (jamiemcc gnome org)\n"
-
-#define LICENSE \
- "This program is free software and comes without any warranty.\n" \
- "It is licensed under version 2 or later of the General Public " \
- "License which can be viewed at:\n" \
- "\n" \
- " http://www.gnu.org/licenses/gpl.txt\n"
+/*
+ * The workflow to process files and notified file change events are
+ * as follows:
+ *
+ * 1) File scan or file notification change (as reported by
+ * FAM/iNotify).
-typedef struct {
- gchar *uri;
- gint mtime;
-} IndexDir;
-
-Tracker *tracker;
-DBConnection *main_thread_db_con;
-DBConnection *main_thread_cache_con;
+ * 2) File Scheduler (we wait until a file's changes have stabilised
+ * (NB not neccesary with inotify))
+ * 3) We process a file's basic metadata (stat) and determine what
+ * needs doing in a seperate thread.
-/*
- * The workflow to process files and notified file change events are as follows:
+ * 4) We extract CPU intensive embedded metadata/text/thumbnail in
+ * another thread and save changes to the DB
*
- * 1) File scan or file notification change (as reported by FAM/iNotify).
- * 2) File Scheduler (we wait until a file's changes have stabilised (NB not neccesary with inotify))
- * 3) We process a file's basic metadata (stat) and determine what needs doing in a seperate thread.
- * 4) We extract CPU intensive embedded metadata/text/thumbnail in another thread and save changes to the DB
*
+ * Three threads are used to fully process a file event. Files or
+ * events to be processed are placed on asynchronous queues where
+ * another thread takes over the work.
*
- * Three threads are used to fully process a file event. Files or events to be processed are placed on
- * asynchronous queues where another thread takes over the work.
+ * The main thread is very lightweight and no cpu intensive or heavy
+ * file I/O (or heavy DB access) is permitted here after
+ * initialisation of the daemon. This ensures the main thread can
+ * handle events and DBUS requests in a timely low latency manner.
*
- * The main thread is very lightweight and no cpu intensive or heavy file I/O (or heavy DB access) is permitted
- * here after initialisation of the daemon. This ensures the main thread can handle events and DBUS
- * requests in a timely low latency manner.
+ * The File Process thread is for moderate CPU intensive load and I/O
+ * and involves calls to stat() and simple fast queries on the DB.
+ * The main thread queues files to be processed by this thread via
+ * the file_process async queue. As no heavily CPU intensive activity
+ * occurs here, we can quickly keep the DB representation of the
+ * watched file system up to date. Once a file has been processed
+ * here it is then placed on the file metadata queue which is handled
+ * by the File Metadata thread.
*
- * The File Process thread is for moderate CPU intensive load and I/O and involves calls to stat()
- * and simple fast queries on the DB. The main thread queues files to be processed by this thread
- * via the file_process async queue. As no heavily CPU intensive activity occurs here, we can quickly
- * keep the DB representation of the watched file system up to date. Once a file has been processed
- * here it is then placed on the file metadata queue which is handled by the File Metadata thread.
+ * The File Metadata thread is a low priority thread to handle the
+ * highly CPU intensive parts. During this phase, embedded metadata
+ * is extracted from files and if a text filter and/or thumbnailer is
+ * available for the mime type of the file then these will be spawned
+ * synchronously. Finally all metadata (including file's text
+ * contents and path to thumbnails) is saved to the DB.
*
- * The File Metadata thread is a low priority thread to handle the highly CPU intensive parts.
- * During this phase, embedded metadata is extracted from files and if a text filter and/or
- * thumbnailer is available for the mime type of the file then these will be spawned synchronously.
- * Finally all metadata (including file's text contents and path to thumbnails) is saved to the DB.
- *
- * All responses including user initiated requests are queued by the main thread onto an
- * asynchronous queue where potentially multiple threads are waiting to process them.
+ * All responses including user initiated requests are queued by the
+ * main thread onto an asynchronous queue where potentially multiple
+ * threads are waiting to process them.
*/
+#define ABOUT \
+ "Tracker " VERSION "\n" \
+ "Copyright (c) 2005-2008 Jamie McCracken (jamiemcc gnome org)\n"
-static gchar **no_watch_dirs = NULL;
-static gchar **watch_dirs = NULL;
-static gchar **crawl_dirs = NULL;
-static gchar *language = NULL;
-static gboolean disable_indexing = FALSE;
-static gboolean reindex = FALSE;
-static gboolean fatal_errors = FALSE;
-static gboolean low_memory;
-static gint throttle = -1;
-static gint verbosity = 0;
-static gint initial_sleep = -1; /* >= 0 is valid and will be set */
-
-static GOptionEntry entries[] = {
- {"exclude-dir", 'e', 0, G_OPTION_ARG_STRING_ARRAY, &no_watch_dirs, N_("Directory to exclude from indexing"), N_("/PATH/DIR")},
- {"include-dir", 'i', 0, G_OPTION_ARG_STRING_ARRAY, &watch_dirs, N_("Directory to include in indexing"), N_("/PATH/DIR")},
- {"crawl-dir", 'c', 0, G_OPTION_ARG_STRING_ARRAY, &crawl_dirs, N_("Directory to crawl for indexing at start up only"), N_("/PATH/DIR")},
- {"no-indexing", 'n', 0, G_OPTION_ARG_NONE, &disable_indexing, N_("Disable any indexing or watching taking place"), NULL },
- {"verbosity", 'v', 0, G_OPTION_ARG_INT, &verbosity, N_("Value that controls the level of logging. Valid values are 0 (displays/logs only errors), 1 (minimal), 2 (detailed), and 3 (debug)"), N_("VALUE") },
- {"throttle", 't', 0, G_OPTION_ARG_INT, &throttle, N_("Value to use for throttling indexing. Value must be in range 0-99 (default 0) with lower values increasing indexing speed"), N_("VALUE") },
- {"low-memory", 'm', 0, G_OPTION_ARG_NONE, &low_memory, N_("Minimizes the use of memory but may slow indexing down"), NULL },
- {"initial-sleep", 's', 0, G_OPTION_ARG_INT, &initial_sleep, N_("Initial sleep time, just before indexing, in seconds"), NULL },
- {"language", 'l', 0, G_OPTION_ARG_STRING, &language, N_("Language to use for stemmer and stop words list (ISO 639-1 2 characters code)"), N_("LANG")},
- {"reindex", 'R', 0, G_OPTION_ARG_NONE, &reindex, N_("Force a re-index of all content"), NULL },
- {"fatal-errors", 'f', 0, G_OPTION_ARG_NONE, &fatal_errors, N_("Make tracker errors fatal"), NULL },
- {NULL}
-};
-
-
-static gint
-get_update_count (DBConnection *db_con)
-{
- TrackerDBResultSet *result_set;
- gchar *str;
- gint count = 0;
-
- result_set = tracker_exec_proc (db_con, "GetUpdateCount", NULL);
-
- if (result_set) {
- tracker_db_result_set_get (result_set, 0, &str, -1);
-
- if (str) {
- count = atoi (str);
- }
-
- g_free (str);
- g_object_unref (result_set);
- }
-
- return count;
-}
+#define LICENSE \
+ "This program is free software and comes without any warranty.\n" \
+ "It is licensed under version 2 or later of the General Public " \
+ "License which can be viewed at:\n" \
+ "\n" \
+ " http://www.gnu.org/licenses/gpl.txt\n"
-gboolean
-tracker_die (void)
-{
- tracker_error ("trackerd has failed to exit on time - terminating...");
- exit (EXIT_FAILURE);
-}
+/* Public */
+Tracker *tracker;
+DBConnection *main_thread_db_con;
+DBConnection *main_thread_cache_con;
+
+static GMainLoop *main_loop;
+
+static gchar **no_watch_dirs;
+static gchar **watch_dirs;
+static gchar **crawl_dirs;
+static gchar *language;
+static gboolean disable_indexing;
+static gboolean reindex;
+static gboolean fatal_errors;
+static gboolean low_memory;
+static gint throttle = -1;
+static gint verbosity;
+static gint initial_sleep = -1;
+
+static GOptionEntry entries[] = {
+ { "exclude-dir", 'e', 0,
+ G_OPTION_ARG_STRING_ARRAY, &no_watch_dirs,
+ N_("Directory to exclude from indexing"),
+ N_("/PATH/DIR") },
+ { "include-dir", 'i', 0,
+ G_OPTION_ARG_STRING_ARRAY, &watch_dirs,
+ N_("Directory to include in indexing"),
+ N_("/PATH/DIR") },
+ { "crawl-dir", 'c', 0,
+ G_OPTION_ARG_STRING_ARRAY, &crawl_dirs,
+ N_("Directory to crawl for indexing at start up only"),
+ N_("/PATH/DIR") },
+ { "no-indexing", 'n', 0,
+ G_OPTION_ARG_NONE, &disable_indexing,
+ N_("Disable any indexing or watching taking place"), NULL },
+ { "verbosity", 'v', 0,
+ G_OPTION_ARG_INT, &verbosity,
+ N_("Value that controls the level of logging. "
+ "Valid values are 0 (displays/logs only errors), "
+ "1 (minimal), 2 (detailed), and 3 (debug)"),
+ N_("VALUE") },
+ { "throttle", 't', 0,
+ G_OPTION_ARG_INT, &throttle,
+ N_("Value to use for throttling indexing. "
+ "Value must be in range 0-99 (default 0) "
+ "with lower values increasing indexing speed"),
+ N_("VALUE") },
+ { "low-memory", 'm', 0,
+ G_OPTION_ARG_NONE, &low_memory,
+ N_("Minimizes the use of memory but may slow indexing down"),
+ NULL },
+ { "initial-sleep", 's', 0,
+ G_OPTION_ARG_INT, &initial_sleep,
+ N_("Initial sleep time, just before indexing, in seconds"),
+ NULL },
+ { "language", 'l', 0,
+ G_OPTION_ARG_STRING, &language,
+ N_("Language to use for stemmer and stop words list "
+ "(ISO 639-1 2 characters code)"),
+ N_("LANG")},
+ { "reindex", 'R', 0,
+ G_OPTION_ARG_NONE, &reindex,
+ N_("Force a re-index of all content"),
+ NULL },
+ { "fatal-errors", 'f', 0,
+ G_OPTION_ARG_NONE, &fatal_errors,
+ N_("Make tracker errors fatal"),
+ NULL },
+ { NULL }
+};
static void
free_file_change_queue (gpointer data, gpointer user_data)
@@ -181,209 +199,294 @@
}
static void
-reset_blacklist_file (char *uri)
+reset_blacklist_file (gchar *uri)
{
+ gchar *dirname;
+ gchar *dirname_parent;
+ gchar *basename;
- 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", "0", parent_path, parent_name, NULL);
-
- g_free (parent);
- g_free (parent_name);
- g_free (parent_path);
+ dirname = g_path_get_dirname (uri);
+ if (!dirname) {
+ return;
+ }
+ basename = g_path_get_basename (dirname);
+ if (!basename) {
+ return;
+ }
+ dirname_parent = g_path_get_dirname (dirname);
+ if (!dirname_parent) {
+ 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", "0",
+ dirname_parent, basename,
+ NULL);
+
+ g_free (basename);
+ g_free (dirname_parent);
+ g_free (dirname);
}
-gboolean
-tracker_do_cleanup (const gchar *sig_msg)
+static void
+signal_handler (gint signo)
{
- GSList *black_list;
-
- tracker->shutdown = TRUE;
-
- tracker_status_set (TRACKER_STATUS_SHUTDOWN);
+ static gboolean in_loop = FALSE;
- if (sig_msg) {
- tracker_log ("Received signal '%s' so now shutting down", sig_msg);
+ /* Die if we get re-entrant signals handler calls */
+ if (in_loop) {
+ exit (EXIT_FAILURE);
}
-
- /* 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 */
-
- //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);
+
+ 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_shutdown,
+ g_strdup (g_strsignal (signo)), NULL);
+
+ default:
+ if (g_strsignal (signo)) {
+ tracker_log ("Received signal:%d->'%s'",
+ signo,
+ g_strsignal (signo));
+ }
+ break;
}
+}
- g_mutex_unlock (tracker->files_signal_mutex);
+static void
+log_option_list (GSList *list,
+ const gchar *str)
+{
+ GSList *l;
- while (!g_mutex_trylock (tracker->metadata_signal_mutex)) {
- g_usleep (100);
+ if (!list) {
+ tracker_log ("%s: NONE!", str);
+ return;
}
- g_mutex_unlock (tracker->metadata_signal_mutex);
+ tracker_log ("%s:", str);
- tracker_log ("Shutting down threads");
+ for (l = list; l; l = l->next) {
+ tracker_log (" %s", l->data);
+ }
+}
- /* send signals to each thread to wake them up and then stop them */
- g_mutex_lock (tracker->metadata_signal_mutex);
- g_cond_signal (tracker->metadata_signal_cond);
- g_mutex_unlock (tracker->metadata_signal_mutex);
+static void
+sanity_check_option_values (void)
+{
+ GSList *watch_directory_roots;
+ GSList *crawl_directory_roots;
+ GSList *no_watch_directory_roots;
+ GSList *no_index_file_types;
- g_mutex_unlock (tracker->files_check_mutex);
+ watch_directory_roots = tracker_config_get_watch_directory_roots (tracker->config);
+ crawl_directory_roots = tracker_config_get_crawl_directory_roots (tracker->config);
+ no_watch_directory_roots = tracker_config_get_no_watch_directory_roots (tracker->config);
- g_mutex_lock (tracker->files_signal_mutex);
- g_cond_signal (tracker->files_signal_cond);
- g_mutex_unlock (tracker->files_signal_mutex);
+ no_index_file_types = tracker_config_get_no_index_file_types (tracker->config);
- /* wait for threads to exit and unlock check mutexes to prevent any deadlocks*/
+ tracker_log ("Tracker configuration options:");
+ tracker_log (" Verbosity ............................ %d",
+ tracker_config_get_verbosity (tracker->config));
+ tracker_log (" Low memory mode ...................... %s",
+ tracker_config_get_low_memory_mode (tracker->config) ? "yes" : "no");
+ tracker_log (" Indexing enabled ..................... %s",
+ tracker_config_get_enable_indexing (tracker->config) ? "yes" : "no");
+ tracker_log (" Watching enabled ..................... %s",
+ tracker_config_get_enable_watches (tracker->config) ? "yes" : "no");
+ tracker_log (" File content indexing enabled ........ %s",
+ tracker_config_get_enable_content_indexing (tracker->config) ? "yes" : "no");
+ tracker_log (" Thumbnailing enabled ................. %s",
+ tracker_config_get_enable_thumbnails (tracker->config) ? "yes" : "no");
+ tracker_log (" Email client to index ................. %s",
+ tracker_config_get_email_client (tracker->config));
- g_mutex_unlock (tracker->metadata_check_mutex);
+ tracker_log ("Tracker indexer parameters:");
+ tracker_log (" Indexer language code ................ %s",
+ tracker_config_get_language (tracker->config));
+ tracker_log (" Minimum index word length ............ %d",
+ tracker_config_get_min_word_length (tracker->config));
+ tracker_log (" Maximum index word length ............ %d",
+ tracker_config_get_max_word_length (tracker->config));
+ tracker_log (" Stemmer enabled ...................... %s",
+ tracker_config_get_enable_stemmer (tracker->config) ? "yes" : "no");
- g_mutex_unlock (tracker->files_check_mutex);
+ tracker->word_count = 0;
+ tracker->word_detail_count = 0;
+ tracker->word_update_count = 0;
- tracker_indexer_close (tracker->file_index);
- tracker_indexer_close (tracker->file_update_index);
- tracker_indexer_close (tracker->email_index);
+ tracker->file_word_table = g_hash_table_new (g_str_hash, g_str_equal);
+ tracker->file_update_word_table = g_hash_table_new (g_str_hash, g_str_equal);
+ tracker->email_word_table = g_hash_table_new (g_str_hash, g_str_equal);
- tracker_email_end_email_watching ();
+ if (!tracker_config_get_low_memory_mode (tracker->config)) {
+ tracker->memory_limit = 16000 *1024;
+
+ tracker->max_process_queue_size = 5000;
+ tracker->max_extract_queue_size = 5000;
+ } else {
+ tracker->memory_limit = 8192 * 1024;
- /* reset integrity status as threads have closed cleanly */
- tracker_db_set_option_int (main_thread_db_con, "IntegrityCheck", 0);
+ tracker->max_process_queue_size = 500;
+ tracker->max_extract_queue_size = 500;
+ }
+ log_option_list (watch_directory_roots, "Watching directory roots");
+ log_option_list (crawl_directory_roots, "Crawling directory roots");
+ log_option_list (no_watch_directory_roots, "NOT watching directory roots");
+ log_option_list (no_index_file_types, "NOT indexing file types");
- /* reset black list files */
- black_list = tracker_process_files_get_temp_black_list ();
- g_slist_foreach (black_list,
- (GFunc) reset_blacklist_file,
- NULL);
- g_slist_free (black_list);
+ tracker_log ("Throttle level is %d\n", tracker_config_get_throttle (tracker->config));
- tracker_db_close (main_thread_db_con);
+ tracker->metadata_table = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ NULL,
+ NULL);
+}
- /* This must be called after all other db functions */
- tracker_db_finalize ();
+static void
+create_index (gboolean need_data)
+{
+ DBConnection *db_con;
+
+ tracker->first_time_index = TRUE;
+ /* Create files db and emails db */
+ db_con = tracker_db_connect ();
- if (tracker->reindex) {
- tracker_dir_remove (tracker->data_dir);
- g_mkdir_with_parents (tracker->data_dir, 00755);
+ /* Reset stats for embedded services if they are being reindexed */
+ if (!need_data) {
+ tracker_log ("*** DELETING STATS *** ");
+ tracker_db_exec_no_reply (db_con,
+ "update ServiceTypes set TypeCount = 0 where Embedded = 1");
}
- if (tracker->hal) {
- g_object_unref (tracker->hal);
- tracker->hal = NULL;
- }
-
- tracker_debug ("Shutting down main thread");
-
- tracker_log_term ();
-
- tracker_nfs_lock_term ();
+ tracker_db_close (db_con);
+ g_free (db_con);
- /* remove sys tmp directory */
- if (tracker->sys_tmp_root_dir) {
- tracker_dir_remove (tracker->sys_tmp_root_dir);
- }
+ /* Create databases */
+ db_con = tracker_db_connect_file_content ();
+ tracker_db_close (db_con);
+ g_free (db_con);
- /* 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;
- }
+ db_con = tracker_db_connect_email_content ();
+ tracker_db_close (db_con);
+ g_free (db_con);
- if (tracker->language) {
- tracker_language_free (tracker->language);
- }
+ db_con = tracker_db_connect_emails ();
+ tracker_db_close (db_con);
+ g_free (db_con);
- if (tracker->config) {
- g_object_unref (tracker->config);
- }
+}
- g_main_loop_quit (tracker->loop);
+static void
+initialise_signal_handler (void)
+{
+#ifndef OS_WIN32
+ struct sigaction act;
+ sigset_t empty_mask;
- exit (EXIT_SUCCESS);
+ sigemptyset (&empty_mask);
+ act.sa_handler = signal_handler;
+ act.sa_mask = empty_mask;
+ act.sa_flags = 0;
- return FALSE;
+ sigaction (SIGTERM, &act, NULL);
+ sigaction (SIGILL, &act, NULL);
+ sigaction (SIGBUS, &act, NULL);
+ sigaction (SIGFPE, &act, NULL);
+ sigaction (SIGHUP, &act, NULL);
+ sigaction (SIGSEGV, &act, NULL);
+ sigaction (SIGABRT, &act, NULL);
+ sigaction (SIGUSR1, &act, NULL);
+ sigaction (SIGINT, &act, NULL);
+#endif
}
static void
-signal_handler (gint signo)
+initialise_directories (void)
{
- static gboolean in_loop = FALSE;
+ gchar *str;
+ gchar *filename;
- /* die if we get re-entrant signals handler calls */
- if (in_loop) {
- exit (EXIT_FAILURE);
- }
+ str = g_strdup_printf ("Tracker-%s.%d", g_get_user_name (), getpid ());
+ tracker->sys_tmp_root_dir = g_build_filename (g_get_tmp_dir (), str, NULL);
+ g_free (str);
- switch (signo) {
+ tracker->root_dir = g_build_filename (g_get_user_data_dir (), "tracker", NULL);
+ tracker->data_dir = g_build_filename (g_get_user_cache_dir (), "tracker", NULL);
+ tracker->config_dir = g_strdup (g_get_user_config_dir ());
+ tracker->user_data_dir = g_build_filename (tracker->root_dir, "data", NULL);
+ tracker->xesam_dir = g_build_filename (g_get_home_dir (), ".xesam", NULL);
- case SIGSEGV:
+ /* Remove an existing one */
+ if (g_file_test (tracker->sys_tmp_root_dir, G_FILE_TEST_EXISTS)) {
+ tracker_dir_remove (tracker->sys_tmp_root_dir);
+ }
- /* we are screwed if we get this so exit immediately! */
- exit (EXIT_FAILURE);
+ /* Remove old tracker dirs */
+ filename = g_build_filename (g_get_home_dir (), ".Tracker", NULL);
- case SIGBUS:
- case SIGILL:
- case SIGFPE:
- case SIGPIPE:
- case SIGABRT:
- case SIGTERM:
- case SIGINT:
+ if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
+ tracker_dir_remove (filename);
+ }
- in_loop = TRUE;
+ g_free (filename);
- tracker->is_running = FALSE;
- tracker_end_watching ();
+ /* Create other directories we need */
+ if (!g_file_test (tracker->user_data_dir, G_FILE_TEST_EXISTS)) {
+ g_mkdir_with_parents (tracker->user_data_dir, 00755);
+ }
- g_timeout_add_full (G_PRIORITY_LOW,
- 1,
- (GSourceFunc) tracker_do_cleanup,
- g_strdup (g_strsignal (signo)), NULL
- );
+ if (!g_file_test (tracker->data_dir, G_FILE_TEST_EXISTS)) {
+ g_mkdir_with_parents (tracker->data_dir, 00755);
+ }
+ tracker->email_attachements_dir = g_build_filename (tracker->sys_tmp_root_dir, "Attachments", NULL);
+ g_mkdir_with_parents (tracker->email_attachements_dir, 00700);
- default:
- if (g_strsignal (signo)) {
- tracker_log ("Received signal %s ", g_strsignal (signo));
- }
- break;
- }
+ /* Remove existing log files */
+ tracker->log_filename = g_build_filename (tracker->root_dir, "tracker.log", NULL);
+ tracker_file_unlink (tracker->log_filename);
}
-static inline void
-queue_dir (const gchar *uri)
+static void
+initialise_threading (void)
{
- TrackerDBFileInfo *info = tracker_db_file_info_new (uri, TRACKER_DB_ACTION_DIRECTORY_CHECK, 0, 0);
- g_async_queue_push (tracker->file_process_queue, info);
-}
+ tracker->files_check_mutex = g_mutex_new ();
+ tracker->files_signal_mutex = g_mutex_new ();
+ tracker->files_signal_cond = g_cond_new ();
+ tracker->metadata_check_mutex = g_mutex_new ();
+ tracker->metadata_signal_mutex = g_mutex_new ();
+ tracker->metadata_signal_cond = g_cond_new ();
+}
static void
-set_defaults (void)
+initialise_defaults (void)
{
tracker->grace_period = 0;
@@ -402,7 +505,6 @@
tracker->watch_limit = 0;
tracker->index_count = 0;
- tracker->update_count = 0;
tracker->max_process_queue_size = MAX_PROCESS_QUEUE_SIZE;
tracker->max_extract_queue_size = MAX_EXTRACT_QUEUE_SIZE;
@@ -418,147 +520,214 @@
}
static void
-log_option_list (GSList *list,
- const gchar *str)
+initialise_databases (gboolean need_index)
{
- GSList *l;
+ Indexer *index;
+ DBConnection *db_con;
+ gchar *final_index_name;
+ gboolean need_data;
+
+ /* FIXME: is this actually necessary? */
+ db_con = tracker_db_connect_cache ();
+ tracker_db_close (db_con);
- if (!list) {
- tracker_log ("%s: NONE!", str);
- return;
+ need_data = tracker_db_needs_data ();
+
+ if (need_data) {
+ tracker_create_common_db ();
}
- tracker_log ("%s:", str);
+ if (!tracker->readonly && need_index) {
+ create_index (need_data);
+ } else {
+ tracker->first_time_index = FALSE;
+ }
- for (l = list; l; l = l->next) {
- tracker_log (" %s", l->data);
+ /* Set up main database connection */
+ db_con = tracker_db_connect ();
+
+ /* Check db integrity if not previously shut down cleanly */
+ if (!tracker->readonly &&
+ !need_index &&
+ tracker_db_get_option_int (db_con, "IntegrityCheck") == 1) {
+ tracker_log ("Performing integrity check as the daemon was not shutdown cleanly");
+ /* FIXME: Finish */
+ }
+
+ if (!tracker->readonly) {
+ tracker_db_set_option_int (db_con, "IntegrityCheck", 1);
+ }
+
+ if (tracker->first_time_index) {
+ tracker_db_set_option_int (db_con, "InitialIndex", 1);
}
-}
-static void
-sanity_check_option_values (void)
-{
- GSList *watch_directory_roots;
- GSList *crawl_directory_roots;
- GSList *no_watch_directory_roots;
- GSList *no_index_file_types;
+ /* Create connections */
+ db_con->cache = tracker_db_connect_cache ();
+ db_con->common = tracker_db_connect_common ();
- watch_directory_roots = tracker_config_get_watch_directory_roots (tracker->config);
- crawl_directory_roots = tracker_config_get_crawl_directory_roots (tracker->config);
- no_watch_directory_roots = tracker_config_get_no_watch_directory_roots (tracker->config);
+ main_thread_db_con = db_con;
+
+ /* Move final file to index file if present and no files left
+ * to merge.
+ */
+ final_index_name = g_build_filename (tracker->data_dir,
+ "file-index-final",
+ NULL);
+
+ if (g_file_test (final_index_name, G_FILE_TEST_EXISTS) &&
+ !tracker_indexer_has_tmp_merge_files (INDEX_TYPE_FILES)) {
+ gchar *file_index_name;
+
+ file_index_name = g_build_filename (tracker->data_dir,
+ TRACKER_INDEXER_FILE_INDEX_DB_FILENAME,
+ NULL);
+
+ tracker_log ("Overwriting '%s' with '%s'",
+ file_index_name,
+ final_index_name);
+ rename (final_index_name, file_index_name);
+ g_free (file_index_name);
+ }
+
+ g_free (final_index_name);
+
+ final_index_name = g_build_filename (tracker->data_dir,
+ "email-index-final",
+ NULL);
+
+ if (g_file_test (final_index_name, G_FILE_TEST_EXISTS) &&
+ !tracker_indexer_has_tmp_merge_files (INDEX_TYPE_EMAILS)) {
+ gchar *file_index_name;
+
+ file_index_name = g_build_filename (tracker->data_dir,
+ TRACKER_INDEXER_EMAIL_INDEX_DB_FILENAME,
+ NULL);
+
+ tracker_log ("Overwriting '%s' with '%s'",
+ file_index_name,
+ final_index_name);
+ rename (final_index_name, file_index_name);
+ g_free (file_index_name);
+ }
+
+ g_free (final_index_name);
- no_index_file_types = tracker_config_get_no_index_file_types (tracker->config);
+ /* Create indexers */
+ index = tracker_indexer_open (TRACKER_INDEXER_FILE_INDEX_DB_FILENAME, TRUE);
+ tracker->file_index = index;
- tracker_log ("Tracker configuration options:");
- tracker_log (" Verbosity ............................ %d",
- tracker_config_get_verbosity (tracker->config));
- tracker_log (" Low memory mode ...................... %s",
- tracker_config_get_low_memory_mode (tracker->config) ? "yes" : "no");
- tracker_log (" Indexing enabled ..................... %s",
- tracker_config_get_enable_indexing (tracker->config) ? "yes" : "no");
- tracker_log (" Watching enabled ..................... %s",
- tracker_config_get_enable_watches (tracker->config) ? "yes" : "no");
- tracker_log (" File content indexing enabled ........ %s",
- tracker_config_get_enable_content_indexing (tracker->config) ? "yes" : "no");
- tracker_log (" Thumbnailing enabled ................. %s",
- tracker_config_get_enable_thumbnails (tracker->config) ? "yes" : "no");
- tracker_log (" Email client to index ................. %s",
- tracker_config_get_email_client (tracker->config));
+ index = tracker_indexer_open (TRACKER_INDEXER_FILE_UPDATE_INDEX_DB_FILENAME, FALSE);
+ tracker->file_update_index = index;
- tracker_log ("Tracker indexer parameters:");
- tracker_log (" Indexer language code ................ %s",
- tracker_config_get_language (tracker->config));
- tracker_log (" Minimum index word length ............ %d",
- tracker_config_get_min_word_length (tracker->config));
- tracker_log (" Maximum index word length ............ %d",
- tracker_config_get_max_word_length (tracker->config));
- tracker_log (" Stemmer enabled ...................... %s",
- tracker_config_get_enable_stemmer (tracker->config) ? "yes" : "no");
+ index = tracker_indexer_open (TRACKER_INDEXER_EMAIL_INDEX_DB_FILENAME, TRUE);
+ tracker->email_index = index;
- tracker->word_count = 0;
- tracker->word_detail_count = 0;
- tracker->word_update_count = 0;
+ db_con->word_index = tracker->file_index;
- tracker->file_word_table = g_hash_table_new (g_str_hash, g_str_equal);
- tracker->file_update_word_table = g_hash_table_new (g_str_hash, g_str_equal);
- tracker->email_word_table = g_hash_table_new (g_str_hash, g_str_equal);
+ tracker_db_get_static_data (db_con);
- if (!tracker_config_get_low_memory_mode (tracker->config)) {
- tracker->memory_limit = 16000 *1024;
-
- tracker->max_process_queue_size = 5000;
- tracker->max_extract_queue_size = 5000;
- } else {
- tracker->memory_limit = 8192 * 1024;
+ tracker->file_metadata_queue = g_async_queue_new ();
+
+ if (!tracker->readonly) {
+ tracker->file_process_queue = g_async_queue_new ();
+ }
+}
+
+static gboolean
+shutdown_timeout_cb (gpointer user_data)
+{
+ tracker_error ("Could not exit in a timely fashion - terminating...");
+ exit (EXIT_FAILURE);
+
+ return FALSE;
+}
+
+static void
+shutdown_threads (void)
+{
+ tracker_log ("Shutting down threads");
+
+ /* Wait for files thread to sleep */
+ while (!g_mutex_trylock (tracker->files_signal_mutex)) {
+ g_usleep (100);
+ }
- tracker->max_process_queue_size = 500;
- tracker->max_extract_queue_size = 500;
+ g_mutex_unlock (tracker->files_signal_mutex);
+
+ while (!g_mutex_trylock (tracker->metadata_signal_mutex)) {
+ g_usleep (100);
}
- log_option_list (watch_directory_roots, "Watching directory roots");
- log_option_list (crawl_directory_roots, "Crawling directory roots");
- log_option_list (no_watch_directory_roots, "NOT watching directory roots");
- log_option_list (no_index_file_types, "NOT indexing file types");
+ g_mutex_unlock (tracker->metadata_signal_mutex);
- tracker_log ("Throttle level is %d\n", tracker_config_get_throttle (tracker->config));
+ /* Send signals to each thread to wake them up and then stop
+ * them.
+ */
+ g_mutex_lock (tracker->metadata_signal_mutex);
+ g_cond_signal (tracker->metadata_signal_cond);
+ g_mutex_unlock (tracker->metadata_signal_mutex);
- tracker->metadata_table = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- NULL,
- NULL);
+ g_mutex_unlock (tracker->files_check_mutex);
+
+ g_mutex_lock (tracker->files_signal_mutex);
+ g_cond_signal (tracker->files_signal_cond);
+ g_mutex_unlock (tracker->files_signal_mutex);
+
+ /* Wait for threads to exit and unlock check mutexes to
+ * prevent any deadlocks
+ */
+ g_mutex_unlock (tracker->metadata_check_mutex);
+ g_mutex_unlock (tracker->files_check_mutex);
}
static void
-create_index (gboolean need_data)
+shutdown_indexer (void)
{
- tracker->first_time_index = TRUE;
-
- /* create files db and emails db */
- DBConnection *db_con_tmp = tracker_db_connect ();
-
- /* reset stats for embedded services if they are being reindexed */
- if (!need_data) {
- tracker_log ("*** DELETING STATS *** ");
- tracker_db_exec_no_reply (db_con_tmp, "update ServiceTypes set TypeCount = 0 where Embedded = 1");
- }
+ tracker_indexer_close (tracker->file_index);
+ tracker_indexer_close (tracker->file_update_index);
+ tracker_indexer_close (tracker->email_index);
- tracker_db_close (db_con_tmp);
- g_free (db_con_tmp);
+ tracker_email_end_email_watching ();
+}
- /* create databases */
+static void
+shutdown_databases (void)
+{
+ /* Reset integrity status as threads have closed cleanly */
+ tracker_db_set_option_int (main_thread_db_con, "IntegrityCheck", 0);
- db_con_tmp = tracker_db_connect_file_content ();
- tracker_db_close (db_con_tmp);
- g_free (db_con_tmp);
+ tracker_db_close (main_thread_db_con);
- db_con_tmp = tracker_db_connect_email_content ();
- tracker_db_close (db_con_tmp);
- g_free (db_con_tmp);
+ /* This must be called after all other db functions */
+ tracker_db_finalize ();
+}
- db_con_tmp = tracker_db_connect_emails ();
- tracker_db_close (db_con_tmp);
- g_free (db_con_tmp);
+static void
+shutdown_directories (void)
+{
+ /* If we are reindexing, just remove the databases */
+ if (tracker->reindex) {
+ tracker_dir_remove (tracker->data_dir);
+ g_mkdir_with_parents (tracker->data_dir, 00755);
+ }
+ /* Remove sys tmp directory */
+ if (tracker->sys_tmp_root_dir) {
+ tracker_dir_remove (tracker->sys_tmp_root_dir);
+ }
}
gint
main (gint argc, gchar *argv[])
{
- gint lfp;
-#ifndef OS_WIN32
- struct sigaction act;
- sigset_t empty_mask;
-#endif
- gchar *lock_file, *str, *lock_str;
- GOptionContext *context = NULL;
- GError *error = NULL;
- gchar *example;
- gboolean need_index = FALSE;
- gboolean need_data;
- DBConnection *db_con;
- gchar *tmp_dir;
- gchar *old_tracker_dir;
- gchar *log_filename;
+ GOptionContext *context = NULL;
+ GError *error = NULL;
+ GSList *l;
+ gint lfp;
+ gchar *lock_file, *str, *lock_str;
+ gchar *example;
+ gboolean need_index = FALSE;
g_type_init ();
@@ -573,14 +742,17 @@
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
- /* set timezone info */
+ /* Set timezone info */
tzset ();
- /* Translators: this messagge will apper immediately after the */
- /* usage string - Usage: COMMAND <THIS_MESSAGE> */
+ /* Translators: this messagge will apper immediately after the
+ * usage string - Usage: COMMAND <THIS_MESSAGE>
+ */
context = g_option_context_new (_("- start the tracker daemon"));
- example = g_strconcat ("-i ", _("DIRECTORY"), " -i ", _("DIRECTORY"),
- " -e ", _("DIRECTORY"), " -e ", _("DIRECTORY"),
+ example = g_strconcat ("-i ", _("DIRECTORY"),
+ " -i ", _("DIRECTORY"),
+ " -e ", _("DIRECTORY"),
+ " -e ", _("DIRECTORY"),
NULL);
#ifdef HAVE_RECENT_GLIB
@@ -591,7 +763,8 @@
"at the same time, join multiple options like:"),
"\n\n\t",
- example, NULL));
+ example,
+ NULL));
#endif /* HAVE_RECENT_GLIB */
@@ -601,98 +774,44 @@
g_option_context_free (context);
g_free (example);
+ if (error) {
+ g_printerr ("Invalid arguments, %s\n", error->message);
+ g_clear_error (&error);
+ return EXIT_FAILURE;
+ }
+
+ /* Print information */
g_print ("\n" ABOUT "\n" LICENSE "\n");
g_print ("Initialising tracker...\n");
-#ifndef OS_WIN32
- /* trap signals */
- sigemptyset (&empty_mask);
- act.sa_handler = signal_handler;
- act.sa_mask = empty_mask;
- act.sa_flags = 0;
- sigaction (SIGTERM, &act, NULL);
- sigaction (SIGILL, &act, NULL);
- sigaction (SIGBUS, &act, NULL);
- sigaction (SIGFPE, &act, NULL);
- sigaction (SIGHUP, &act, NULL);
- sigaction (SIGSEGV, &act, NULL);
- sigaction (SIGABRT, &act, NULL);
- sigaction (SIGUSR1, &act, NULL);
- sigaction (SIGINT, &act, NULL);
-#endif
+ initialise_signal_handler ();
tracker = g_new0 (Tracker, 1);
- tracker_xesam_init ();
+ tracker->pid = getpid ();
+ tracker->dir_queue = g_async_queue_new ();
/* Set up directories */
- tracker->pid = (int) getpid ();
- tmp_dir = g_strdup_printf ("Tracker-%s.%d", g_get_user_name (), tracker->pid);
- tracker->sys_tmp_root_dir = g_build_filename (g_get_tmp_dir (), tmp_dir, NULL);
- g_free (tmp_dir);
+ initialise_directories ();
+ umask (077);
- tracker->root_dir = g_build_filename (g_get_user_data_dir (), "tracker", NULL);
- tracker->data_dir = g_build_filename (g_get_user_cache_dir (), "tracker", NULL);
- tracker->config_dir = g_strdup (g_get_user_config_dir ());
- tracker->user_data_dir = g_build_filename (tracker->root_dir, "data", NULL);
-
/* Set up the config */
tracker->config = tracker_config_new ();
tracker->language = tracker_language_new (tracker->config);
/* Set up the log */
- log_filename = g_build_filename (tracker->root_dir, "tracker.log", NULL);
- tracker_file_unlink (log_filename);
-
- tracker_log_init (log_filename,
+ tracker_log_init (tracker->log_filename,
tracker_config_get_verbosity (tracker->config),
fatal_errors);
tracker_log ("Starting log");
+ /* Set up locking */
tracker_nfs_lock_init (tracker->root_dir);
+
+ /* Set up xesam */
+ tracker_xesam_init ();
- /* Set up mutexes and intitial state */
- tracker->is_running = FALSE;
- tracker->shutdown = FALSE;
-
- tracker->files_check_mutex = g_mutex_new ();
- tracker->files_signal_mutex = g_mutex_new ();
- tracker->files_signal_cond = g_cond_new ();
-
- tracker->metadata_check_mutex = g_mutex_new ();
- tracker->metadata_signal_mutex = g_mutex_new ();
- tracker->metadata_signal_cond = g_cond_new ();
-
- /* Remove an existing one */
- if (g_file_test (tracker->sys_tmp_root_dir, G_FILE_TEST_EXISTS)) {
- tracker_dir_remove (tracker->sys_tmp_root_dir);
- }
-
- /* Remove old tracker dirs */
- old_tracker_dir = g_build_filename (g_get_home_dir (), ".Tracker", NULL);
-
- if (g_file_test (old_tracker_dir ,G_FILE_TEST_EXISTS)) {
- tracker_dir_remove (old_tracker_dir);
- }
-
- g_free (old_tracker_dir);
-
- /* Create other directories we need */
- if (!g_file_test (tracker->user_data_dir, G_FILE_TEST_EXISTS)) {
- g_mkdir_with_parents (tracker->user_data_dir, 00755);
- }
-
- if (!g_file_test (tracker->data_dir, G_FILE_TEST_EXISTS)) {
- g_mkdir_with_parents (tracker->data_dir, 00755);
- }
-
- tracker->email_attachements_dir = g_build_filename (tracker->sys_tmp_root_dir, "Attachments", NULL);
- g_mkdir_with_parents (tracker->email_attachements_dir, 00700);
- tracker_log ("Made email attachments directory %s\n", tracker->email_attachements_dir);
-
- tracker->dir_queue = g_async_queue_new ();
-
- tracker->xesam_dir = g_build_filename (g_get_home_dir (), ".xesam", NULL);
+ initialise_threading ();
if (reindex || tracker_db_needs_setup ()) {
tracker_dir_remove (tracker->data_dir);
@@ -700,37 +819,33 @@
need_index = TRUE;
}
- umask (077);
-
str = g_strconcat (g_get_user_name (), "_tracker_lock", NULL);
- /* check if setup for NFS usage (and enable atomic NFS safe locking) */
- //lock_str = tracker_get_config_option ("NFSLocking");
+ /* Check if setup for NFS usage (and enable atomic NFS safe locking) */
lock_str = NULL;
if (lock_str != NULL) {
-
tracker->use_nfs_safe_locking = (strcmp (str, "1") == 0);
- /* place lock file in tmp dir to allow multiple sessions on NFS */
+ /* Place lock file in tmp dir to allow multiple
+ * sessions on NFS.
+ */
lock_file = g_build_filename (tracker->sys_tmp_root_dir, str, NULL);
-
g_free (lock_str);
-
} else {
-
tracker->use_nfs_safe_locking = FALSE;
- /* place lock file in home dir to prevent multiple sessions on NFS (as standard locking might be broken on NFS) */
+ /* Place lock file in home dir to prevent multiple
+ * sessions on NFS (as standard locking might be
+ * broken on NFS)
+ */
lock_file = g_build_filename (tracker->root_dir, str, NULL);
}
g_free (str);
- /* prevent muliple instances */
- tracker->readonly = FALSE;
-
- lfp = g_open (lock_file, O_RDWR|O_CREAT, 0640);
+ /* Prevent muliple instances */
+ lfp = g_open (lock_file, O_RDWR | O_CREAT, 0640);
g_free (lock_file);
if (lfp < 0) {
@@ -745,25 +860,24 @@
/* Set child's niceness to 19 */
errno = 0;
- /* nice() uses attribute "warn_unused_result" and so complains if we do not check its
- returned value. But it seems that since glibc 2.2.4, nice() can return -1 on a
- successful call so we have to check value of errno too. Stupid... */
+
+ /* nice() uses attribute "warn_unused_result" and so complains
+ * if we do not check its returned value. But it seems that
+ * since glibc 2.2.4, nice() can return -1 on a successful
+ * call so we have to check value of errno too. Stupid...
+ */
if (nice (19) == -1 && errno) {
- g_printerr ("ERROR: trying to set nice value\n");
+ tracker_log ("Couldn't set nice() value");
}
#ifdef IOPRIO_SUPPORT
ioprio ();
#endif
-
- /* deal with config options with defaults, config file and option params */
- set_defaults ();
-
- if (error) {
- g_printerr ("invalid arguments: %s\n", error->message);
- return 1;
- }
+ /* Deal with config options with defaults, config file and
+ * option params.
+ */
+ initialise_defaults ();
if (watch_dirs) {
tracker_config_add_watch_directory_roots (tracker->config, watch_dirs);
@@ -803,7 +917,7 @@
sanity_check_option_values ();
- /* Initialize the service manager */
+ /* Initialise the service manager */
tracker_service_manager_init ();
/* Set thread safe DB connection */
@@ -814,118 +928,7 @@
return EXIT_FAILURE;
}
- /* FIXME: is this actually necessary? */
- db_con = tracker_db_connect_cache ();
- tracker_db_close (db_con);
-
- need_data = tracker_db_needs_data ();
-
- if (need_data) {
- tracker_create_common_db ();
- }
-
- if (!tracker->readonly && need_index) {
- create_index (need_data);
- } else {
- tracker->first_time_index = FALSE;
- }
-
- /* Set up main database connection */
- db_con = tracker_db_connect ();
-
- /* check db integrity if not previously shut down cleanly */
- if (!tracker->readonly && !need_index && tracker_db_get_option_int (db_con, "IntegrityCheck") == 1) {
-
- tracker_log ("performing integrity check as trackerd was not shutdown cleanly");
-
-
-/* turn off corruption check as it can hog cpu for long time
-
- if (!tracker_db_integrity_check (db_con) ||
- !tracker_indexer_repair (TRACKER_INDEXER_FILE_INDEX_DB_FILENAME) ||
- !tracker_indexer_repair (TRACKER_INDEXER_EMAIL_INDEX_DB_FILENAME)) {
- tracker_error ("db or index corruption detected - prepare for reindex...");
- tracker_db_close (db_con);
-
- tracker_dir_remove (tracker->data_dir);
- g_mkdir_with_parents (tracker->data_dir, 00755);
- create_index (need_data);
- db_con = tracker_db_connect ();
- db_con->thread = "main";
-
- }
-*/
- }
-
-
- if (!tracker->readonly) {
- tracker_db_set_option_int (db_con, "IntegrityCheck", 1);
- }
-
- if (tracker->first_time_index) {
- tracker_db_set_option_int (db_con, "InitialIndex", 1);
- }
-
- db_con->cache = tracker_db_connect_cache ();
- db_con->common = tracker_db_connect_common ();
-
- main_thread_db_con = db_con;
-
- /* move final file to index file if present and no files left to merge */
- char *final_index_name = g_build_filename (tracker->data_dir, "file-index-final", NULL);
-
- if (g_file_test (final_index_name, G_FILE_TEST_EXISTS) && !tracker_indexer_has_tmp_merge_files (INDEX_TYPE_FILES)) {
-
- char *file_index_name = g_build_filename (tracker->data_dir, TRACKER_INDEXER_FILE_INDEX_DB_FILENAME, NULL);
-
- tracker_log ("overwriting %s with %s", file_index_name, final_index_name);
-
- rename (final_index_name, file_index_name);
-
- g_free (file_index_name);
- }
-
- g_free (final_index_name);
-
- final_index_name = g_build_filename (tracker->data_dir, "email-index-final", NULL);
-
- if (g_file_test (final_index_name, G_FILE_TEST_EXISTS) && !tracker_indexer_has_tmp_merge_files (INDEX_TYPE_EMAILS)) {
-
- char *file_index_name = g_build_filename (tracker->data_dir, TRACKER_INDEXER_EMAIL_INDEX_DB_FILENAME, NULL);
-
- tracker_log ("overwriting %s with %s", file_index_name, final_index_name);
-
- rename (final_index_name, file_index_name);
-
- g_free (file_index_name);
- }
-
- g_free (final_index_name);
-
-
-
- Indexer *index = tracker_indexer_open (TRACKER_INDEXER_FILE_INDEX_DB_FILENAME, TRUE);
- tracker->file_index = index;
-
- index = tracker_indexer_open (TRACKER_INDEXER_FILE_UPDATE_INDEX_DB_FILENAME, FALSE);
- tracker->file_update_index = index;
-
- index = tracker_indexer_open (TRACKER_INDEXER_EMAIL_INDEX_DB_FILENAME, TRUE);
- tracker->email_index = index;
-
- db_con->word_index = tracker->file_index;
-
- tracker->update_count = get_update_count (main_thread_db_con);
-
- tracker_db_get_static_data (db_con);
-
- tracker->file_metadata_queue = g_async_queue_new ();
-
- if (!tracker->readonly) {
- tracker->file_process_queue = g_async_queue_new ();
- }
-
- tracker->loop = g_main_loop_new (NULL, FALSE);
+ initialise_databases (need_index);
tracker_email_init ();
@@ -934,9 +937,12 @@
tracker->hal = tracker_hal_new ();
#endif
- /* this var is used to tell the threads when to quit */
+ /* Set our status as running, if this is FALSE, threads stop
+ * doing what they do and shutdown.
+ */
tracker->is_running = TRUE;
+ /* Connect to databases */
tracker->index_db = tracker_db_connect_all ();
/* If we are already running, this should return some
@@ -947,22 +953,76 @@
}
if (!tracker->readonly) {
- if (!tracker_start_watching ()) {
- tracker_error ("ERROR: file monitoring failed to start");
- tracker_do_cleanup ("File watching failure");
- return EXIT_FAILURE;
+ if (G_UNLIKELY (!tracker_start_watching ())) {
+ tracker->is_running = FALSE;
+ tracker_error ("File monitoring failed to start");
+ } else {
+ 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_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);
+ if (tracker->is_running) {
+ main_loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (main_loop);
+ }
+
+ /*
+ * Shutdown the daemon
+ */
+ tracker->shutdown = TRUE;
+ tracker_status_set (TRACKER_STATUS_SHUTDOWN);
+
+ /* Reset black list files */
+ l = tracker_process_files_get_temp_black_list ();
+ g_slist_foreach (l, (GFunc) reset_blacklist_file, NULL);
+ g_slist_free (l);
+
+ /* 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;
+ }
+
+ /* Set kill timeout */
+ g_timeout_add_full (G_PRIORITY_LOW, 20000, shutdown_timeout_cb, NULL, NULL);
+
+ shutdown_threads ();
+ shutdown_indexer ();
+ shutdown_databases ();
+ shutdown_directories ();
+
+ /* Shutdown major subsystems */
+ if (tracker->hal) {
+ g_object_unref (tracker->hal);
+ tracker->hal = NULL;
+ }
+
+ if (tracker->language) {
+ tracker_language_free (tracker->language);
+ }
+
+ if (tracker->config) {
+ g_object_unref (tracker->config);
+ }
+
+ tracker_nfs_lock_term ();
+ tracker_log_term ();
+
+ /* FIXME: we need to clean up Tracker struct members */
return EXIT_SUCCESS;
}
+
+void
+tracker_shutdown (void)
+{
+ g_main_loop_quit (main_loop);
+}
Modified: branches/indexer-split/src/trackerd/tracker-main.h
==============================================================================
--- branches/indexer-split/src/trackerd/tracker-main.h (original)
+++ branches/indexer-split/src/trackerd/tracker-main.h Thu May 8 16:39:43 2008
@@ -53,8 +53,6 @@
} IndexStatus;
typedef struct {
- GMainLoop *loop;
-
gboolean is_running;
gboolean readonly;
@@ -79,6 +77,8 @@
gchar *services_dir;
gchar *xesam_dir;
+ gchar *log_filename;
+
/* Performance and memory usage options */
gint max_process_queue_size;
gint max_extract_queue_size;
@@ -133,7 +133,6 @@
/* Application run time values */
gint index_count;
- gint update_count;
/* Cache words before saving to word index */
GHashTable *file_word_table;
@@ -159,12 +158,12 @@
GHashTable *xesam_sessions;
} Tracker;
+void tracker_shutdown (void);
GSList * tracker_get_watch_root_dirs (void);
gboolean tracker_spawn (gchar **argv,
gint timeout,
gchar **tmp_stdout,
gint *exit_status);
-gboolean tracker_do_cleanup (const gchar *sig_msg);
gboolean tracker_watch_dir (const gchar *uri);
void tracker_scan_directory (const gchar *uri);
Modified: branches/indexer-split/src/trackerd/tracker-process-files.c
==============================================================================
--- branches/indexer-split/src/trackerd/tracker-process-files.c (original)
+++ branches/indexer-split/src/trackerd/tracker-process-files.c Thu May 8 16:39:43 2008
@@ -1189,8 +1189,6 @@
tracker_db_set_option_int (db_con, "InitialIndex", 0);
- tracker->update_count = 0;
-
tracker_log ("Updating database stats, please wait...");
tracker_db_interface_start_transaction (db_con->db);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]