diff -u -u -r1.181 rhythmdb.c
--- rhythmdb/rhythmdb.c	1 Mar 2006 12:19:09 -0000	1.181
+++ rhythmdb/rhythmdb.c	2 Mar 2006 08:22:42 -0000
@@ -101,7 +101,7 @@
 	gboolean no_update;
 
 	GMutex *change_mutex;
-	GList *added_entries;
+	GHashTable *added_entries;
 	GHashTable *changed_entries;
 
 	GHashTable *propname_map;
@@ -228,7 +228,6 @@
 static void rhythmdb_monitor_uri_path (RhythmDB *db,
 				       const char *uri,
 				       GError **error);
-static gboolean timeout_rhythmdb_commit (RhythmDB *db);
 
 enum
 {
@@ -503,6 +502,7 @@
 
 	db->priv->change_mutex = g_mutex_new ();
 	db->priv->changed_entries = g_hash_table_new (NULL, NULL);
+	db->priv->added_entries = g_hash_table_new (NULL, NULL);
 	
 	db->priv->event_poll_id = g_idle_add ((GSourceFunc) rhythmdb_idle_poll_events, db);
 
@@ -803,46 +803,96 @@
 	}
 }
 
+typedef struct {
+	RhythmDB *db;
+	GList *entries;
+} EmitEntryiesData;
 
-static void
-rhythmdb_commit_internal (RhythmDB *db, gboolean sync_changes)
+static gboolean
+rhythmdb_emit_entries_added_idle (EmitEntryiesData *data)
 {
-	GList *tem;
+	GList *l;
 
-	g_assert (rb_is_main_thread ());
+	for (l = data->entries; l != NULL; l = g_list_next (l))
+		g_signal_emit (G_OBJECT (data->db), rhythmdb_signals[ENTRY_ADDED], 0, l->data);
+
+	g_list_free (data->entries);
+	g_free (data);
+	return FALSE;
+}
+
+static gboolean
+process_added_entries_cb (RhythmDBEntry *entry, GThread *thread, EmitEntryiesData *data)
+{
+	if (thread != g_thread_self ())
+		return FALSE;
+	
+	if (entry->type == RHYTHMDB_ENTRY_TYPE_SONG) {
+		const gchar *uri;
+
+		uri = rhythmdb_entry_get_string (entry, 
+						 RHYTHMDB_PROP_LOCATION);
+
+		/* always start remote files hidden*/
+		if (!g_str_has_prefix (uri, "file://"))
+			entry->hidden = TRUE;
+
+		queue_stat_uri (uri, data->db, -1);
+	}
+
+	data->entries = g_list_prepend (data->entries, entry);
+	g_assert (entry->inserted == FALSE);
+	entry->inserted = TRUE;
+	return TRUE;
+}
+
+static void
+rhythmdb_commit_internal (RhythmDB *db, gboolean sync_changes, GThread *thread)
+{
+	EmitEntryiesData *data;
 
 	g_mutex_lock (db->priv->change_mutex);
+
 	g_hash_table_foreach (db->priv->changed_entries, (GHFunc) emit_entry_changed, db);
 	if (sync_changes)
 		g_hash_table_foreach (db->priv->changed_entries, (GHFunc) sync_entry_changed, db);
 	g_hash_table_foreach_remove (db->priv->changed_entries, (GHRFunc) free_entry_changes, db);
 
-	for (tem = db->priv->added_entries; tem; tem = tem->next) {
-		RhythmDBEntry *entry = tem->data;
+	data = g_new0 (EmitEntryiesData, 1);
+	data->db = db;
+	data->entries = NULL;
+	g_hash_table_foreach_remove (db->priv->added_entries, (GHRFunc) process_added_entries_cb, data);
+	g_idle_add ((GSourceFunc)rhythmdb_emit_entries_added_idle, data);
 
-		if (entry->type == RHYTHMDB_ENTRY_TYPE_SONG) {
-			const gchar *uri;
+	g_mutex_unlock (db->priv->change_mutex);
+}
 
-			uri = rhythmdb_entry_get_string (entry, 
-							 RHYTHMDB_PROP_LOCATION);
+typedef struct {
+	RhythmDB *db;
+	gboolean sync;
+	GThread *thread;
+} RhythmDBTimoutCommitData;
 
-			/* always start remote files hidden*/
-			if (!g_str_has_prefix (uri, "file://"))
-				entry->hidden = TRUE;
+static gboolean
+timeout_rhythmdb_commit (RhythmDBTimoutCommitData *data)
+{
+	rhythmdb_commit_internal (data->db, data->sync, data->thread);
+	g_free (data);
+	return FALSE;
+}
 
-			queue_stat_uri (uri, db, -1);
-		}
-		rhythmdb_emit_entry_added (db, entry);
-		g_assert (entry->inserted == FALSE);
-		entry->inserted = TRUE;
-	}
+static void
+rhythmdb_add_timeout_commit (RhythmDB *db, gboolean sync)
+{
+	RhythmDBTimoutCommitData *data;
 
-	g_list_free (db->priv->added_entries);
-	db->priv->added_entries = NULL;
-	g_mutex_unlock (db->priv->change_mutex);
+	data = g_new0 (RhythmDBTimoutCommitData, 1);
+	data->db = db;
+	data->sync = sync;
+	data->thread = g_thread_self ();
+	g_timeout_add (100, (GSourceFunc)timeout_rhythmdb_commit, data);
 }
 
