gvfs r2261 - in trunk: . daemon/trashlib
- From: ryanl svn gnome org
- To: svn-commits-list gnome org
- Subject: gvfs r2261 - in trunk: . daemon/trashlib
- Date: Fri, 27 Feb 2009 23:04:31 +0000 (UTC)
Author: ryanl
Date: Fri Feb 27 23:04:31 2009
New Revision: 2261
URL: http://svn.gnome.org/viewvc/gvfs?rev=2261&view=rev
Log:
2009-02-27 Ryan Lortie <desrt desrt ca>
* daemon/trashlib/dirwatch.c:
* daemon/trashlib/dirwatch.h:
* daemon/trashlib/trashdir.c:
* daemon/trashlib/trashitem.c:
Use DirWatch only when watching (move broken manual-scan code out).
Fix a bunch of leaks.
Modified:
trunk/ChangeLog
trunk/daemon/trashlib/dirwatch.c
trunk/daemon/trashlib/dirwatch.h
trunk/daemon/trashlib/trashdir.c
trunk/daemon/trashlib/trashitem.c
Modified: trunk/daemon/trashlib/dirwatch.c
==============================================================================
--- trunk/daemon/trashlib/dirwatch.c (original)
+++ trunk/daemon/trashlib/dirwatch.c Fri Feb 27 23:04:31 2009
@@ -42,6 +42,13 @@
* stops existing momentarily will (hopefully) always be reported.
* The first call (if it happens) will always be to create().
*
+ * check() is only ever called in response to a call to
+ * dir_watch_check() in which case it will be called only if the
+ * watched directory was marked as having existed before the check and
+ * is found to still exist. This facilitates the checking that has to
+ * occur in that case (ie: check the contents of the directory to make
+ * sure that they are also unchanged).
+ *
* This implementation is currently tweaked a bit for how GFileMonitor
* currently works with inotify. If GFileMonitor's implementation is
* changed it might be a good idea to take another look at this code.
@@ -53,10 +60,10 @@
GFile *topdir;
DirWatchFunc create;
+ DirWatchFunc check;
DirWatchFunc destroy;
gpointer user_data;
gboolean state;
- gboolean active;
DirWatch *parent;
@@ -172,6 +179,29 @@
}
static void
+dir_watch_recursive_check (gpointer user_data)
+{
+ DirWatch *watch = user_data;
+ gboolean exists;
+
+ exists = dir_exists (watch->directory);
+
+ if (watch->state && exists)
+ watch->check (watch->user_data);
+
+ else if (!watch->state && exists)
+ {
+ watch->state = TRUE;
+ dir_watch_created (watch);
+ }
+ else if (watch->state && !exists)
+ {
+ watch->state = FALSE;
+ dir_watch_destroyed (watch);
+ }
+}
+
+static void
dir_watch_recursive_destroy (gpointer user_data)
{
DirWatch *watch = user_data;
@@ -193,8 +223,8 @@
DirWatch *
dir_watch_new (GFile *directory,
GFile *topdir,
- gboolean watching,
DirWatchFunc create,
+ DirWatchFunc check,
DirWatchFunc destroy,
gpointer user_data)
{
@@ -202,6 +232,7 @@
watch = g_slice_new0 (DirWatch);
watch->create = create;
+ watch->check = check;
watch->destroy = destroy;
watch->user_data = user_data;
@@ -211,9 +242,7 @@
/* the top directory always exists */
if (g_file_equal (directory, topdir))
{
- if (watching)
- dir_watch_created (watch);
-
+ dir_watch_created (watch);
watch->state = TRUE;
}
@@ -224,15 +253,13 @@
parent = g_file_get_parent (directory);
g_assert (parent != NULL);
- watch->parent = dir_watch_new (parent, topdir, watching,
+ watch->parent = dir_watch_new (parent, topdir,
dir_watch_recursive_create,
+ dir_watch_recursive_check,
dir_watch_recursive_destroy,
watch);
g_object_unref (parent);
-
- if (!watching)
- watch->state = watch->parent->state && dir_exists (directory);
}
return watch;
@@ -250,68 +277,37 @@
g_object_unref (watch->topdir);
dir_watch_free (watch->parent);
- }
-}
-void
-dir_watch_enable (DirWatch *watch)
-{
- /* topdir always exists. say so. */
- if (watch->parent == NULL)
- dir_watch_created (watch);
-
- else
- dir_watch_enable (watch->parent);
+ g_slice_free (DirWatch, watch);
+ }
}
+/**
+ * dir_watch_check:
+ * @watch: a #DirWatch
+ *
+ * Emit missed events.
+ *
+ * This function is called on a DirWatch that might have missed events
+ * (because it is watching on an NFS mount, for example).
+ *
+ * This function will manually check if any directories have come into
+ * or gone out of existence and will emit created or destroyed callbacks
+ * as appropriate.
+ *
+ * Additionally, if a directory is found to still exist, the checked
+ * callback will be emitted.
+ **/
void
-dir_watch_disable (DirWatch *watch)
-{
- if (watch->parent_monitor)
- g_object_unref (watch->parent_monitor);
-
- watch->parent_monitor = NULL;
-
- if (watch->parent)
- dir_watch_disable (watch->parent);
-}
-
-gboolean
-dir_watch_is_valid (DirWatch *watch)
+dir_watch_check (DirWatch *watch)
{
- return watch->state;
-}
-
-gboolean
-dir_watch_double_check (DirWatch *watch)
-{
- gboolean old_state;
-
- old_state = watch->state;
-
if (watch->parent == NULL)
{
- g_assert (watch->state == TRUE);
- return TRUE;
- }
-
- if (dir_watch_double_check (watch->parent))
- {
- if (dir_watch_is_valid (watch->parent))
- watch->state = dir_exists (watch->directory);
- else
- watch->state = FALSE;
-
-
- if (!old_state && watch->state && watch->parent_monitor)
- dir_watch_created (watch);
-
- else if (old_state && !watch->state && watch->parent_monitor)
- dir_watch_destroyed (watch);
+ g_assert (watch->state);
- else if (old_state || watch->state)
- return TRUE;
+ watch->check (watch->user_data);
+ return;
}
- return FALSE;
+ dir_watch_check (watch->parent);
}
Modified: trunk/daemon/trashlib/dirwatch.h
==============================================================================
--- trunk/daemon/trashlib/dirwatch.h (original)
+++ trunk/daemon/trashlib/dirwatch.h Fri Feb 27 23:04:31 2009
@@ -16,17 +16,12 @@
DirWatch *dir_watch_new (GFile *directory,
GFile *topdir,
- gboolean watching,
DirWatchFunc create,
+ DirWatchFunc check,
DirWatchFunc destroy,
gpointer user_data);
-void dir_watch_enable (DirWatch *watch);
-void dir_watch_disable (DirWatch *watch);
-gboolean dir_watch_double_check (DirWatch *watch);
-
-gboolean dir_watch_is_valid (DirWatch *watch);
-gboolean dir_watch_needs_update (DirWatch *watch);
+void dir_watch_check (DirWatch *watch);
void dir_watch_free (DirWatch *watch);
Modified: trunk/daemon/trashlib/trashdir.c
==============================================================================
--- trunk/daemon/trashlib/trashdir.c (original)
+++ trunk/daemon/trashlib/trashdir.c Fri Feb 27 23:04:31 2009
@@ -8,6 +8,7 @@
#include "trashdir.h"
+#include <sys/stat.h>
#include <string.h>
#include "dirwatch.h"
@@ -146,6 +147,10 @@
else if (event_type == G_FILE_MONITOR_EVENT_DELETED)
trash_root_remove_item (dir->root, file, dir->is_homedir);
+ else if (event_type == G_FILE_MONITOR_EVENT_PRE_UNMOUNT ||
+ event_type == G_FILE_MONITOR_EVENT_UNMOUNTED)
+ ;
+
else
{
static gboolean already_did_warning;
@@ -168,6 +173,8 @@
dirname = g_file_get_path (dir->directory);
g_warning (" dir: %s, file: %s, type: %d\n\n",
dirname, name, event_type);
+ g_free (dirname);
+ g_free (name);
}
trash_root_thaw (dir->root);
@@ -186,6 +193,14 @@
}
static void
+trash_dir_check (gpointer user_data)
+{
+ TrashDir *dir = user_data;
+
+ trash_dir_enumerate (dir);
+}
+
+static void
trash_dir_destroyed (gpointer user_data)
{
TrashDir *dir = user_data;
@@ -201,6 +216,7 @@
trash_dir_watch (TrashDir *dir)
{
g_assert (dir->monitor == NULL);
+ g_assert (dir->watch == NULL);
/* start monitoring after a period of not monitoring.
*
@@ -214,7 +230,7 @@
* toplevel items that need to be removed.
*
* in case 1, trash_dir_created() will be called from
- * dir_watch_new(). it calls trash_dir_rescan() itself.
+ * dir_watch_new(). it calls trash_enumerate() itself.
*
* in case 2, no other function will be called and we must manually
* call trash_dir_empty().
@@ -222,7 +238,11 @@
* we can tell if case 1 happened because trash_dir_created() also
* sets the dir->monitor.
*/
- dir_watch_enable (dir->watch);
+ dir->watch = dir_watch_new (dir->directory, dir->topdir,
+ trash_dir_created,
+ trash_dir_check,
+ trash_dir_destroyed,
+ dir);
if (dir->monitor == NULL)
/* case 2 */
@@ -232,6 +252,8 @@
void
trash_dir_unwatch (TrashDir *dir)
{
+ g_assert (dir->watch != NULL);
+
/* stop monitoring.
*
* in all cases, we just fall silent.
@@ -243,19 +265,49 @@
dir->monitor = NULL;
}
- dir_watch_disable (dir->watch);
+ dir_watch_free (dir->watch);
+ dir->watch = NULL;
}
-void
-trash_dir_rescan (TrashDir *dir)
+static gboolean
+dir_exists (GFile *directory,
+ GFile *top_dir)
{
- if (dir_watch_double_check (dir->watch))
+ gboolean result = FALSE;
+ GFile *parent;
+
+ if (g_file_equal (directory, top_dir))
+ return TRUE;
+
+ parent = g_file_get_parent (directory);
+
+ if (dir_exists (parent, top_dir))
{
- if (dir_watch_is_valid (dir->watch))
- trash_dir_enumerate (dir);
- else
- trash_dir_empty (dir);
+ struct stat buf;
+ gchar *path;
+
+ path = g_file_get_path (directory);
+ result = !lstat (path, &buf) && S_ISDIR (buf.st_mode);
+
+ g_free (path);
}
+
+ g_object_unref (parent);
+
+ return result;
+}
+
+void
+trash_dir_rescan (TrashDir *dir)
+{
+ if (dir->watch)
+ dir_watch_check (dir->watch);
+
+ else if (dir_exists (dir->directory, dir->topdir))
+ trash_dir_enumerate (dir);
+
+ else
+ trash_dir_empty (dir);
}
static trash_dir_ui_hook ui_hook;
@@ -285,9 +337,15 @@
dir->monitor = NULL;
dir->is_homedir = is_homedir;
- dir->watch = dir_watch_new (dir->directory, dir->topdir, watching,
- trash_dir_created, trash_dir_destroyed,
- dir);
+ if (watching)
+ dir->watch = dir_watch_new (dir->directory,
+ dir->topdir,
+ trash_dir_created,
+ trash_dir_check,
+ trash_dir_destroyed,
+ dir);
+ else
+ dir->watch = NULL;
if (ui_hook)
ui_hook (dir, dir->directory);
@@ -306,7 +364,8 @@
void
trash_dir_free (TrashDir *dir)
{
- dir_watch_free (dir->watch);
+ if (dir->watch)
+ dir_watch_free (dir->watch);
if (dir->monitor)
g_object_unref (dir->monitor);
Modified: trunk/daemon/trashlib/trashitem.c
==============================================================================
--- trunk/daemon/trashlib/trashitem.c (original)
+++ trunk/daemon/trashlib/trashitem.c Fri Feb 27 23:04:31 2009
@@ -180,6 +180,7 @@
rootdir = g_file_get_parent (trashdir);
*original = g_file_get_child (rootdir, orig);
+ g_object_unref (rootdir);
}
g_free (orig);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]