diff -u -p -r1.53 rb-file-helpers.c
--- lib/rb-file-helpers.c	17 Jul 2006 14:51:23 -0000	1.53
+++ lib/rb-file-helpers.c	25 Jul 2006 06:12:43 -0000
@@ -629,12 +629,23 @@ escape_extra_gnome_vfs_chars (char *uri)
 }
 
 typedef struct {
-	const char *uri;
+	char *uri;
 	GFunc func;
 	gpointer user_data;
 	gboolean *cancel_flag;
+	GDestroyNotify data_destroy;
 } RBUriHandleRecursivelyData;
 
+static void
+_rb_uri_recurse_data_free (RBUriHandleRecursivelyData *data)
+{
+	g_free (data->uri);
+	if (data->data_destroy)
+		data->data_destroy (data->user_data);
+
+	g_free (data);
+}
+
 static gboolean
 rb_uri_handle_recursively_cb (const gchar *rel_path,
 			      GnomeVFSFileInfo *info,
@@ -642,6 +653,8 @@ rb_uri_handle_recursively_cb (const gcha
 			      RBUriHandleRecursivelyData *data,
 			      gboolean *recurse)
 {
+	char *path, *escaped_rel_path;
+
 	if (data->cancel_flag && *data->cancel_flag)
 		return TRUE;
 
@@ -653,16 +666,12 @@ rb_uri_handle_recursively_cb (const gcha
 		return TRUE;
 	}
 
-	if (info->type == GNOME_VFS_FILE_TYPE_REGULAR) {
-		char *path, *escaped_rel_path;
-
-		escaped_rel_path = gnome_vfs_escape_path_string (rel_path);
-		escaped_rel_path = escape_extra_gnome_vfs_chars (escaped_rel_path);
-		path = g_build_filename (data->uri, escaped_rel_path, NULL);
-		(data->func) (path, data->user_data);
-		g_free (escaped_rel_path);
-		g_free (path);
-	}
+	escaped_rel_path = gnome_vfs_escape_path_string (rel_path);
+	escaped_rel_path = escape_extra_gnome_vfs_chars (escaped_rel_path);
+	path = g_build_filename (data->uri, escaped_rel_path, NULL);
+	(data->func) (path, data->user_data);
+	g_free (escaped_rel_path);
+	g_free (path);
 
 	*recurse = !recursing_will_loop;
 	return TRUE;
@@ -678,10 +687,11 @@ rb_uri_handle_recursively (const char *t
 	GnomeVFSFileInfoOptions flags;
 	GnomeVFSResult result;
 	
-	data->uri = text_uri;
+	data->uri = g_strdup (text_uri);
 	data->func = func;
 	data->user_data = user_data;
 	data->cancel_flag = cancelflag;
+	data->data_destroy = NULL;
 
 	flags = GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
 		GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE |
@@ -692,8 +702,47 @@ rb_uri_handle_recursively (const char *t
 					    GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK,
 					    (GnomeVFSDirectoryVisitFunc)rb_uri_handle_recursively_cb,
 					    data);
-	g_free (data);
+	_rb_uri_recurse_data_free (data);
 }
+
+static gpointer
+_recurse_async_func (RBUriHandleRecursivelyData *data)
+{
+	GnomeVFSFileInfoOptions flags;
+	GnomeVFSResult result;
+
+	flags = GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
+		GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE |
+		GNOME_VFS_FILE_INFO_FOLLOW_LINKS |
+		GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS;
+	result = gnome_vfs_directory_visit (data->uri,
+					    flags,
+					    GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK,
+					    (GnomeVFSDirectoryVisitFunc)rb_uri_handle_recursively_cb,
+					    data);
+	
+	_rb_uri_recurse_data_free (data);
+	return NULL;
+}
+
+void
+rb_uri_handle_recursively_async (const char *text_uri,
+			         GFunc func,
+				 gboolean *cancelflag,
+			         gpointer user_data,
+				 GDestroyNotify data_destroy)
+{
+	RBUriHandleRecursivelyData *data = g_new0 (RBUriHandleRecursivelyData, 1);
+	
+	data->uri = g_strdup (text_uri);
+	data->func = func;
+	data->user_data = user_data;
+	data->cancel_flag = cancelflag;
+	data->data_destroy = data_destroy;
+
+	g_thread_create ((GThreadFunc)_recurse_async_func, data, FALSE, NULL);
+}
+
 
 GnomeVFSResult
 rb_uri_mkstemp (const char *prefix, char **uri_ret, GnomeVFSHandle **ret)
diff -u -p -r1.24 rb-file-helpers.h
--- lib/rb-file-helpers.h	20 Apr 2006 20:43:21 -0000	1.24
+++ lib/rb-file-helpers.h	25 Jul 2006 06:12:43 -0000
@@ -49,6 +49,12 @@ void		rb_uri_handle_recursively(const ch
 					  gboolean *cancelflag,
 					  gpointer user_data);
 
+void		rb_uri_handle_recursively_async(const char *uri,
+						GFunc func,
+						gboolean *cancelflag,
+						gpointer user_data,
+						GDestroyNotify data_destroy);
+
 char*		rb_uri_append_path	(const char *uri,
 					 const char *path);
 char*		rb_uri_append_uri	(const char *uri,
diff -u -p -r1.5 rhythmdb-monitor.c
--- rhythmdb/rhythmdb-monitor.c	14 Jul 2006 12:29:27 -0000	1.5
+++ rhythmdb/rhythmdb-monitor.c	25 Jul 2006 06:14:24 -0000
@@ -29,6 +29,7 @@
 #include <libgnomevfs/gnome-vfs-volume-monitor.h>
 
 #include "rb-debug.h"
+#include "rb-util.h"
 #include "rhythmdb.h"
 #include "rhythmdb-private.h"
 #include "rb-file-helpers.h"
@@ -49,7 +50,7 @@ rhythmdb_init_monitoring (RhythmDB *db)
 {
 	db->priv->monitored_directories = g_hash_table_new_full (g_str_hash, g_str_equal,
 								 (GDestroyNotify) g_free,
-								 NULL);
+								 (GDestroyNotify)gnome_vfs_monitor_cancel);
 
 	db->priv->changed_files = g_hash_table_new_full (g_str_hash, g_str_equal,
 							 (GDestroyNotify) g_free,
@@ -81,74 +82,54 @@ rhythmdb_finalize_monitoring (RhythmDB *
 	g_hash_table_destroy (db->priv->changed_files);
 }
 
-static gboolean
-rhythmdb_unmonitor_directories (char *dir, GnomeVFSMonitorHandle *handle, RhythmDB *db)
-{
-	gnome_vfs_monitor_cancel (handle);
-	return TRUE;
-}
-
 void
 rhythmdb_stop_monitoring (RhythmDB *db)
 {
 	g_hash_table_foreach_remove (db->priv->monitored_directories,
-				     (GHRFunc) rhythmdb_unmonitor_directories,
+				     (GHRFunc) rb_true_function,
 				     db);
 }
 
 static void
 monitor_entry_file (RhythmDBEntry *entry, RhythmDB *db)
 {
-	GError *error = NULL;
-
 	if (entry->type == RHYTHMDB_ENTRY_TYPE_SONG) {
-		rhythmdb_monitor_uri_path (db, entry->location, &error);
-	}
+		const char *loc;
+		GSList *l;
+
+		loc = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
 
-	if (error) {
-		/* FIXME: should we complain to the user? */
-		rb_debug ("error while attempting to monitor library track: %s", error->message);
+		/* don't add add monitor if it's in the library path*/
+		for (l = db->priv->library_locations; l != NULL; l = g_slist_next (l)) {
+			if (g_str_has_prefix (loc, (const char*)l->data))
+				return;
+				
+		}
+		rhythmdb_monitor_uri_path (db, entry->location, NULL);
 	}
 }
 
 static void
 monitor_subdirectory (const char *uri, RhythmDB *db)
 {
-	GError *error = NULL;
-
-	if (!rb_uri_is_directory (uri))
-		return;
-
-	rhythmdb_monitor_uri_path (db, uri, &error);
-
-	if (error) {
-		/* FIXME: should we complain to the user? */
-		rb_debug ("error while attempting to monitor the library directory: %s", error->message);
-	}
+	if (rb_uri_is_directory (uri))
+		rhythmdb_monitor_uri_path (db, uri, NULL);
+	else
+		rhythmdb_add_uri (db, uri);
 }
 
 static void
 monitor_library_directory (const char *uri, RhythmDB *db)
 {
-	GError *error = NULL;
-
 	if ((strcmp (uri, "file:///") == 0) ||
 	    (strcmp (uri, "file://") == 0)) {
-		/* display an error to the user? */
 		return;
 	}
 
 	rb_debug ("beginning monitor of the library directory %s", uri);
-	rhythmdb_monitor_uri_path (db, uri, &error);
-	rb_uri_handle_recursively (uri, (GFunc) monitor_subdirectory, NULL, db);
-
-	if (error) {
-		/* FIXME: should we complain to the user? */
-		rb_debug ("error while attempting to monitor the library directory: %s", error->message);
-	}
-
-	rb_debug ("loading new tracks from library directory %s", uri);
-	rhythmdb_add_uri (db, uri);
+	rhythmdb_monitor_uri_path (db, uri, NULL);
+	rb_uri_handle_recursively_async (uri, (GFunc) monitor_subdirectory, NULL,
+					 g_object_ref (db), (GDestroyNotify)g_object_unref);
 }
 
 static gboolean
@@ -183,18 +164,25 @@ rhythmdb_process_changed_files (RhythmDB
 	return TRUE;
 }
 
+static gpointer
+_monitor_entry_thread (RhythmDB *db)
+{
+	rhythmdb_entry_foreach (db, (GFunc) monitor_entry_file, db);
+	g_object_unref (G_OBJECT (db));
+	return NULL;
+}
+
 void
 rhythmdb_start_monitoring (RhythmDB *db)
 {
 	db->priv->changed_files_id = g_timeout_add (RHYTHMDB_FILE_MODIFY_PROCESS_TIME * 1000,
 						    (GSourceFunc) rhythmdb_process_changed_files, db);
 
-	if (db->priv->library_locations) {
-		g_slist_foreach (db->priv->library_locations, (GFunc) monitor_library_directory, db);
-	}
+	g_thread_create ((GThreadFunc)_monitor_entry_thread, g_object_ref (db), FALSE, NULL);
 
-	/* monitor every directory that contains a (TYPE_SONG) track */
-	rhythmdb_entry_foreach (db, (GFunc) monitor_entry_file, db);
+	/* monitor all library locations */
+	if (db->priv->library_locations)
+		g_slist_foreach (db->priv->library_locations, (GFunc) monitor_library_directory, db);
 }
 
 static void
@@ -266,7 +254,7 @@ rhythmdb_monitor_uri_path (RhythmDB *db,
 {
 	char *directory;
 	GnomeVFSResult vfsresult;
-	GnomeVFSMonitorHandle **handle;
+	GnomeVFSMonitorHandle *handle = NULL;
 
 	if (rb_uri_is_directory (uri)) {
 		if (g_str_has_suffix(uri, G_DIR_SEPARATOR_S)) {
@@ -284,18 +272,19 @@ rhythmdb_monitor_uri_path (RhythmDB *db,
 		gnome_vfs_uri_unref (parent);
 	}
 
-	if (directory == NULL || g_hash_table_lookup (db->priv->monitored_directories, directory))
+	if (directory == NULL || g_hash_table_lookup (db->priv->monitored_directories, directory)) {
+		g_free (directory);
 		return;
+	}
 
-	handle = g_new0 (GnomeVFSMonitorHandle *, 1);
-	vfsresult = gnome_vfs_monitor_add (handle, directory,
+	vfsresult = gnome_vfs_monitor_add (&handle, directory,
 					   GNOME_VFS_MONITOR_DIRECTORY,
 					   (GnomeVFSMonitorCallback) rhythmdb_directory_change_cb,
 					   db);
 	if (vfsresult == GNOME_VFS_OK) {
 		rb_debug ("monitoring: %s", directory);
 		g_hash_table_insert (db->priv->monitored_directories,
-				     directory, *handle);
+				     directory, handle);
 	} else {
 		g_set_error (error,
 			     RHYTHMDB_ERROR,
@@ -305,7 +294,6 @@ rhythmdb_monitor_uri_path (RhythmDB *db,
 			     gnome_vfs_result_to_string (vfsresult));
 		rb_debug ("failed to monitor %s", directory);
 		g_free (directory);
-		g_free (handle);
 	}
 }
 
diff -u -p -r1.241 rhythmdb.c
--- rhythmdb/rhythmdb.c	23 Jul 2006 16:02:59 -0000	1.241
+++ rhythmdb/rhythmdb.c	25 Jul 2006 06:14:29 -0000
@@ -1495,9 +1495,6 @@ rhythmdb_process_stat_event (RhythmDB *d
 
 			if (mtime == event->vfsinfo->mtime) {
 				rb_debug ("not modified: %s", event->real_uri);
-				/* monitor the file for changes */
-				if (eel_gconf_get_boolean (CONF_MONITOR_LIBRARY))
-					rhythmdb_monitor_uri_path (db, entry->location, NULL /* FIXME */);
 			} else {
 				RhythmDBEvent *new_event;
 
