Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mcs/class/System/System.IO/FileSystemWatcher.cs2
-rw-r--r--mcs/class/System/Test/System.IO/FileSystemWatcherTest.cs78
2 files changed, 78 insertions, 2 deletions
diff --git a/mcs/class/System/System.IO/FileSystemWatcher.cs b/mcs/class/System/System.IO/FileSystemWatcher.cs
index 9c003a80e5a..cbf71e7a9a6 100644
--- a/mcs/class/System/System.IO/FileSystemWatcher.cs
+++ b/mcs/class/System/System.IO/FileSystemWatcher.cs
@@ -61,7 +61,7 @@ namespace System.IO {
SearchPattern2 pattern;
bool disposed;
string mangledFilter;
- static IFileWatcher watcher;
+ IFileWatcher watcher;
object watcher_handle;
static object lockobj = new object ();
diff --git a/mcs/class/System/Test/System.IO/FileSystemWatcherTest.cs b/mcs/class/System/Test/System.IO/FileSystemWatcherTest.cs
index 358a43eb1cd..5e1a2b7303a 100644
--- a/mcs/class/System/Test/System.IO/FileSystemWatcherTest.cs
+++ b/mcs/class/System/Test/System.IO/FileSystemWatcherTest.cs
@@ -11,6 +11,7 @@
using NUnit.Framework;
using System;
using System.IO;
+using System.Reflection;
using MonoTests.Helpers;
@@ -109,7 +110,82 @@ namespace MonoTests.System.IO
}
}
}
+
+ [Test]
+ public void CreateTwoAndDispose ()
+ {
+ // Create two FSW instances and dispose them. Verify
+ // that the backend IFileWatcher's Dispose
+ // (watcher_handle) method got called.
+
+ // FIXME: This only works for the
+ // CoreFXFileSystemWatcherProxy not the other backends.
+
+ using (var tmp = new TempDirectory ()) {
+ // have to use reflection to poke at the private fields of FileSystemWatcher.
+ var watcherField = typeof (FileSystemWatcher).GetField ("watcher", BindingFlags.Instance | BindingFlags.NonPublic);
+ Assert.IsNotNull (watcherField);
+ var watcherHandleField = typeof (FileSystemWatcher).GetField ("watcher_handle", BindingFlags.Instance | BindingFlags.NonPublic);
+ Assert.IsNotNull (watcherHandleField);
+ var proxyType = typeof (FileSystemWatcher).Assembly.GetType ("System.IO.CoreFXFileSystemWatcherProxy");
+ Assert.IsNotNull (proxyType);
+ // the "internal_map" maps watcher handles to backend CoreFX FSW instances
+ var proxyTypeInternalMapField = proxyType.GetField ("internal_map", BindingFlags.Static | BindingFlags.NonPublic);
+ Assert.IsNotNull (proxyTypeInternalMapField);
+
+ var fsw1 = new FileSystemWatcher (tmp.Path, "*");
+ var fsw2 = new FileSystemWatcher (tmp.Path, "*");
+ // at this point watcher and watcher_handle should be set
+
+ global::System.Collections.Generic.IDictionary<object, global::System.IO.CoreFX.FileSystemWatcher> internal_map = null;
+ object handle1 = null;
+ object handle2 = null;
+
+ // using "using" to ensure that Dispose gets called even if we throw an exception
+ using (var fsw11 = fsw1)
+ using (var fsw22 = fsw2) {
+
+ // Once at least one FSW is initialized, watcher should be set. But if the
+ // wrong backend is getting used, ignore this test because the other checks
+ // (internal_map in particular) won't be valid.
+ var watcher = watcherField.GetValue (fsw1);
+ Assert.IsNotNull (watcher);
+ if (!proxyType.IsAssignableFrom (watcher.GetType ()))
+ Assert.Ignore ("Testing only CoreFXFileSystemWatcherProxy FSW backend");
+
+ handle1 = watcherHandleField.GetValue (fsw1);
+ handle2 = watcherHandleField.GetValue (fsw2);
+
+ Assert.IsNotNull (handle1);
+ Assert.IsNotNull (handle2);
+
+ // Can't check for internal_map earlier - it is lazily created when the first
+ // FSW instance is created
+ internal_map = proxyTypeInternalMapField.GetValue (null)
+ as global::System.Collections.Generic.IDictionary<object, global::System.IO.CoreFX.FileSystemWatcher>;
+ Assert.IsNotNull (internal_map);
+
+ // Both of handles should be in the internal map while the file system watchers
+ // are not disposed.
+ Assert.IsTrue (internal_map.ContainsKey (handle1));
+ Assert.IsTrue (internal_map.ContainsKey (handle2));
+
+ }
+
+ // Dispose was called, now watcher_handle should be null
+
+ Assert.IsNull (watcherHandleField.GetValue (fsw1));
+ Assert.IsNull (watcherHandleField.GetValue (fsw2));
+
+ // This pair are the critical checks: after we call Dispose on fsw1 and fsw2, the
+ // backend's internal map shouldn't have anything keyed on handle1 and handle2.
+ // Therefore System.IO.CoreFX.FileSystemWatcher instances will be disposed of, too.
+ Assert.IsFalse (internal_map.ContainsKey (handle1));
+ Assert.IsFalse (internal_map.ContainsKey (handle2));
+ }
+ }
+
}
}
-#endif \ No newline at end of file
+#endif