-
 /**
  * rhythmdb_commit:
  * @db: a #RhythmDB.
@@ -854,24 +904,9 @@
 void
 rhythmdb_commit (RhythmDB *db)
 {
-	if (rb_is_main_thread ())
-		rhythmdb_commit_internal (db, TRUE);
-	else {
-		if (!db->priv->commit_timeout_id)
-			db->priv->commit_timeout_id = g_timeout_add (100, (GSourceFunc)timeout_rhythmdb_commit, db);
-	}
-}
-
-static gboolean
-timeout_rhythmdb_commit (RhythmDB *db)
-{
-	db->priv->commit_timeout_id = 0;
-	rhythmdb_commit_internal (RHYTHMDB (db), TRUE);
-
-	return FALSE;
+	rhythmdb_commit_internal (db, TRUE, g_thread_self ());
 }
 
-
 GQuark
 rhythmdb_error_quark (void)
 {
@@ -943,7 +978,7 @@
 	g_return_if_fail (entry->location != NULL);
 	
 	g_mutex_lock (db->priv->change_mutex);
-	db->priv->added_entries = g_list_prepend (db->priv->added_entries, entry);	
+	g_hash_table_insert (db->priv->added_entries, entry, g_thread_self ());
 	g_mutex_unlock (db->priv->change_mutex);
 }
 
@@ -1514,7 +1549,7 @@
 			g_value_unset (&value);
 		}
 
-		rhythmdb_commit_internal (db, FALSE);
+		rhythmdb_add_timeout_commit (db, FALSE);
 	} 
 
 	if (entry == NULL) {
@@ -1538,7 +1573,7 @@
 
 		rhythmdb_entry_set_visibility (db, entry, TRUE);
 
-		rhythmdb_commit_internal (db, FALSE);
+		rhythmdb_add_timeout_commit (db, FALSE);
 	}
 }
 
@@ -1641,7 +1676,7 @@
 	if (eel_gconf_get_boolean (CONF_MONITOR_LIBRARY))
 		rhythmdb_monitor_uri_path (db, entry->location, NULL);
 
-	rhythmdb_commit_internal (db, FALSE);
+	rhythmdb_add_timeout_commit (db, FALSE);
 	
 	return TRUE;
 }
@@ -1658,9 +1693,7 @@
 	 * we can run a single commit for several queued 
 	 * entry_set
 	 */
-	if (!db->priv->commit_timeout_id) {
-		db->priv->commit_timeout_id = g_timeout_add (100, (GSourceFunc)timeout_rhythmdb_commit, db);
-	}
+	rhythmdb_add_timeout_commit (db, TRUE);
 }
 
 static void
@@ -3627,12 +3660,6 @@
 	}
 
 	return etype;
-}
-
-void
-rhythmdb_emit_entry_added (RhythmDB *db, RhythmDBEntry *entry)
-{
-	g_signal_emit (G_OBJECT (db), rhythmdb_signals[ENTRY_ADDED], 0, entry);
 }
 
 void
