2004-11-29 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System / System.IO / DefaultWatcher.cs
index 36d6d939f4e08f3d81591279554a6ee755636c45..81ae631e6e4177effd482be99ed179c4e355862b 100644 (file)
@@ -37,9 +37,10 @@ namespace System.IO {
        class DefaultWatcherData {
                public FileSystemWatcher FSW;
                public string Directory;
-               public string FileMask;
+               public string FileMask; // If NoWildcards, contains the full path to the file.
                public bool IncludeSubdirs;
                public bool Enabled;
+               public bool NoWildcards;
                public DateTime DisabledTime;
                public Hashtable Files;
        }
@@ -100,7 +101,12 @@ namespace System.IO {
 
                                data.FSW = fsw;
                                data.Directory = fsw.FullPath;
-                               data.FileMask = fsw.MangledFilter;
+                               data.NoWildcards = !fsw.Pattern.HasWildcard;
+                               if (data.NoWildcards)
+                                       data.FileMask = Path.Combine (data.Directory, fsw.MangledFilter);
+                               else
+                                       data.FileMask = fsw.MangledFilter;
+
                                data.IncludeSubdirs = fsw.IncludeSubdirectories;
                                data.Enabled = true;
                                data.DisabledTime = DateTime.MaxValue;
@@ -126,34 +132,28 @@ namespace System.IO {
                        int zeroes = 0;
 
                        while (true) {
+                               Thread.Sleep (750);
+                               
+                               Hashtable my_watches;
                                lock (watches) {
-                                       if (watches.Count > 0) {
-                                               zeroes = 0;
-                                               ArrayList removed = null;
-                                               foreach (DefaultWatcherData data in watches.Values) {
-                                                       bool remove = UpdateDataAndDispatch (data, true);
-                                                       if (remove) {
-                                                               if (removed == null)
-                                                                       removed = new ArrayList ();
-
-                                                               removed.Add (data);
-                                                       }
-                                               }
-
-                                               if (removed != null) {
-                                                       foreach (DefaultWatcherData data in removed)
-                                                               watches.Remove (data.FSW);
-
-                                                       removed.Clear ();
-                                                       removed = null;
-                                               }
-                                       } else {
-                                               zeroes++;
-                                               if (zeroes == 20)
+                                       if (watches.Count == 0) {
+                                               if (++zeroes == 20)
                                                        break;
+                                               continue;
+                                       }
+                                       
+                                       my_watches = (Hashtable) watches.Clone ();
+                               }
+                               
+                               if (watches.Count != 0) {
+                                       zeroes = 0;
+                                       foreach (DefaultWatcherData data in my_watches.Values) {
+                                               bool remove = UpdateDataAndDispatch (data, true);
+                                               if (remove)
+                                                       lock (watches)
+                                                               watches.Remove (data.FSW);
                                        }
                                }
-                               Thread.Sleep (750);
                        }
 
                        lock (this) {
@@ -185,6 +185,7 @@ namespace System.IO {
                        }
                }
 
+               static string [] NoStringsArray = new string [0];
                void DoFiles (DefaultWatcherData data, string directory, bool dispatch)
                {
                        bool direxists = Directory.Exists (directory);
@@ -194,10 +195,16 @@ namespace System.IO {
                        }
 
                        string [] files = null;
-                       if (direxists) {
+                       if (!direxists) {
+                               files = NoStringsArray;
+                       } else if (!data.NoWildcards) {
                                files = Directory.GetFileSystemEntries (directory, data.FileMask);
                        } else {
-                               files = new string [0];
+                               // The pattern does not have wildcards
+                               if (File.Exists (data.FileMask) || Directory.Exists (data.FileMask))
+                                       files = new string [] { data.FileMask };
+                               else
+                                       files = NoStringsArray;
                        }
 
                        /* Set all as untested */
@@ -211,7 +218,14 @@ namespace System.IO {
                        foreach (string filename in files) {
                                FileData fd = (FileData) data.Files [filename];
                                if (fd == null) {
-                                       data.Files.Add (filename, CreateFileData (directory, filename));
+                                       try {
+                                               data.Files.Add (filename, CreateFileData (directory, filename));
+                                       } catch {
+                                               // The file might have been removed in the meanwhile
+                                               data.Files.Remove (filename);
+                                               continue;
+                                       }
+                                       
                                        if (dispatch)
                                                DispatchEvents (data.FSW, FileAction.Added, filename);
                                } else if (fd.Directory == directory) {