All users chaining onto the central inotify event is quite inefficient and there are bugs which occur when more than one person attempts to watch a specific path with inotify. This implements a subscription system where you are guaranteed to only be called for the events you asked for, and you can safely unsubscribe too. Index: Util/Conf.cs =================================================================== RCS file: /cvs/gnome/beagle/Util/Conf.cs,v retrieving revision 1.3 diff -u -B -p -r1.3 Conf.cs --- Util/Conf.cs 6 Jun 2005 16:32:50 -0000 1.3 +++ Util/Conf.cs 13 Jun 2005 23:36:56 -0000 @@ -44,7 +44,7 @@ namespace Beagle.Util { private static Hashtable mtimes; private static Hashtable subscriptions; private static bool watching_for_updates; - private static int update_wd; + private static bool update_watch_present; private static BindingFlags method_search_flags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod; public delegate void ConfigUpdateHandler (Section section); @@ -66,22 +66,23 @@ namespace Beagle.Util { public static void WatchForUpdates () { - if (update_wd > 0) + // Make sure we don't try and watch for updates more than once + if (update_watch_present) return; if (Inotify.Enabled) { - Inotify.Event += OnInotifyEvent; - update_wd = Inotify.Watch (configs_dir, Inotify.EventType.Create | Inotify.EventType.Modify); + Inotify.Subscribe (configs_dir, OnInotifyEvent, Inotify.EventType.Create | Inotify.EventType.Modify); } else { // Poll for updates every 60 secs GLib.Timeout.Add (60000, new GLib.TimeoutHandler (CheckForUpdates)); - update_wd = 1; } + + update_watch_present = true; } - private static void OnInotifyEvent (int wd, string path, string subitem, string srcpath, Inotify.EventType type) + private static void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { - if (wd != update_wd || subitem == "" || watching_for_updates == false) + if (subitem == "" || watching_for_updates == false) return; Load (); Index: Util/Inotify.cs =================================================================== RCS file: /cvs/gnome/beagle/Util/Inotify.cs,v retrieving revision 1.45 diff -u -B -p -r1.45 Inotify.cs --- Util/Inotify.cs 3 Jun 2005 11:47:13 -0000 1.45 +++ Util/Inotify.cs 13 Jun 2005 23:36:56 -0000 @@ -40,9 +40,7 @@ namespace Beagle.Util { public class Inotify { - public delegate void Handler (int wd, string path, string subitem, string srcpath, EventType type); - - public static event Handler Event; + public delegate void InotifyCallback (Watch watch, string path, string subitem, string srcpath, EventType type); ///////////////////////////////////////////////////////////////////////////////////// @@ -178,7 +176,44 @@ namespace Beagle.Util { ///////////////////////////////////////////////////////////////////////////////////// - private class Watched { + public interface Watch { + void Unsubscribe (); + } + + private class WatchInternal : Watch { + private InotifyCallback callback; + private EventType mask; + private WatchInfo watchinfo; + private bool is_subscribed; + + public InotifyCallback Callback { + get { return callback; } + } + + public EventType Mask { + get { return mask; } + } + + public WatchInternal (InotifyCallback callback, EventType mask, WatchInfo watchinfo) + { + this.callback = callback; + this.mask = mask; + this.watchinfo = watchinfo; + this.is_subscribed = true; + } + + public void Unsubscribe () + { + if (!this.is_subscribed) + return; + + Inotify.Unsubscribe (watchinfo, this); + this.is_subscribed = false; + } + + } + + private class WatchInfo { public int Wd; public string Path; public bool IsDirectory; @@ -188,20 +223,22 @@ namespace Beagle.Util { public EventType FilterSeen; public ArrayList Children; - public Watched Parent; + public WatchInfo Parent; + + public ArrayList Subscribers; } static Hashtable watched_by_wd = new Hashtable (); static Hashtable watched_by_path = new Hashtable (); - static Watched last_watched = null; + static WatchInfo last_watched = null; private class PendingMove { - public Watched Watch; + public WatchInfo Watch; public string SrcName; public DateTime Time; public uint Cookie; - public PendingMove (Watched watched, string srcname, DateTime time, uint cookie) { + public PendingMove (WatchInfo watched, string srcname, DateTime time, uint cookie) { Watch = watched; SrcName = srcname; Time = time; @@ -219,17 +256,17 @@ namespace Beagle.Util { return watched_by_path.Contains (path); } - // Filter Watched items when we do the Lookup. + // Filter WatchInfo items when we do the Lookup. // We do the filtering here to avoid having to acquire // the watched_by_wd lock yet again. - static private Watched Lookup (int wd, EventType event_type) + static private WatchInfo Lookup (int wd, EventType event_type) { lock (watched_by_wd) { - Watched watched; + WatchInfo watched; if (last_watched != null && last_watched.Wd == wd) watched = last_watched; else { - watched = watched_by_wd [wd] as Watched; + watched = watched_by_wd [wd] as WatchInfo; if (watched != null) last_watched = watched; } @@ -244,7 +281,7 @@ namespace Beagle.Util { } // The caller has to handle all locking itself - static private void Forget (Watched watched) + static private void Forget (WatchInfo watched) { if (last_watched == watched) last_watched = null; @@ -254,9 +291,11 @@ namespace Beagle.Util { watched_by_path.Remove (watched.Path); } - static public int Watch (string path, EventType mask, EventType initial_filter) + static public Watch Subscribe (string path, InotifyCallback callback, EventType mask, EventType initial_filter) { - int wd = -1; + WatchInternal watch; + WatchInfo watched; + EventType mask_orig = mask; if (!Path.IsPathRooted (path)) path = Path.GetFullPath (path); @@ -268,27 +307,50 @@ namespace Beagle.Util { throw new IOException (path); lock (watched_by_wd) { - Watched watched; + bool new_watch_needed = true; + + watched = watched_by_path [path] as WatchInfo; - watched = watched_by_path [path] as Watched; if (watched != null) { - if (watched.Mask == mask) - return watched.Wd; - Forget (watched); - } + // We already have a WatchInfo object on this path, so we'll reuse it. + + // Does the existing watch already satisfy the event requirements for this subscriber? + if ((watched.Mask & mask) == mask) + new_watch_needed = false; + else + mask |= watched.Mask; + } else { + // We need an entirely new WatchInfo object + watched = new WatchInfo (); + watched.Path = path; + watched.IsDirectory = is_directory; + watched.Subscribers = new ArrayList (); + watched.Children = new ArrayList (); + DirectoryInfo dir = new DirectoryInfo (path); + watched.Parent = watched_by_path [dir.Parent.ToString ()] as WatchInfo; + if (watched.Parent != null) + watched.Parent.Children.Add (watched); + watched_by_path [watched.Path] = watched; + } + + if (new_watch_needed) { + int wd = -1; + + // We rely on the behaviour that watching the same inode twice won't result + // in the wd value changing. + // (no need to worry about watched_by_wd being polluted with stale watches) + + wd = inotify_glue_watch (dev_inotify, path, mask | base_mask); + if (wd < 0) { + string msg = String.Format ("Attempt to watch {0} failed!", path); + throw new IOException (msg); + } - wd = inotify_glue_watch (dev_inotify, path, mask | base_mask); - if (wd < 0) { - string msg = String.Format ("Attempt to watch {0} failed!", path); - throw new IOException (msg); + watched.Wd = wd; + watched_by_wd [watched.Wd] = watched; } - watched = new Watched (); - watched.Wd = wd; - watched.Path = path; - watched.IsDirectory = is_directory; watched.Mask = mask; - watched.FilterMask = initial_filter; watched.FilterSeen = 0; @@ -292,23 +354,16 @@ namespace Beagle.Util { watched.FilterMask = initial_filter; watched.FilterSeen = 0; - watched.Children = new ArrayList (); - - DirectoryInfo dir = new DirectoryInfo (path); - watched.Parent = watched_by_path [dir.Parent.ToString ()] as Watched; - if (watched.Parent != null) - watched.Parent.Children.Add (watched); - - watched_by_wd [watched.Wd] = watched; - watched_by_path [watched.Path] = watched; + watch = new WatchInternal (callback, mask_orig, watched); + watched.Subscribers.Add (watch); } - return wd; + return watch; } - - public static int Watch (string path, EventType mask) + + static public Watch Subscribe (string path, InotifyCallback callback, EventType mask) { - return Watch (path, mask, 0); + return Subscribe (path, callback, mask, 0); } static public EventType Filter (string path, EventType mask) @@ -318,8 +373,8 @@ namespace Beagle.Util { path = Path.GetFullPath (path); lock (watched_by_wd) { - Watched watched; - watched = watched_by_path [path] as Watched; + WatchInfo watched; + watched = watched_by_path [path] as WatchInfo; seen = watched.FilterSeen; watched.FilterMask = mask; @@ -329,33 +384,22 @@ namespace Beagle.Util { return seen; } - static public int Ignore (string path) + static private void Unsubscribe (WatchInfo watched, WatchInternal watch) { - path = Path.GetFullPath (path); - - int wd = 0; - lock (watched_by_wd) { - - Watched watched; - watched = watched_by_path [path] as Watched; - - // If we aren't actually watching that path, - // silently return. - if (watched == null) - return 0; - - wd = watched.Wd; + watched.Subscribers.Remove (watch); - int retval = inotify_glue_ignore (dev_inotify, wd); - if (retval < 0) { - string msg = String.Format ("Attempt to ignore {0} failed!", watched.Path); - throw new IOException (msg); - } + // Other subscribers might still be around + if (watched.Subscribers.Count > 0) + return; - Forget (watched); + int retval = inotify_glue_ignore (dev_inotify, watched.Wd); + if (retval < 0) { + string msg = String.Format ("Attempt to ignore {0} failed!", watched.Path); + throw new IOException (msg); } - return wd; + Forget (watched); + return; } @@ -473,7 +517,7 @@ namespace Beagle.Util { // Update the watched_by_path hash and the path stored inside the watch // in response to a move event. - static private void MoveWatch (Watched watch, string name) + static private void MoveWatch (WatchInfo watch, string name) { watched_by_path.Remove (watch.Path); watch.Path = name; @@ -487,7 +531,7 @@ namespace Beagle.Util { // all of its subdirectories, their subdirectories, and so on. static private void HandleMove (string srcpath, string dstpath) { - Watched start = watched_by_path [srcpath] as Watched; // not the same as src! + WatchInfo start = watched_by_path [srcpath] as WatchInfo; // not the same as src! if (start == null) { Console.WriteLine ("Lookup failed for {0}", srcpath); return; @@ -499,9 +543,9 @@ namespace Beagle.Util { Queue queue = new Queue(); queue.Enqueue (start); do { - Watched target = queue.Dequeue () as Watched; + WatchInfo target = queue.Dequeue () as WatchInfo; for (int i = 0; i < target.Children.Count; i++) { - Watched child = target.Children[i] as Watched; + WatchInfo child = target.Children[i] as WatchInfo; string name = Path.Combine (dstpath, child.Path.Substring (start.Path.Length + 1)); MoveWatch (child, name); queue.Enqueue (child); @@ -512,7 +556,7 @@ namespace Beagle.Util { MoveWatch (start, dstpath); } - static private void SendEvent (Watched watched, string filename, string srcpath, EventType mask) + static private void SendEvent (WatchInfo watched, string filename, string srcpath, EventType mask) { // Does the watch care about this event? if ((watched.Mask & mask) == 0) @@ -530,14 +574,17 @@ namespace Beagle.Util { srcpath != null ? "(from " + srcpath + ")" : ""); } - if (Event != null) { + if (watched.Subscribers == null) + return; + + foreach (WatchInternal watch in watched.Subscribers) try { - Event (watched.Wd, watched.Path, filename, srcpath, mask); + if (watch.Callback != null && (watch.Mask & mask) != 0) + watch.Callback (watch, watched.Path, filename, srcpath, mask); } catch (Exception e) { - Logger.Log.Error ("Caught exception inside Inotify.Event"); + Logger.Log.Error ("Caught exception executing Inotify callbacks"); Logger.Log.Error (e); } - } } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -668,7 +715,7 @@ namespace Beagle.Util { // Before we get any further, mark it next_event.Dispatched = true; - Watched watched; + WatchInfo watched; watched = Lookup (next_event.Wd, next_event.Type); if (watched == null) continue; @@ -677,7 +724,7 @@ namespace Beagle.Util { // If this event is a paired MoveTo, there is extra work to do. if ((next_event.Type & EventType.MovedTo) != 0 && next_event.PairedMove != null) { - Watched paired_watched; + WatchInfo paired_watched; paired_watched = Lookup (next_event.PairedMove.Wd, next_event.PairedMove.Type); if (paired_watched != null) { @@ -724,7 +771,7 @@ namespace Beagle.Util { string path = (string) to_watch.Dequeue (); Console.WriteLine ("Watching {0}", path); - Inotify.Watch (path, Inotify.EventType.All); + Inotify.Subscribe (path, null, Inotify.EventType.All); if (recursive) { foreach (string subdir in DirectoryWalker.GetDirectories (path)) Index: beagled/BlamQueryable/BlamQueryable.cs =================================================================== RCS file: /cvs/gnome/beagle/beagled/BlamQueryable/BlamQueryable.cs,v retrieving revision 1.30 diff -u -B -p -r1.30 BlamQueryable.cs --- beagled/BlamQueryable/BlamQueryable.cs 30 May 2005 10:18:03 -0000 1.30 +++ beagled/BlamQueryable/BlamQueryable.cs 13 Jun 2005 23:36:57 -0000 @@ -44,7 +44,6 @@ namespace Beagle.Daemon.BlamQueryable { string blam_dir; const string blam_file = "collection.xml"; - int blam_wd = -1; public BlamQueryable () : base ("BlamIndex") { @@ -69,8 +68,7 @@ namespace Beagle.Daemon.BlamQueryable { if (Inotify.Enabled) { Inotify.EventType mask = Inotify.EventType.CloseWrite; - blam_wd = Inotify.Watch (blam_dir, mask); - Inotify.Event += OnInotifyEvent; + Inotify.Subscribe (blam_dir, OnInotifyEvent, mask); } else { FileSystemWatcher fsw = new FileSystemWatcher (); fsw.Path = blam_dir; @@ -99,15 +97,12 @@ namespace Beagle.Daemon.BlamQueryable { ///////////////////////////////////////////////// // Modified event using Inotify - private void OnInotifyEvent (int wd, + private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { - if (wd != blam_wd) - return; - if (subitem != blam_file) return; Index: beagled/EvolutionMailDriver/EvolutionMailDriver.cs =================================================================== RCS file: /cvs/gnome/beagle/beagled/EvolutionMailDriver/EvolutionMailDriver.cs,v retrieving revision 1.43 diff -u -B -p -r1.43 EvolutionMailDriver.cs --- beagled/EvolutionMailDriver/EvolutionMailDriver.cs 24 May 2005 21:12:48 -0000 1.43 +++ beagled/EvolutionMailDriver/EvolutionMailDriver.cs 13 Jun 2005 23:36:57 -0000 @@ -46,7 +46,6 @@ namespace Beagle.Daemon.EvolutionMailDri public static Logger log = Logger.Get ("mail"); private string local_path, imap_path, imap4_path; - private SortedList watched = new SortedList (); private MailCrawler crawler; public EvolutionMailQueryable () : base ("MailIndex") @@ -193,7 +192,6 @@ namespace Beagle.Daemon.EvolutionMailDri // Get notification when an index or summary file changes if (Inotify.Enabled) { - Inotify.Event += OnInotifyEvent; Watch (this.local_path); Watch (this.imap_path); Watch (this.imap4_path); @@ -239,30 +237,23 @@ namespace Beagle.Daemon.EvolutionMailDri if (! dir.Exists) continue; - int wd = Inotify.Watch (dir.FullName, + Inotify.Subscribe (dir.FullName, OnInotifyEvent, Inotify.EventType.Create | Inotify.EventType.Delete | Inotify.EventType.MovedTo); - watched [wd] = dir.FullName; foreach (DirectoryInfo subdir in dir.GetDirectories ()) queue.Enqueue (subdir); } } - private void Ignore (string path) - { - Inotify.Ignore (path); - watched.RemoveAt (watched.IndexOfValue (path)); - } - - private void OnInotifyEvent (int wd, - string path, + private void OnInotifyEvent (Inotify.Watch watch, + string path, string subitem, string srcpath, Inotify.EventType type) { - if (subitem == "" || ! watched.Contains (wd)) + if (subitem == "") return; string fullPath = Path.Combine (path, subitem); @@ -273,7 +264,7 @@ namespace Beagle.Daemon.EvolutionMailDri } if ((type & Inotify.EventType.Delete) != 0 && (type & Inotify.EventType.IsDirectory) != 0) { - Ignore (fullPath); + watch.Unsubscribe (); return; } Index: beagled/FileSystemQueryable/InotifyBackend.cs =================================================================== RCS file: /cvs/gnome/beagle/beagled/FileSystemQueryable/InotifyBackend.cs,v retrieving revision 1.9 diff -u -B -p -r1.9 InotifyBackend.cs --- beagled/FileSystemQueryable/InotifyBackend.cs 9 May 2005 21:52:54 -0000 1.9 +++ beagled/FileSystemQueryable/InotifyBackend.cs 13 Jun 2005 23:36:57 -0000 @@ -35,75 +35,49 @@ namespace Beagle.Daemon.FileSystemQuerya public class InotifyBackend : IFileEventBackend { - Hashtable watching = new Hashtable (); FileSystemQueryable queryable; public object WatchDirectories (string path) { - int wd; - + object watch = null; try { - wd = Inotify.Watch (path, Inotify.EventType.Create); - watching [wd] = true; + watch = Inotify.Subscribe (path, OnInotifyEvent, Inotify.EventType.Create); } catch (IOException) { // We can race and files can disappear. No big deal. - wd = -1; } - - return wd; + return watch; } public object WatchFiles (string path, object old_handle) { - int wd; - int old_wd = -1; - if (old_handle != null) - old_wd = (int) old_handle; - + object watch = null; try { - wd = Inotify.Watch (path, + watch = Inotify.Subscribe (path, OnInotifyEvent, Inotify.EventType.Open | Inotify.EventType.Create | Inotify.EventType.Delete | Inotify.EventType.CloseWrite | Inotify.EventType.MovedFrom | Inotify.EventType.MovedTo); - watching [wd] = true; - if (old_wd >= 0 && old_wd != wd) - watching.Remove (old_wd); } catch (IOException) { // We can race and files can disappear. No big deal. - wd = -1; } - - return wd; + return watch; } public void Start (FileSystemQueryable queryable) { this.queryable = queryable; - - Inotify.Event += OnInotifyEvent; } - private void OnInotifyEvent (int wd, - string path, + private void OnInotifyEvent (Inotify.Watch watch, + string path, string subitem, string srcpath, Inotify.EventType type) { - // Filter out any events on unfamiliar watches - if (! watching.Contains (wd)) - return; - - // Clean up after removed watches - if ((type & Inotify.EventType.Ignored) != 0) { - watching.Remove (wd); - return; - } - string full_path; if (subitem.Length == 0) full_path = path; Index: beagled/GaimLogQueryable/GaimLogQueryable.cs =================================================================== RCS file: /cvs/gnome/beagle/beagled/GaimLogQueryable/GaimLogQueryable.cs,v retrieving revision 1.32 diff -u -B -p -r1.32 GaimLogQueryable.cs --- beagled/GaimLogQueryable/GaimLogQueryable.cs 16 May 2005 16:05:50 -0000 1.32 +++ beagled/GaimLogQueryable/GaimLogQueryable.cs 13 Jun 2005 23:36:58 -0000 @@ -44,8 +44,6 @@ namespace Beagle.Daemon.GaimLogQueryable private int polling_interval_in_seconds = 60; - Hashtable watched = new Hashtable (); - private GaimLogCrawler crawler; public GaimLogQueryable () : base ("GaimLogIndex") @@ -68,10 +66,8 @@ namespace Beagle.Daemon.GaimLogQueryable Stopwatch stopwatch = new Stopwatch (); stopwatch.Start (); - if (Inotify.Enabled) { - Inotify.Event += OnInotifyEvent; + if (Inotify.Enabled) Watch (log_dir); - } crawler = new GaimLogCrawler (log_dir); Crawl (); @@ -130,11 +126,9 @@ namespace Beagle.Daemon.GaimLogQueryable DirectoryInfo dir = queue.Dequeue () as DirectoryInfo; // Setup watches on the present directory. - int wd = Inotify.Watch (dir.FullName, + Inotify.Subscribe (dir.FullName, OnInotifyEvent, Inotify.EventType.Create | Inotify.EventType.Modify); - watched [wd] = true; - // Add all subdirectories to the queue so their files can be indexed. foreach (DirectoryInfo subdir in dir.GetDirectories ()) queue.Enqueue (subdir); @@ -155,13 +149,13 @@ namespace Beagle.Daemon.GaimLogQueryable ///////////////////////////////////////////////// - private void OnInotifyEvent (int wd, + private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { - if (subitem == "" || ! watched.Contains (wd)) + if (subitem == "") return; string full_path = Path.Combine (path, subitem); Index: beagled/LauncherQueryable/LauncherQueryable.cs =================================================================== RCS file: /cvs/gnome/beagle/beagled/LauncherQueryable/LauncherQueryable.cs,v retrieving revision 1.18 diff -u -B -p -r1.18 LauncherQueryable.cs --- beagled/LauncherQueryable/LauncherQueryable.cs 17 May 2005 21:24:55 -0000 1.18 +++ beagled/LauncherQueryable/LauncherQueryable.cs 13 Jun 2005 23:36:58 -0000 @@ -41,7 +41,6 @@ namespace Beagle.Daemon.LauncherQueryabl private static Logger log = Logger.Get ("LauncherQueryable"); ArrayList Dirs; - Hashtable watched = new Hashtable (); int polling_interval_in_hours = 1; public LauncherQueryable () : base ("LauncherIndex") @@ -79,9 +78,6 @@ namespace Beagle.Daemon.LauncherQueryabl Stopwatch timer = new Stopwatch (); timer.Start (); - if (Inotify.Enabled) - Inotify.Event += OnInotifyEvent; - Crawl (); if (!Inotify.Enabled) { @@ -114,7 +110,7 @@ namespace Beagle.Daemon.LauncherQueryabl // Crawl the specified directory and all subdirectories, indexing all // discovered launchers. If Inotify is available, every directory - // scanned will be added to the watched list. + // scanned will be watched. private int CrawlLaunchers (string path) { DirectoryInfo root = new DirectoryInfo (path); @@ -129,8 +125,7 @@ namespace Beagle.Daemon.LauncherQueryabl DirectoryInfo dir = queue.Dequeue () as DirectoryInfo; if (Inotify.Enabled) { - int wd = Inotify.Watch (dir.FullName, Inotify.EventType.Create | Inotify.EventType.Modify); - watched [wd] = true; + Inotify.Subscribe (dir.FullName, OnInotifyEvent, Inotify.EventType.Create | Inotify.EventType.Modify); } foreach (FileInfo file in dir.GetFiles ()) { @@ -145,13 +140,13 @@ namespace Beagle.Daemon.LauncherQueryabl return fileCount; } - private void OnInotifyEvent (int wd, - string path, + private void OnInotifyEvent (Inotify.Watch watch, + string path, string subitem, string srcpath, Inotify.EventType type) { - if (subitem == "" || ! watched.Contains (wd)) + if (subitem == "") return; string fullPath = Path.Combine (path, subitem); Index: beagled/LifereaQueryable/LifereaQueryable.cs =================================================================== RCS file: /cvs/gnome/beagle/beagled/LifereaQueryable/LifereaQueryable.cs,v retrieving revision 1.10 diff -u -B -p -r1.10 LifereaQueryable.cs --- beagled/LifereaQueryable/LifereaQueryable.cs 3 Jun 2005 21:14:40 -0000 1.10 +++ beagled/LifereaQueryable/LifereaQueryable.cs 13 Jun 2005 23:36:58 -0000 @@ -42,7 +42,6 @@ namespace Beagle.Daemon.LifereaQueryable private static Logger log = Logger.Get ("LifereaQueryable"); string liferea_dir; - int liferea_wd = -1; public LifereaQueryable () : base ("LifereaIndex") { @@ -70,8 +69,7 @@ namespace Beagle.Daemon.LifereaQueryable if (Inotify.Enabled) { Inotify.EventType mask = Inotify.EventType.CloseWrite; - liferea_wd = Inotify.Watch (liferea_dir, mask); - Inotify.Event += OnInotifyEvent; + Inotify.Subscribe (liferea_dir, OnInotifyEvent, mask); } else { FileSystemWatcher fsw = new FileSystemWatcher (); fsw.Path = liferea_dir; @@ -113,15 +111,12 @@ namespace Beagle.Daemon.LifereaQueryable // Modified/Created event using Inotify - private void OnInotifyEvent (int wd, + private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { - if (wd != liferea_wd) - return; - if (subitem == "") return; Index: beagled/TomboyQueryable/TomboyQueryable.cs =================================================================== RCS file: /cvs/gnome/beagle/beagled/TomboyQueryable/TomboyQueryable.cs,v retrieving revision 1.24 diff -u -B -p -r1.24 TomboyQueryable.cs --- beagled/TomboyQueryable/TomboyQueryable.cs 16 May 2005 16:05:52 -0000 1.24 +++ beagled/TomboyQueryable/TomboyQueryable.cs 13 Jun 2005 23:36:59 -0000 @@ -40,7 +40,6 @@ namespace Beagle.Daemon.TomboyQueryable private static Logger log = Logger.Get ("TomboyQueryable"); string tomboy_dir; - int tomboy_wd = -1; public TomboyQueryable () : base ("TomboyIndex") { @@ -66,8 +65,7 @@ namespace Beagle.Daemon.TomboyQueryable Inotify.EventType.MovedTo | Inotify.EventType.MovedFrom; - tomboy_wd = Inotify.Watch (tomboy_dir, mask); - Inotify.Event += OnInotifyEvent; + Inotify.Subscribe (tomboy_dir, OnInotifyEvent, mask); } else { FileSystemWatcher fsw = new FileSystemWatcher (); fsw.Path = tomboy_dir; @@ -113,15 +111,12 @@ namespace Beagle.Daemon.TomboyQueryable ///////////////////////////////////////////////// // Modified/Created/Deleted event using Inotify - private void OnInotifyEvent (int wd, + private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { - if (wd != tomboy_wd) - return; - if (subitem == "") return;