[tracker/writeback] Make sure the fd isn't closed as long as the lock stays.
- From: Carlos Garnacho <carlosg src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker/writeback] Make sure the fd isn't closed as long as the lock stays.
- Date: Mon, 23 Nov 2009 13:44:16 +0000 (UTC)
commit f9d0465012bd0282e4f94faa5e90dae838bf68a0
Author: Carlos Garnacho <carlos lanedo com>
Date: Mon Nov 23 14:43:00 2009 +0100
Make sure the fd isn't closed as long as the lock stays.
src/libtracker-common/tracker-file-utils.c | 85 ++++++++++++++----------
src/tracker-writeback/tracker-writeback-file.c | 17 +++++-
2 files changed, 66 insertions(+), 36 deletions(-)
---
diff --git a/src/libtracker-common/tracker-file-utils.c b/src/libtracker-common/tracker-file-utils.c
index 5c5a36d..f58537a 100644
--- a/src/libtracker-common/tracker-file-utils.c
+++ b/src/libtracker-common/tracker-file-utils.c
@@ -45,6 +45,8 @@
#define TEXT_SNIFF_SIZE 4096
+static GHashTable *file_locks = NULL;
+
FILE *
tracker_file_open (const gchar *uri,
const gchar *how,
@@ -690,70 +692,80 @@ tracker_env_check_xdg_dirs (void)
return success;
}
-static int
-flock_file (GFile *file,
- gint flags)
+gboolean
+tracker_file_lock (GFile *file)
{
- gchar *path;
gint fd, retval;
+ gchar *path;
+
+ g_return_val_if_fail (G_IS_FILE (file), FALSE);
+
+ if (G_UNLIKELY (!file_locks)) {
+ file_locks = g_hash_table_new_full ((GHashFunc) g_file_hash,
+ (GEqualFunc) g_file_equal,
+ (GDestroyNotify) g_object_unref,
+ NULL);
+ }
- g_return_val_if_fail (G_IS_FILE (file), -1);
+ /* Don't try to lock twice */
+ if (g_hash_table_lookup (file_locks, file) != NULL) {
+ return TRUE;
+ }
if (!g_file_is_native (file)) {
- return -1;
+ return FALSE;
}
path = g_file_get_path (file);
if (!path) {
- return -1;
+ return FALSE;
}
fd = open (path, O_RDONLY);
if (fd < 0) {
- g_warning ("Could not open '%s'", path);
- retval = -1;
+ g_warning ("Could not open '%s'", path);
+ g_free (path);
+
+ return FALSE;
+ }
+
+ retval = flock (fd, LOCK_EX);
+
+ if (retval == 0) {
+ g_hash_table_insert (file_locks,
+ g_object_ref (file),
+ GINT_TO_POINTER (fd));
} else {
- retval = flock (fd, flags);
- close (fd);
+ g_warning ("Could not lock file '%s'", path);
+ close (fd);
}
g_free (path);
- return retval;
+ return (retval == 0);
}
gboolean
-tracker_file_lock (GFile *file)
+tracker_file_unlock (GFile *file)
{
- gint retval;
+ gint retval, fd;
- g_return_val_if_fail (G_IS_FILE (file), FALSE);
+ g_return_val_if_fail (G_IS_FILE (file), TRUE);
- retval = flock_file (file, LOCK_EX);
+ if (!file_locks) {
+ return TRUE;
+ }
- if (retval < 0) {
- gchar *path;
+ fd = GPOINTER_TO_INT (g_hash_table_lookup (file_locks, file));
- path = g_file_get_path (file);
- g_warning ("Could not lock file '%s'", path);
- g_free (path);
-
- return FALSE;
+ if (fd == 0) {
+ /* File wasn't actually locked */
+ return TRUE;
}
- return TRUE;
-}
-
-gboolean
-tracker_file_unlock (GFile *file)
-{
- gint retval;
-
- g_return_val_if_fail (G_IS_FILE (file), FALSE);
-
- retval = flock_file (file, LOCK_UN);
+ retval = flock (fd, LOCK_UN);
if (retval < 0) {
gchar *path;
@@ -765,6 +777,9 @@ tracker_file_unlock (GFile *file)
return FALSE;
}
+ g_hash_table_remove (file_locks, file);
+ close (fd);
+
return TRUE;
}
@@ -797,7 +812,7 @@ tracker_file_is_locked (GFile *file)
}
/* Check for locks */
- retval = flock (fd, LOCK_EX | LOCK_NB);
+ retval = flock (fd, LOCK_SH | LOCK_NB);
if (retval < 0) {
if (errno == EWOULDBLOCK) {
diff --git a/src/tracker-writeback/tracker-writeback-file.c b/src/tracker-writeback/tracker-writeback-file.c
index a6b370e..cae2736 100644
--- a/src/tracker-writeback/tracker-writeback-file.c
+++ b/src/tracker-writeback/tracker-writeback-file.c
@@ -43,6 +43,21 @@ tracker_writeback_file_init (TrackerWritebackFile *writeback_file)
}
static gboolean
+unlock_file_cb (GFile *file)
+{
+ gchar *path;
+
+ path = g_file_get_path (file);
+ g_message ("Unlocking file '%s'", path);
+ g_free (path);
+
+ tracker_file_unlock (file);
+ g_object_unref (file);
+
+ return FALSE;
+}
+
+static gboolean
tracker_writeback_file_update_metadata (TrackerWriteback *writeback,
GPtrArray *values)
{
@@ -77,7 +92,7 @@ tracker_writeback_file_update_metadata (TrackerWriteback *writeback,
retval = (writeback_file_class->update_file_metadata) (TRACKER_WRITEBACK_FILE (writeback),
file, values);
- tracker_file_unlock (file);
+ g_timeout_add_seconds (3, (GSourceFunc) unlock_file_cb, g_object_ref (file));
g_object_unref (file);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]