[rhythmbox] rhythmdb: use queries to find entries on (un)mounted volumes
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] rhythmdb: use queries to find entries on (un)mounted volumes
- Date: Thu, 19 Aug 2010 13:16:59 +0000 (UTC)
commit 9f506e0db8eb1b70f75723dbcb3706fa3a82b6c3
Author: Jonathan Matthew <jonathan d14n org>
Date: Thu Aug 19 23:07:43 2010 +1000
rhythmdb: use queries to find entries on (un)mounted volumes
Aside from being a simpler way of doing it, this fixes a deadlock when
an import error entry exists on a volume that is unmounted.
rhythmdb_entry_foreach_by_type callbacks are held with various internal
locks held, and since they aren't recursive locks, calling rhythmdb functions
from there is dangerous.
rhythmdb/rhythmdb-monitor.c | 125 ++++++++++++++++++++-----------------------
1 files changed, 59 insertions(+), 66 deletions(-)
---
diff --git a/rhythmdb/rhythmdb-monitor.c b/rhythmdb/rhythmdb-monitor.c
index 88a06d6..9484943 100644
--- a/rhythmdb/rhythmdb-monitor.c
+++ b/rhythmdb/rhythmdb-monitor.c
@@ -40,6 +40,7 @@
#include "rb-util.h"
#include "rhythmdb.h"
#include "rhythmdb-private.h"
+#include "rhythmdb-query-result-list.h"
#include "rb-file-helpers.h"
#include "rb-preferences.h"
#include "eel-gconf-extensions.h"
@@ -414,70 +415,75 @@ rhythmdb_monitor_uri_path (RhythmDB *db, const char *uri, GError **error)
g_object_unref (directory);
}
-typedef struct
-{
- RhythmDB *db;
- RBRefString *mount_point;
- RhythmDBEntryAvailability avail;
-} MountCtxt;
-
static void
-entry_volume_mounted_or_unmounted (RhythmDBEntry *entry,
- MountCtxt *ctxt)
+rhythmdb_mount_added_cb (GVolumeMonitor *monitor,
+ GMount *mount,
+ RhythmDB *db)
{
- RBRefString *mount_point;
-
- mount_point = rhythmdb_entry_get_refstring (entry, RHYTHMDB_PROP_MOUNTPOINT);
- if (mount_point == NULL || !rb_refstring_equal (mount_point, ctxt->mount_point)) {
- return;
- }
+ GList *l;
+ RhythmDBQueryResultList *list;
+ char *mountpoint;
+ GFile *root;
- rhythmdb_entry_update_availability (entry, ctxt->avail);
- rhythmdb_commit (ctxt->db);
+ root = g_mount_get_root (mount);
+ mountpoint = g_file_get_uri (root);
+ rb_debug ("volume %s mounted", mountpoint);
+ g_object_unref (root);
- /* check local files when mounted */
- if (ctxt->avail == RHYTHMDB_ENTRY_AVAIL_MOUNTED) {
+ list = rhythmdb_query_result_list_new ();
+ rhythmdb_do_full_query (db,
+ RHYTHMDB_QUERY_RESULTS (list),
+ RHYTHMDB_QUERY_PROP_EQUALS,
+ RHYTHMDB_PROP_TYPE,
+ RHYTHMDB_ENTRY_TYPE_SONG,
+ RHYTHMDB_QUERY_PROP_EQUALS,
+ RHYTHMDB_PROP_MOUNTPOINT,
+ mountpoint,
+ RHYTHMDB_QUERY_END);
+ l = rhythmdb_query_result_list_get_results (list);
+ rb_debug ("%d mounted entries to process", g_list_length (l));
+ for (; l != NULL; l = l->next) {
+ RhythmDBEntry *entry = l->data;
const char *location = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
+
+ rhythmdb_entry_update_availability (entry, RHYTHMDB_ENTRY_AVAIL_MOUNTED);
if (rb_uri_is_local (location)) {
- rhythmdb_add_uri_with_types (ctxt->db,
+ rhythmdb_add_uri_with_types (db,
location,
RHYTHMDB_ENTRY_TYPE_SONG,
RHYTHMDB_ENTRY_TYPE_IGNORE,
RHYTHMDB_ENTRY_TYPE_IMPORT_ERROR);
}
-
}
+ g_object_unref (list);
+ g_free (mountpoint);
+ rhythmdb_commit (db);
}
static void
-rhythmdb_mount_added_cb (GVolumeMonitor *monitor,
- GMount *mount,
- RhythmDB *db)
+process_unmounted_entries (RhythmDB *db, RhythmDBEntryType *entry_type, const char *mountpoint)
{
- MountCtxt ctxt;
- char *mp;
- GFile *root;
-
- root = g_mount_get_root (mount);
- mp = g_file_get_uri (root);
- g_object_unref (root);
-
- ctxt.mount_point = rb_refstring_new (mp);
- g_free (mp);
-
- ctxt.db = db;
- ctxt.avail = RHYTHMDB_ENTRY_AVAIL_MOUNTED;
- rb_debug ("volume %s mounted", rb_refstring_get (ctxt.mount_point));
- rhythmdb_entry_foreach_by_type (db,
- RHYTHMDB_ENTRY_TYPE_SONG,
- (GFunc) entry_volume_mounted_or_unmounted,
- &ctxt);
- rhythmdb_entry_foreach_by_type (db,
- RHYTHMDB_ENTRY_TYPE_IMPORT_ERROR,
- (GFunc) entry_volume_mounted_or_unmounted,
- &ctxt);
+ RhythmDBQueryResultList *list;
+ GList *l;
+
+ list = rhythmdb_query_result_list_new ();
+ rhythmdb_do_full_query (db,
+ RHYTHMDB_QUERY_RESULTS (list),
+ RHYTHMDB_QUERY_PROP_EQUALS,
+ RHYTHMDB_PROP_TYPE,
+ entry_type,
+ RHYTHMDB_QUERY_PROP_EQUALS,
+ RHYTHMDB_PROP_MOUNTPOINT,
+ mountpoint,
+ RHYTHMDB_QUERY_END);
+ l = rhythmdb_query_result_list_get_results (list);
+ rb_debug ("%d unmounted entries to process", g_list_length (l));
+ for (; l != NULL; l = l->next) {
+ RhythmDBEntry *entry = l->data;
+ rhythmdb_entry_update_availability (entry, RHYTHMDB_ENTRY_AVAIL_UNMOUNTED);
+ }
+ g_object_unref (list);
rhythmdb_commit (db);
- rb_refstring_unref (ctxt.mount_point);
}
static void
@@ -485,30 +491,17 @@ rhythmdb_mount_removed_cb (GVolumeMonitor *monitor,
GMount *mount,
RhythmDB *db)
{
- MountCtxt ctxt;
- char *mp;
+ char *mountpoint;
GFile *root;
root = g_mount_get_root (mount);
- mp = g_file_get_uri (root);
+ mountpoint = g_file_get_uri (root);
+ rb_debug ("volume %s unmounted", mountpoint);
g_object_unref (root);
- ctxt.mount_point = rb_refstring_new (mp);
- g_free (mp);
-
- ctxt.db = db;
- ctxt.avail = RHYTHMDB_ENTRY_AVAIL_UNMOUNTED;
- rb_debug ("volume %s unmounted", rb_refstring_get (ctxt.mount_point));
- rhythmdb_entry_foreach_by_type (db,
- RHYTHMDB_ENTRY_TYPE_SONG,
- (GFunc) entry_volume_mounted_or_unmounted,
- &ctxt);
- rhythmdb_entry_foreach_by_type (db,
- RHYTHMDB_ENTRY_TYPE_IMPORT_ERROR,
- (GFunc) entry_volume_mounted_or_unmounted,
- &ctxt);
- rhythmdb_commit (db);
- rb_refstring_unref (ctxt.mount_point);
+ process_unmounted_entries (db, RHYTHMDB_ENTRY_TYPE_SONG, mountpoint);
+ process_unmounted_entries (db, RHYTHMDB_ENTRY_TYPE_IMPORT_ERROR, mountpoint);
+ g_free (mountpoint);
}
GList *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]