* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System / System.IO / FAMWatcher.cs
index c2998f3fcecb820f4a20842080ecbb6670b31a31..63faf5fed7c33acf9f2d6f53675f0cff53af96f4 100644 (file)
@@ -77,13 +77,14 @@ namespace System.IO {
                static FAMConnection conn;
                static Thread thread;
                static bool stop;
+               static bool use_gamin;
                
                private FAMWatcher ()
                {
                }
                
                // Locked by caller
-               public static bool GetInstance (out IFileWatcher watcher)
+               public static bool GetInstance (out IFileWatcher watcher, bool gamin)
                {
                        if (failed == true) {
                                watcher = null;
@@ -95,6 +96,7 @@ namespace System.IO {
                                return true;
                        }
 
+                       use_gamin = gamin;
                        watches = Hashtable.Synchronized (new Hashtable ());
                        requests = Hashtable.Synchronized (new Hashtable ());
                        if (FAMOpen (out conn) == -1) {
@@ -131,7 +133,7 @@ namespace System.IO {
                                        data.SubDirs = new Hashtable ();
 
                                data.Enabled = true;
-                               StartMonitoringDirectory (data);
+                               StartMonitoringDirectory (data, false);
                                lock (this) {
                                        watches [fsw] = data;
                                        requests [data.Request.ReqNum] = data;
@@ -140,28 +142,60 @@ namespace System.IO {
                        }
                }
 
-               static void StartMonitoringDirectory (FAMData data)
+               static void StartMonitoringDirectory (FAMData data, bool justcreated)
                {
                        FAMRequest fr;
+                       FileSystemWatcher fsw;
                        if (FAMMonitorDirectory (ref conn, data.Directory, out fr, IntPtr.Zero) == -1)
                                throw new Win32Exception ();
 
+                       fsw = data.FSW;
                        data.Request = fr;
-                       if (!data.IncludeSubdirs)
-                               return;
-
-                       foreach (string directory in Directory.GetDirectories (data.Directory)) {
-                               FAMData fd = new FAMData ();
-                               fd.FSW = data.FSW;
-                               fd.Directory = directory;
-                               fd.FileMask = data.FSW.MangledFilter;
-                               fd.IncludeSubdirs = true;
-                               fd.SubDirs = new Hashtable ();
-                               fd.Enabled = true;
-
-                               StartMonitoringDirectory (fd);
-                               data.SubDirs [directory] = fd;
-                               requests [fd.Request.ReqNum] = fd;
+
+                       if (data.IncludeSubdirs) {
+                               foreach (string directory in Directory.GetDirectories (data.Directory)) {
+                                       FAMData fd = new FAMData ();
+                                       fd.FSW = data.FSW;
+                                       fd.Directory = directory;
+                                       fd.FileMask = data.FSW.MangledFilter;
+                                       fd.IncludeSubdirs = true;
+                                       fd.SubDirs = new Hashtable ();
+                                       fd.Enabled = true;
+
+                                       if (justcreated) {
+                                               lock (fsw) {
+                                                       RenamedEventArgs renamed = null;
+
+                                                       fsw.DispatchEvents (FileAction.Added, directory, ref renamed);
+
+                                                       if (fsw.Waiting) {
+                                                               fsw.Waiting = false;
+                                                               System.Threading.Monitor.PulseAll (fsw);
+                                                       }
+                                               }
+                                       }
+
+                                       StartMonitoringDirectory (fd, justcreated);
+                                       data.SubDirs [directory] = fd;
+                                       requests [fd.Request.ReqNum] = fd;
+                               }
+                       }
+
+                       if (justcreated) {
+                               foreach (string filename in Directory.GetFiles(data.Directory)) {
+                                       lock (fsw) {
+                                               RenamedEventArgs renamed = null;
+
+                                               fsw.DispatchEvents (FileAction.Added, filename, ref renamed);
+                                               /* If a file has been created, then it has been written to */
+                                               fsw.DispatchEvents (FileAction.Modified, filename, ref renamed);
+
+                                               if (fsw.Waiting) {
+                                                       fsw.Waiting = false;
+                                                       System.Threading.Monitor.PulseAll(fsw);
+                                               }
+                                       }
+                               }
                        }
                }
 
@@ -278,11 +312,15 @@ namespace System.IO {
                                                string full = fsw.FullPath;
                                                string datadir = data.Directory;
                                                if (datadir != full) {
-                                                       string reldir = datadir.Substring (full.Length + 1);
+                                                       int len = full.Length;
+                                                       int slash = 1;
+                                                       if (len > 1 && full [len - 1] == Path.DirectorySeparatorChar)
+                                                               slash = 0;
+                                                       string reldir = datadir.Substring (full.Length + slash);
                                                        datadir = Path.Combine (datadir, filename);
                                                        filename = Path.Combine (reldir, filename);
                                                } else {
-                                                       datadir = Path.Combine (fsw.FullPath, filename);
+                                                       datadir = Path.Combine (full, filename);
                                                }
 
                                                if (fa == FileAction.Added && Directory.Exists (datadir)) {
@@ -298,7 +336,6 @@ namespace System.IO {
                                                        fd.Enabled = true;
                                                        newdirs.Add (fd);
                                                        newdirs.Add (data);
-                                                       requests [fd.Request.ReqNum] = fd;
                                                }
                                        }
 
@@ -318,10 +355,11 @@ namespace System.IO {
 
                        if (newdirs != null) {
                                int count = newdirs.Count;
-                               for (int n = 0; n < count; n++) {
+                               for (int n = 0; n < count; n += 2) {
                                        FAMData newdir = (FAMData) newdirs [n];
                                        FAMData parent = (FAMData) newdirs [n + 1];
-                                       StartMonitoringDirectory (newdir);
+                                       StartMonitoringDirectory (newdir, true);
+                                       requests [newdir.Request.ReqNum] = newdir;
                                        lock (parent) {
                                                parent.SubDirs [newdir.Directory] = newdir;
                                        }
@@ -335,25 +373,79 @@ namespace System.IO {
                        FAMClose (ref conn);
                }
 
-               [DllImport ("libfam.so.0")]
-               extern static int FAMOpen (out FAMConnection fc);
+               static int FAMOpen (out FAMConnection fc)
+               {
+                       if (use_gamin)
+                               return gamin_Open (out fc);
+                       return fam_Open (out fc);
+               }
 
-               [DllImport ("libfam.so.0")]
-               extern static int FAMClose (ref FAMConnection fc);
+               static int FAMClose (ref FAMConnection fc)
+               {
+                       if (use_gamin)
+                               return gamin_Close (ref fc);
+                       return fam_Close (ref fc);
+               }
 
-               [DllImport ("libfam.so.0")]
-               extern static int FAMMonitorDirectory (ref FAMConnection fc, string filename,
+               static int FAMMonitorDirectory (ref FAMConnection fc, string filename, out FAMRequest fr, IntPtr user_data)
+               {
+                       if (use_gamin)
+                               return gamin_MonitorDirectory (ref fc, filename, out fr, user_data);
+                       return fam_MonitorDirectory (ref fc, filename, out fr, user_data);
+               }
+
+               static int FAMCancelMonitor (ref FAMConnection fc, ref FAMRequest fr)
+               {
+                       if (use_gamin)
+                               return gamin_CancelMonitor (ref fc, ref fr);
+                       return fam_CancelMonitor (ref fc, ref fr);
+               }
+
+               static int FAMPending (ref FAMConnection fc)
+               {
+                       if (use_gamin)
+                               return gamin_Pending (ref fc);
+                       return fam_Pending (ref fc);
+               }
+
+
+               
+               [DllImport ("libfam.so.0", EntryPoint="FAMOpen")]
+               extern static int fam_Open (out FAMConnection fc);
+
+               [DllImport ("libfam.so.0", EntryPoint="FAMClose")]
+               extern static int fam_Close (ref FAMConnection fc);
+
+               [DllImport ("libfam.so.0", EntryPoint="FAMMonitorDirectory")]
+               extern static int fam_MonitorDirectory (ref FAMConnection fc, string filename,
                                                        out FAMRequest fr, IntPtr user_data);
 
-               [DllImport ("libfam.so.0")]
-               extern static int FAMCancelMonitor (ref FAMConnection fc, ref FAMRequest fr);
+               [DllImport ("libfam.so.0", EntryPoint="FAMCancelMonitor")]
+               extern static int fam_CancelMonitor (ref FAMConnection fc, ref FAMRequest fr);
+
+               [DllImport ("libfam.so.0", EntryPoint="FAMPending")]
+               extern static int fam_Pending (ref FAMConnection fc);
+
+               [DllImport ("libgamin-1.so.0", EntryPoint="FAMOpen")]
+               extern static int gamin_Open (out FAMConnection fc);
+
+               [DllImport ("libgamin-1.so.0", EntryPoint="FAMClose")]
+               extern static int gamin_Close (ref FAMConnection fc);
+
+               [DllImport ("libgamin-1.so.0", EntryPoint="FAMMonitorDirectory")]
+               extern static int gamin_MonitorDirectory (ref FAMConnection fc, string filename,
+                                                       out FAMRequest fr, IntPtr user_data);
+
+               [DllImport ("libgamin-1.so.0", EntryPoint="FAMCancelMonitor")]
+               extern static int gamin_CancelMonitor (ref FAMConnection fc, ref FAMRequest fr);
+
+               [DllImport ("libgamin-1.so.0", EntryPoint="FAMPending")]
+               extern static int gamin_Pending (ref FAMConnection fc);
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern static int InternalFAMNextEvent (ref FAMConnection fc, out string filename,
                                                        out int code, out int reqnum);
 
-               [DllImport ("libfam.so.0")]
-               extern static int FAMPending (ref FAMConnection fc);
        }
 }