From cb956b58a6a5a84bcb2acc2302ad60fba01c0e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Wed, 28 Feb 2018 13:42:15 +0100 Subject: Revert "Revert "[System.IO] Integrate FileSystemWatchers from CoreFX The FSEvent CoreFX watcher becomes the new default for MacOS."" This reverts commit 2174a521a3e45f6ce4db967a53edcc1ee2dd0433. --- mcs/class/System/System.IO/FileSystemWatcher.cs | 100 ++++++++++++++++++------ 1 file changed, 76 insertions(+), 24 deletions(-) (limited to 'mcs/class/System/System.IO/FileSystemWatcher.cs') diff --git a/mcs/class/System/System.IO/FileSystemWatcher.cs b/mcs/class/System/System.IO/FileSystemWatcher.cs index 53e31d61f7e..c27900524d3 100644 --- a/mcs/class/System/System.IO/FileSystemWatcher.cs +++ b/mcs/class/System/System.IO/FileSystemWatcher.cs @@ -45,6 +45,8 @@ namespace System.IO { #region Fields + bool inited; + bool start_requested; bool enableRaisingEvents; string filter; bool includeSubdirectories; @@ -59,6 +61,7 @@ namespace System.IO { bool disposed; string mangledFilter; static IFileWatcher watcher; + object watcher_handle; static object lockobj = new object (); #endregion // Fields @@ -95,6 +98,8 @@ namespace System.IO { if (!Directory.Exists (path)) throw new ArgumentException ("Directory does not exist", "path"); + this.inited = false; + this.start_requested = false; this.enableRaisingEvents = false; this.filter = filter; this.includeSubdirectories = false; @@ -121,28 +126,39 @@ namespace System.IO { switch (mode) { case 1: // windows ok = DefaultWatcher.GetInstance (out watcher); - //ok = WindowsWatcher.GetInstance (out watcher); + watcher_handle = this; break; case 2: // libfam ok = FAMWatcher.GetInstance (out watcher, false); + watcher_handle = this; break; case 3: // kevent ok = KeventWatcher.GetInstance (out watcher); + watcher_handle = this; break; case 4: // libgamin ok = FAMWatcher.GetInstance (out watcher, true); + watcher_handle = this; break; case 5: // inotify ok = InotifyWatcher.GetInstance (out watcher, true); + watcher_handle = this; + break; + case 6: // CoreFX + ok = CoreFXFileSystemWatcherProxy.GetInstance (out watcher); + watcher_handle = (watcher as CoreFXFileSystemWatcherProxy).NewWatcher (this); break; } if (mode == 0 || !ok) { if (String.Compare (managed, "disabled", true) == 0) NullFileWatcher.GetInstance (out watcher); - else + else { DefaultWatcher.GetInstance (out watcher); + watcher_handle = this; + } } + this.inited = true; ShowWatcherInfo (); } @@ -173,9 +189,6 @@ namespace System.IO { return mangledFilter; string filterLocal = "*.*"; - if (!(watcher.GetType () == typeof (WindowsWatcher))) - filterLocal = "*"; - return filterLocal; } } @@ -210,6 +223,12 @@ namespace System.IO { public bool EnableRaisingEvents { get { return enableRaisingEvents; } set { + if (disposed) + throw new ObjectDisposedException (GetType().Name); + + start_requested = true; + if (!inited) + return; if (value == enableRaisingEvents) return; // Do nothing @@ -218,6 +237,7 @@ namespace System.IO { Start (); } else { Stop (); + start_requested = false; } } } @@ -232,7 +252,7 @@ namespace System.IO { if (value == null || value == "") value = "*.*"; - if (filter != value) { + if (!string.Equals(filter, value, PathInternal.StringComparison)) { filter = value; pattern = null; mangledFilter = null; @@ -264,8 +284,8 @@ namespace System.IO { if (internalBufferSize == value) return; - if (value < 4196) - value = 4196; + if (value < 4096) + value = 4096; internalBufferSize = value; if (enableRaisingEvents) { @@ -299,7 +319,11 @@ namespace System.IO { public string Path { get { return path; } set { - if (path == value) + if (disposed) + throw new ObjectDisposedException (GetType().Name); + + value = (value == null) ? string.Empty : value; + if (string.Equals(path, value, PathInternal.StringComparison)) return; bool exists = false; @@ -312,10 +336,10 @@ namespace System.IO { } if (exc != null) - throw new ArgumentException ("Invalid directory name", "value", exc); + throw new ArgumentException(SR.Format(SR.InvalidDirName, value), nameof(Path)); if (!exists) - throw new ArgumentException ("Directory does not exist", "value"); + throw new ArgumentException(SR.Format(SR.InvalidDirName_NotExists, value), nameof(Path)); path = value; fullpath = null; @@ -329,7 +353,12 @@ namespace System.IO { [Browsable(false)] public override ISite Site { get { return base.Site; } - set { base.Site = value; } + set + { + base.Site = value; + if (Site != null && Site.DesignMode) + this.EnableRaisingEvents = true; + } } [DefaultValue(null)] @@ -347,27 +376,41 @@ namespace System.IO { public void BeginInit () { // Not necessary in Mono + // but if called, EndInit() must be called + inited = false; } protected override void Dispose (bool disposing) { - if (!disposed) { - disposed = true; - Stop (); - } + if (disposed) + return; + + try { + watcher.StopDispatching (watcher_handle); + watcher.Dispose (watcher_handle); + } catch (Exception) { } + watcher_handle = null; + watcher = null; + + disposed = true; base.Dispose (disposing); + GC.SuppressFinalize (this); } ~FileSystemWatcher () { - disposed = true; - Stop (); + if (disposed) + return; + + Dispose (false); } public void EndInit () { - // Not necessary in Mono + inited = true; + if (start_requested) + this.EnableRaisingEvents = true; } enum EventType { @@ -384,13 +427,13 @@ namespace System.IO { foreach (var target in ev.GetInvocationList()) { switch (evtype) { case EventType.RenameEvent: - ((RenamedEventHandler)target).BeginInvoke (this, (RenamedEventArgs)arg, null, null); + ((RenamedEventHandler)target).Invoke (this, (RenamedEventArgs)arg); break; case EventType.ErrorEvent: - ((ErrorEventHandler)target).BeginInvoke (this, (ErrorEventArgs)arg, null, null); + ((ErrorEventHandler)target).Invoke (this, (ErrorEventArgs)arg); break; case EventType.FileSystemEvent: - ((FileSystemEventHandler)target).BeginInvoke (this, (FileSystemEventArgs)arg, null, null); + ((FileSystemEventHandler)target).Invoke (this, (FileSystemEventArgs)arg); break; } } @@ -503,12 +546,20 @@ namespace System.IO { void Start () { - watcher.StartDispatching (this); + if (disposed) + return; + if (watcher_handle == null) + return; + watcher.StartDispatching (watcher_handle); } void Stop () { - watcher.StopDispatching (this); + if (disposed) + return; + if (watcher_handle == null) + return; + watcher.StopDispatching (watcher_handle); } #endregion // Methods @@ -537,6 +588,7 @@ namespace System.IO { /* 3 -> Kevent */ /* 4 -> gamin */ /* 5 -> inotify */ + /* 6 -> CoreFX */ [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern int InternalSupportsFSW (); } -- cgit v1.2.3