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:
authorAlexis Christoforides <alexis@thenull.net>2018-02-11 02:59:23 +0300
committerMarek Safar <marek.safar@gmail.com>2018-02-28 12:47:01 +0300
commitf5b10f34a98bdbbdc0cb086a9240d5a7795ab7c0 (patch)
treec5528a39e84c60d83cf08b70778ea7e5796a0112
parent872c0488308d955e1073058f2dbda4e689e502da (diff)
[System.IO] Integrate FileSystemWatchers from CoreFX
The FSEvent CoreFX watcher becomes the new default for MacOS.
-rw-r--r--data/config.in1
m---------external/api-snapshot0
m---------external/corefx0
-rw-r--r--man/mono.15
-rw-r--r--mcs/class/System/System.IO/CoreFXFileSystemWatcherProxy.cs183
-rw-r--r--mcs/class/System/System.IO/DefaultWatcher.cs11
-rw-r--r--mcs/class/System/System.IO/FAMWatcher.cs10
-rw-r--r--mcs/class/System/System.IO/FileSystemWatcher.cs100
-rw-r--r--mcs/class/System/System.IO/IFileWatcher.cs5
-rw-r--r--mcs/class/System/System.IO/InotifyWatcher.cs11
-rw-r--r--mcs/class/System/System.IO/KeventWatcher.cs11
-rw-r--r--mcs/class/System/System.IO/NullFileWatcher.cs9
-rw-r--r--mcs/class/System/System.IO/WaitForChangedResult.cs69
-rw-r--r--mcs/class/System/System.IO/WindowsWatcher.cs53
-rw-r--r--mcs/class/System/System_xtest.dll.sources7
-rw-r--r--mcs/class/System/basic_System.dll.sources2
-rw-r--r--mcs/class/System/build_System.dll.sources2
-rw-r--r--mcs/class/System/common.sources3
-rw-r--r--mcs/class/System/corefx.unix.sources1
-rw-r--r--mcs/class/System/corefx/SR.cs252
-rw-r--r--mcs/class/System/darwin_net_4_x_System.dll.sources12
-rw-r--r--mcs/class/System/linux_net_4_x_System.dll.sources16
-rw-r--r--mcs/class/System/net_4_x_System.dll.sources6
-rw-r--r--mcs/class/System/win32_net_4_x_System.dll.sources11
-rw-r--r--mcs/class/System/xammac_net_4_5_System.dll.sources2
-rw-r--r--mcs/class/test-helpers/PlatformDetection.cs3
-rw-r--r--mono/metadata/filewatcher.c48
-rw-r--r--mono/metadata/filewatcher.h6
-rw-r--r--mono/metadata/icall-def.h5
29 files changed, 676 insertions, 168 deletions
diff --git a/data/config.in b/data/config.in
index 282bc114950..36aa4c9085e 100644
--- a/data/config.in
+++ b/data/config.in
@@ -40,4 +40,5 @@
<dllmap dll="gdiplus.dll" target="@libgdiplus_install_loc@" os="!windows"/>
<dllmap dll="gdi32" target="@libgdiplus_install_loc@" os="!windows"/>
<dllmap dll="gdi32.dll" target="@libgdiplus_install_loc@" os="!windows"/>
+ <dllmap dll="System.Native" target="__Internal"/>
</configuration>
diff --git a/external/api-snapshot b/external/api-snapshot
-Subproject 729d1eddb4af334912cf6a1015d50f8c8457007
+Subproject ae826ca5fa6b77a2bdeed2bc750f8aede057e3f
diff --git a/external/corefx b/external/corefx
-Subproject 4e29271452b57ecf28819c19da601c3d72af61c
+Subproject f01c024d335e2c5f7269dffb99405d1e4d128b4
diff --git a/man/mono.1 b/man/mono.1
index ea0897b5bba..55c5abcd620 100644
--- a/man/mono.1
+++ b/man/mono.1
@@ -1126,8 +1126,11 @@ When Mono is built with a soft float fallback on ARM and this variable is set to
"1", Mono will always emit soft float code, even if a VFP unit is
detected.
.TP
+\fBMONO_DARWIN_USE_KQUEUE_FSW\fR
+Fall back on the kqueue FileSystemWatcher implementation in Darwin. The default is the FSEvent implementation.
+.TP
\fBMONO_DARWIN_WATCHER_MAXFDS\fR
-This is a debugging aid used to force limits on the FileSystemWatcher
+This is a debugging aid used to force limits on the kqueue FileSystemWatcher
implementation in Darwin. There is no limit by default.
.TP
\fBMONO_DISABLE_AIO\fR
diff --git a/mcs/class/System/System.IO/CoreFXFileSystemWatcherProxy.cs b/mcs/class/System/System.IO/CoreFXFileSystemWatcherProxy.cs
new file mode 100644
index 00000000000..466acd1fff0
--- /dev/null
+++ b/mcs/class/System/System.IO/CoreFXFileSystemWatcherProxy.cs
@@ -0,0 +1,183 @@
+// Bridges the Mono and CoreFX FileSystemWatcher types.
+
+using System.Collections.Generic;
+using System.Collections.Concurrent;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Runtime.CompilerServices;
+
+using C = System.IO.CoreFX.FileSystemWatcher;
+using M = System.IO.FileSystemWatcher;
+using Handle = System.Object;
+
+namespace System.IO {
+
+ internal class CoreFXFileSystemWatcherProxy : IFileWatcher
+ {
+ static IFileWatcher instance; // Mono FSW objects -> this
+ static IDictionary<Handle, C> internal_map; // this -> CoreFX FSW objects
+ static ConditionalWeakTable<Handle, M> external_map; // this -> Mono FSW objects
+ static IDictionary<object, Handle> event_map; // CoreFX FSW events -> this
+
+ const int INTERRUPT_MS = 300;
+
+ protected void Operation (Action<IDictionary<object, C>, ConditionalWeakTable<object, M>, IDictionary<object, object>, Handle> map_op = null, Action<C, M> object_op = null, object handle = null, Action<C, M> cancel_op = null)
+ {
+ C internal_fsw = null;
+ M fsw = null;
+ bool live, havelock;
+
+ if (cancel_op != null) { // highest priority and must not lock
+ havelock = Monitor.TryEnter (instance, INTERRUPT_MS);
+ live = (handle != null && (internal_map.TryGetValue (handle, out internal_fsw) || external_map.TryGetValue (handle, out fsw))) ;
+ if (live && havelock)
+ try { cancel_op (internal_fsw, fsw); }
+ catch (Exception) { };
+
+ if (havelock)
+ Monitor.Exit (instance);
+ if (live && !havelock)
+ try {
+ var t = Task<bool>.Run( () => { cancel_op (internal_fsw, fsw); return true;});
+ t.Wait (INTERRUPT_MS);
+ }
+ catch (Exception) { };
+ return;
+ }
+ if (map_op != null && handle == null) {
+ lock (instance) {
+ try { map_op (internal_map, external_map, event_map, null); }
+ catch (Exception e) { throw new InvalidOperationException (nameof(map_op), e); }
+ }
+ return;
+ }
+
+ if (handle == null)
+ return;
+
+ lock (instance) {
+ live = (internal_map.TryGetValue (handle, out internal_fsw) && external_map.TryGetValue (handle, out fsw)) ;
+ if (live && map_op != null) {
+ try { map_op (internal_map, external_map, event_map, handle); }
+ catch (Exception e) { throw new InvalidOperationException (nameof(map_op), e); };
+ }
+ }
+ if (!live || object_op == null)
+ return;
+
+ try { object_op (internal_fsw, fsw); }
+ catch (Exception e) { throw new InvalidOperationException (nameof(object_op), e); };
+ }
+
+ protected void ProxyDispatch (object sender, FileAction action, FileSystemEventArgs args)
+ {
+ RenamedEventArgs renamed =
+ action == FileAction.RenamedNewName ? (RenamedEventArgs) args : null;
+
+ object handle = null;
+
+ Operation (map_op: (in_map, out_map, event_map, h) => event_map.TryGetValue (sender, out handle));
+
+ Operation (object_op: (_, fsw) => {
+ if (!fsw.EnableRaisingEvents)
+ return;
+ fsw.DispatchEvents (action, args.Name, ref renamed);
+ if (fsw.Waiting) {
+ fsw.Waiting = false;
+ System.Threading.Monitor.PulseAll (fsw);
+ }
+ }, handle: handle);
+ }
+
+ protected void ProxyDispatchError (object sender, ErrorEventArgs args)
+ {
+ object handle = null;
+
+ Operation (map_op: (in_map, out_map, event_map, _) => event_map.TryGetValue (sender, out handle));
+
+ Operation (object_op: (_, fsw) => fsw.DispatchErrorEvents (args),
+ handle: handle);
+ }
+
+ public object NewWatcher (M fsw)
+ {
+ var handle = new object ();
+ var result = new C ();
+
+ result.Changed += (object o, FileSystemEventArgs args) =>
+ { ProxyDispatch (o, FileAction.Modified, args); };
+ result.Created += (object o, FileSystemEventArgs args) =>
+ { ProxyDispatch (o, FileAction.Added, args); };
+ result.Deleted += (object o, FileSystemEventArgs args) =>
+ { ProxyDispatch (o, FileAction.Removed, args); };
+ result.Renamed += (object o, RenamedEventArgs args) =>
+ { ProxyDispatch (o, FileAction.RenamedNewName, args); };
+
+ result.Error += (object o, ErrorEventArgs args) =>
+ { ProxyDispatchError (handle, args); };
+
+ Operation (map_op: (in_map, out_map, event_map, _) => {
+ in_map.Add (handle, result);
+ out_map.Add (handle, fsw);
+ event_map.Add (result, handle);
+ });
+
+ return handle;
+ }
+
+ public void StartDispatching (object handle)
+ {
+ Operation (object_op: (internal_fsw, fsw) => {
+ internal_fsw.Path = fsw.Path;
+ internal_fsw.Filter = fsw.Filter;
+ internal_fsw.IncludeSubdirectories = fsw.IncludeSubdirectories;
+ internal_fsw.InternalBufferSize = fsw.InternalBufferSize;
+ internal_fsw.NotifyFilter = fsw.NotifyFilter;
+ internal_fsw.Site = fsw.Site;
+ internal_fsw.EnableRaisingEvents = true;
+ }, handle: handle);
+ }
+
+ public void StopDispatching (object handle)
+ {
+ Operation (handle: handle,
+ cancel_op: (internal_fsw, fsw) =>
+ {
+ if (internal_fsw != null)
+ internal_fsw.EnableRaisingEvents = false;
+
+ });
+ }
+
+ public void Dispose (object handle)
+ {
+ if (handle == null)
+ return;
+
+ Operation (handle: handle,
+ cancel_op: (internal_fsw, fsw) => {
+ if (internal_fsw != null)
+ internal_fsw.Dispose ();
+ var inner_key = internal_map [handle];
+ internal_map.Remove (handle);
+ external_map.Remove (handle);
+ event_map.Remove (inner_key);
+ handle = null;
+ });
+ }
+
+ public static bool GetInstance (out IFileWatcher watcher)
+ {
+ if (instance != null) {
+ watcher = instance;
+ return true;
+ }
+
+ internal_map = new ConcurrentDictionary <object, C> ();
+ external_map = new ConditionalWeakTable <object, M> ();
+ event_map = new ConcurrentDictionary <object, object> ();
+ instance = watcher = new CoreFXFileSystemWatcherProxy ();
+ return true;
+ }
+ }
+}
diff --git a/mcs/class/System/System.IO/DefaultWatcher.cs b/mcs/class/System/System.IO/DefaultWatcher.cs
index cbda2b294aa..28186f8451b 100644
--- a/mcs/class/System/System.IO/DefaultWatcher.cs
+++ b/mcs/class/System/System.IO/DefaultWatcher.cs
@@ -79,8 +79,9 @@ namespace System.IO {
return true;
}
- public void StartDispatching (FileSystemWatcher fsw)
+ public void StartDispatching (object handle)
{
+ var fsw = handle as FileSystemWatcher;
DefaultWatcherData data;
lock (this) {
if (watches == null)
@@ -116,8 +117,9 @@ namespace System.IO {
}
}
- public void StopDispatching (FileSystemWatcher fsw)
+ public void StopDispatching (object handle)
{
+ var fsw = handle as FileSystemWatcher;
DefaultWatcherData data;
lock (this) {
if (watches == null) return;
@@ -132,6 +134,11 @@ namespace System.IO {
}
}
+ public void Dispose (object handle)
+ {
+ // does nothing
+ }
+
void Monitor ()
{
diff --git a/mcs/class/System/System.IO/FAMWatcher.cs b/mcs/class/System/System.IO/FAMWatcher.cs
index 63faf5fed7c..d0ee6526ee5 100644
--- a/mcs/class/System/System.IO/FAMWatcher.cs
+++ b/mcs/class/System/System.IO/FAMWatcher.cs
@@ -110,8 +110,9 @@ namespace System.IO {
return true;
}
- public void StartDispatching (FileSystemWatcher fsw)
+ public void StartDispatching (object handle)
{
+ var fsw = handle as FileSystemWatcher;
FAMData data;
lock (this) {
if (thread == null) {
@@ -199,8 +200,9 @@ namespace System.IO {
}
}
- public void StopDispatching (FileSystemWatcher fsw)
+ public void StopDispatching (object handle)
{
+ var fsw = handle as FileSystemWatcher;
FAMData data;
lock (this) {
data = (FAMData) watches [fsw];
@@ -408,6 +410,10 @@ namespace System.IO {
return fam_Pending (ref fc);
}
+ public void Dispose (object handle)
+ {
+ // does nothing
+ }
[DllImport ("libfam.so.0", EntryPoint="FAMOpen")]
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 ();
}
diff --git a/mcs/class/System/System.IO/IFileWatcher.cs b/mcs/class/System/System.IO/IFileWatcher.cs
index 7ed4878fa6d..d7e6055a1d5 100644
--- a/mcs/class/System/System.IO/IFileWatcher.cs
+++ b/mcs/class/System/System.IO/IFileWatcher.cs
@@ -30,8 +30,9 @@
namespace System.IO {
interface IFileWatcher {
- void StartDispatching (FileSystemWatcher fsw);
- void StopDispatching (FileSystemWatcher fsw);
+ void StartDispatching (object fsw);
+ void StopDispatching (object fsw);
+ void Dispose (object fsw);
}
}
diff --git a/mcs/class/System/System.IO/InotifyWatcher.cs b/mcs/class/System/System.IO/InotifyWatcher.cs
index fe023429a0c..8668533ff83 100644
--- a/mcs/class/System/System.IO/InotifyWatcher.cs
+++ b/mcs/class/System/System.IO/InotifyWatcher.cs
@@ -133,8 +133,9 @@ namespace System.IO {
return true;
}
- public void StartDispatching (FileSystemWatcher fsw)
+ public void StartDispatching (object handle)
{
+ var fsw = handle as FileSystemWatcher;
ParentInotifyData parent;
lock (this) {
if ((long) FD == -1)
@@ -328,8 +329,9 @@ namespace System.IO {
}
}
- public void StopDispatching (FileSystemWatcher fsw)
+ public void StopDispatching (object handle)
{
+ var fsw = handle as FileSystemWatcher;
ParentInotifyData parent;
lock (this) {
parent = (ParentInotifyData) watches [fsw];
@@ -608,6 +610,11 @@ namespace System.IO {
return AddWatch (fd, directory, mask);
}
+ public void Dispose (object handle)
+ {
+ // does nothing
+ }
+
[DllImport ("libc", EntryPoint="close")]
internal extern static int Close (IntPtr fd);
diff --git a/mcs/class/System/System.IO/KeventWatcher.cs b/mcs/class/System/System.IO/KeventWatcher.cs
index 778671764ea..5a1984f7099 100644
--- a/mcs/class/System/System.IO/KeventWatcher.cs
+++ b/mcs/class/System/System.IO/KeventWatcher.cs
@@ -736,8 +736,9 @@ namespace System.IO {
return true;
}
- public void StartDispatching (FileSystemWatcher fsw)
+ public void StartDispatching (object handle)
{
+ var fsw = handle as FileSystemWatcher;
KqueueMonitor monitor;
if (watches.ContainsKey (fsw)) {
@@ -750,14 +751,20 @@ namespace System.IO {
monitor.Start ();
}
- public void StopDispatching (FileSystemWatcher fsw)
+ public void StopDispatching (object handle)
{
+ var fsw = handle as FileSystemWatcher;
KqueueMonitor monitor = (KqueueMonitor)watches [fsw];
if (monitor == null)
return;
monitor.Stop ();
}
+
+ public void Dispose (object handle)
+ {
+ // does nothing
+ }
[DllImport ("libc")]
extern static int close (int fd);
diff --git a/mcs/class/System/System.IO/NullFileWatcher.cs b/mcs/class/System/System.IO/NullFileWatcher.cs
index 33f314f55b8..ea1cbccfaee 100644
--- a/mcs/class/System/System.IO/NullFileWatcher.cs
+++ b/mcs/class/System/System.IO/NullFileWatcher.cs
@@ -35,12 +35,17 @@ namespace System.IO
{
static IFileWatcher instance;
- public void StartDispatching (FileSystemWatcher fsw)
+ public void StartDispatching (object handle)
{
// does nothing
}
- public void StopDispatching (FileSystemWatcher fsw)
+ public void StopDispatching (object handle)
+ {
+ // does nothing
+ }
+
+ public void Dispose (object handle)
{
// does nothing
}
diff --git a/mcs/class/System/System.IO/WaitForChangedResult.cs b/mcs/class/System/System.IO/WaitForChangedResult.cs
deleted file mode 100644
index 7a6765b1e07..00000000000
--- a/mcs/class/System/System.IO/WaitForChangedResult.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-//
-// System.IO.WaitForChangedResult.cs
-//
-// Author:
-// Tim Coleman (tim@timcoleman.com)
-//
-// Copyright (C) Tim Coleman, 2002
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-
-namespace System.IO {
- public struct WaitForChangedResult {
-
- #region Fields
-
- WatcherChangeTypes changeType;
- string name;
- string oldName;
- bool timedOut;
-
- #endregion // Fields
-
- #region Properties
-
- public WatcherChangeTypes ChangeType {
- get { return changeType; }
- set { changeType = value; }
- }
-
- public string Name {
- get { return name; }
- set { name = value; }
- }
-
- public string OldName {
- get { return oldName; }
- set { oldName = value; }
- }
-
- public bool TimedOut {
- get { return timedOut; }
- set { timedOut = value; }
- }
-
- #endregion // Properties
- }
-}
diff --git a/mcs/class/System/System.IO/WindowsWatcher.cs b/mcs/class/System/System.IO/WindowsWatcher.cs
deleted file mode 100644
index dc5e848f13d..00000000000
--- a/mcs/class/System/System.IO/WindowsWatcher.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-// System.IO.WindowsWatcher.cs: windows IFileWatcher
-//
-// Authors:
-// Gonzalo Paniagua Javier (gonzalo@ximian.com)
-//
-// (c) 2004 Novell, Inc. (http://www.novell.com)
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-namespace System.IO {
- class WindowsWatcher : IFileWatcher
- {
- private WindowsWatcher ()
- {
- }
-
- // Locked by caller
- public static bool GetInstance (out IFileWatcher watcher)
- {
- throw new NotSupportedException ();
- }
-
- public void StartDispatching (FileSystemWatcher fsw)
- {
- }
-
- public void StopDispatching (FileSystemWatcher fsw)
- {
- }
- }
-}
-
diff --git a/mcs/class/System/System_xtest.dll.sources b/mcs/class/System/System_xtest.dll.sources
index 40c357e00c8..da81fa878ab 100644
--- a/mcs/class/System/System_xtest.dll.sources
+++ b/mcs/class/System/System_xtest.dll.sources
@@ -92,3 +92,10 @@ System/RemoteExecutorTests.cs
../../../external/corefx/src/Common/src/System/Net/UriScheme.cs
../../../external/corefx/src/Common/src/System/SerializableAttribute.cs
../../../external/corefx/src/Common/tests/System/ShouldNotBeInvokedException.cs
+
+# System.IO.FileSystemWatcher
+../../../external/corefx/src/System.IO.FileSystem.Watcher/tests/Utility/*.cs
+../../../external/corefx/src/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.cs
+../../../external/corefx/src/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.unit.cs
+../../../external/corefx/src/Common/tests/System/IO/TempFile.cs
+../../../external/corefx/src/Common/tests/System/IO/TempDirectory.cs
diff --git a/mcs/class/System/basic_System.dll.sources b/mcs/class/System/basic_System.dll.sources
index ee2d1a0d962..ba79dd85fc1 100644
--- a/mcs/class/System/basic_System.dll.sources
+++ b/mcs/class/System/basic_System.dll.sources
@@ -1,2 +1,2 @@
#include net_4_x_System.dll.sources
-
+../../../external/corefx/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.UnknownUnix.cs
diff --git a/mcs/class/System/build_System.dll.sources b/mcs/class/System/build_System.dll.sources
index ee2d1a0d962..ba79dd85fc1 100644
--- a/mcs/class/System/build_System.dll.sources
+++ b/mcs/class/System/build_System.dll.sources
@@ -1,2 +1,2 @@
#include net_4_x_System.dll.sources
-
+../../../external/corefx/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.UnknownUnix.cs
diff --git a/mcs/class/System/common.sources b/mcs/class/System/common.sources
index 785ea5e3513..90911c364ca 100644
--- a/mcs/class/System/common.sources
+++ b/mcs/class/System/common.sources
@@ -1,5 +1,6 @@
Assembly/AssemblyInfo.cs
../../build/common/SR.cs
+corefx/SR.cs
corefx/ZLibNative.cs
@@ -39,7 +40,6 @@ System.IO/IODescriptionAttribute.cs
System.IO/NotifyFilters.cs
System.IO/RenamedEventArgs.cs
System.IO/RenamedEventHandler.cs
-System.IO/WaitForChangedResult.cs
System.IO/WatcherChangeTypes.cs
System.Net/BasicClient.cs
@@ -928,3 +928,4 @@ corefx/SR.cs
../../../external/corefx/src/System.Private.Uri/src/System/UriBuilder.cs
../../../external/corefx/src/System.Runtime.Extensions/src/System/CodeDom/Compiler/IndentedTextWriter.cs
+../../../external/corefx/src/System.IO.FileSystem.Watcher/src/System/IO/WaitForChangedResult.cs
diff --git a/mcs/class/System/corefx.unix.sources b/mcs/class/System/corefx.unix.sources
new file mode 100644
index 00000000000..bec78d856d3
--- /dev/null
+++ b/mcs/class/System/corefx.unix.sources
@@ -0,0 +1 @@
+../../../external/corefx/src/Common/src/Interop/Unix/*.cs
diff --git a/mcs/class/System/corefx/SR.cs b/mcs/class/System/corefx/SR.cs
index d83dc9b8691..720825e4b91 100644
--- a/mcs/class/System/corefx/SR.cs
+++ b/mcs/class/System/corefx/SR.cs
@@ -46,6 +46,257 @@ partial class SR
public const string PartitionerStatic_CurrentCalledBeforeMoveNext = "MoveNext must be called at least once before calling Current.";
public const string ConcurrentBag_Enumerator_EnumerationNotStartedOrAlreadyFinished = "Enumeration has either not started or has already finished.";
public const string Arg_KeyNotFoundWithKey = "The given key '{0}' was not present in the dictionary.";
+ public const string IO_FileExists_Name = "The file '{0}' already exists.";
+ public const string IO_FileName_Name = "File name: '{0}'";
+ public const string IO_FileNotFound = "Unable to find the specified file.";
+ public const string IO_FileNotFound_FileName = "Could not load file or assembly '{0}'. The system cannot find the file specified.";
+ public const string IO_FileLoad = "Could not load the specified file.";
+ public const string IO_NoPermissionToDirectoryName = "<Path discovery permission to the specified directory was denied.%gt;";
+ public const string IO_PathNotFound_NoPathName = "Could not find a part of the path.";
+ public const string IO_PathNotFound_Path = "Could not find a part of the path '{0}'.";
+ public const string IO_AlreadyExists_Name = "Cannot create '{0}' because a file or directory with the same name already exists.";
+ public const string Lazy_CreateValue_NoParameterlessCtorForT = "The lazily-initialized type does not have a public, parameterless constructor.";
+ public const string Lazy_ctor_ModeInvalid = "The mode argument specifies an invalid value.";
+ public const string Lazy_StaticInit_InvalidOperation = "ValueFactory returned null.";
+ public const string Lazy_ToString_ValueNotCreated = "Value is not created.";
+ public const string Lazy_Value_RecursiveCallsToValue = "ValueFactory attempted to access the Value property of this instance.";
+ public const string MissingConstructor_Name = "Constructor on type '{0}' not found.";
+ public const string MustUseCCRewrite = "An assembly (probably '{1}') must be rewritten using the code contracts binary rewriter (CCRewrite) because it is calling Contract.{0} and the CONTRACTS_FULL symbol is defined. Remove any explicit definitions of the CONTRACTS_FULL symbol from your project and rebuild. CCRewrite can be downloaded from http://go.microsoft.com/fwlink/?LinkID=169180. \\r\\nAfter the rewriter is installed, it can be enabled in Visual Studio from the project's Properties page on the Code Contracts pane. Ensure that 'Perform Runtime Contract Checking' is enabled, which will define CONTRACTS_FULL.";
+ public const string ObjectDisposed_Generic = "Cannot access a disposed object.";
+ public const string ObjectDisposed_ObjectName_Name = "Object name: '{0}'.";
+
+ public const string PlatformNotSupported_MakePointerType = "MakePointerType() is not supported on this platform.";
+ public const string Rank_MultiDimNotSupported = "Only single dimension arrays are supported here.";
+ public const string RuntimeWrappedException = "An object that does not derive from System.Exception has been wrapped in a RuntimeWrappedException.";
+ public const string SpinWait_SpinUntil_ArgumentNull = "The condition argument is null.";
+ public const string Serialization_CorruptField = "The value of the field '{0}' is invalid. The serialized data is corrupt.";
+ public const string Serialization_InvalidData = "An error occurred while deserializing the object. The serialized data is corrupt.";
+ public const string Serialization_InvalidEscapeSequence = "The serialized data contained an invalid escape sequence '\\\\{0}'.";
+ public const string SpinWait_SpinUntil_TimeoutWrong = "The timeout must represent a value between -1 and Int32.MaxValue, inclusive.";
+ public const string Threading_AbandonedMutexException = "The wait completed due to an abandoned mutex.";
+ public const string Threading_SemaphoreFullException = "Adding the specified count to the semaphore would cause it to exceed its maximum count.";
+ public const string Threading_WaitHandleCannotBeOpenedException = "No handle of the given name exists.";
+ public const string Threading_WaitHandleCannotBeOpenedException_InvalidHandle = "A WaitHandle with system-wide name '{0}' cannot be created. A WaitHandle of a different type might have the same name.";
+ public const string TimeZoneNotFound_MissingRegistryData = "The time zone ID '{0}' was not found on the local computer.";
+ public const string TypeInitialization_Default = "Type constructor threw an exception.";
+ public const string TypeInitialization_Type = "The type initializer for '{0}' threw an exception.";
+ public const string TypeInitialization_Type_NoTypeAvailable = "A type initializer threw an exception. To determine which type, inspect the InnerException's StackTrace property.";
+ public const string Verification_Exception = "Operation could destabilize the runtime.";
+ public const string Arg_EnumFormatUnderlyingTypeAndObjectMustBeSameType = "Enum underlying type and the object must be same type or object. Type passed in was '{0}'; the enum underlying type was '{1}'.";
+ public const string Format_InvalidEnumFormatSpecification = "Format String can be only 'G', 'g', 'X', 'x', 'F', 'f', 'D' or 'd'.";
+ public const string Arg_MustBeEnumBaseTypeOrEnum = "The value passed in must be an enum base or an underlying type for an enum, such as an Int32.";
+ public const string Arg_EnumUnderlyingTypeAndObjectMustBeSameType = "Enum underlying type and the object must be same type or object must be a String. Type passed in was '{0}'; the enum underlying type was '{1}'.";
+ public const string Arg_MustBeType = "Type must be a type provided by the runtime.";
+ public const string Arg_MustContainEnumInfo = "Must specify valid information for parsing in the string.";
+ public const string Arg_EnumValueNotFound = "Requested value '{0}' was not found.";
+ public const string Argument_StringZeroLength = "String cannot be of zero length.";
+ public const string Argument_StringFirstCharIsZero = "The first char in the string is the null character.";
+ public const string Argument_LongEnvVarValue = "Environment variable name or value is too long.";
+ public const string Argument_IllegalEnvVarName = "Environment variable name cannot contain equal character.";
+ public const string AssumptionFailed = "Assumption failed.";
+ public const string AssumptionFailed_Cnd = "Assumption failed: {0}";
+ public const string AssertionFailed = "Assertion failed.";
+ public const string AssertionFailed_Cnd = "Assertion failed: {0}";
+ public const string Debug_Fail = "Fail: {0}";
+ public const string PreconditionFailed = "Precondition failed.";
+ public const string PreconditionFailed_Cnd = "Precondition failed: {0}";
+ public const string PostconditionFailed = "Postcondition failed.";
+ public const string PostconditionFailed_Cnd = "Postcondition failed: {0}";
+ public const string PostconditionOnExceptionFailed = "Postcondition failed after throwing an exception.";
+ public const string PostconditionOnExceptionFailed_Cnd = "Postcondition failed after throwing an exception: {0}";
+ public const string InvariantFailed = "Invariant failed.";
+ public const string InvariantFailed_Cnd = "Invariant failed: {0}";
+ public const string MissingEncodingNameResource = "Could not find a resource entry for the encoding codepage '{0} - {1}'";
+ public const string Globalization_cp_1200 = "Unicode";
+ public const string Globalization_cp_1201 = "Unicode (Big-Endian)";
+ public const string Globalization_cp_12000 = "Unicode (UTF-32)";
+ public const string Globalization_cp_12001 = "Unicode (UTF-32 Big-Endian)";
+ public const string Globalization_cp_20127 = "US-ASCII";
+ public const string Globalization_cp_28591 = "Western European (ISO)";
+ public const string Globalization_cp_65000 = "Unicode (UTF-7)";
+ public const string Globalization_cp_65001 = "Unicode (UTF-8)";
+ public const string InvalidCast_Empty = "Object cannot be cast to Empty.";
+ public const string Arg_UnknownTypeCode = "Unknown TypeCode value.";
+ public const string Format_BadDatePattern = "Could not determine the order of year, month, and date from '{0}'.";
+ public const string Format_BadDateTime = "String was not recognized as a valid DateTime.";
+ public const string Format_BadDateTimeCalendar = "The DateTime represented by the string is not supported in calendar {0}.";
+ public const string Format_BadDayOfWeek = "String was not recognized as a valid DateTime because the day of week was incorrect.";
+ public const string Format_DateOutOfRange = "The DateTime represented by the string is out of range.";
+ public const string Format_MissingIncompleteDate = "There must be at least a partial date with a year present in the input.";
+ public const string Format_OffsetOutOfRange = "The time zone offset must be within plus or minus 14 hours.";
+ public const string Format_RepeatDateTimePattern = "DateTime pattern '{0}' appears more than once with different values.";
+ public const string Format_UnknowDateTimeWord = "The string was not recognized as a valid DateTime. There is an unknown word starting at index {0}.";
+ public const string Format_UTCOutOfRange = "The UTC representation of the date falls outside the year range 1-9999.";
+ public const string InvalidOperation_ComputerName = "Computer name could not be obtained.";
+ public const string RFLCT_Ambiguous = "Ambiguous match found.";
+ public const string AggregateException_ctor_DefaultMessage = "One or more errors occurred.";
+ public const string AggregateException_ctor_InnerExceptionNull = "An element of innerExceptions was null.";
+ public const string AggregateException_DeserializationFailure = "The serialization stream contains no inner exceptions.";
+ public const string AggregateException_InnerException = "(Inner Exception #{0}) "; // {entry.Item3}
+ public const string ArgumentOutOfRange_TimeoutTooLarge = "Time-out interval must be less than 2^32-2.";
+ public const string ArgumentOutOfRange_PeriodTooLarge = "Period must be less than 2^32-2.";
+ public const string TaskScheduler_FromCurrentSynchronizationContext_NoCurrent = "The current SynchronizationContext may not be used as a TaskScheduler.";
+ public const string TaskScheduler_ExecuteTask_WrongTaskScheduler = "ExecuteTask may not be called for a task which was previously queued to a different TaskScheduler.";
+ public const string TaskScheduler_InconsistentStateAfterTryExecuteTaskInline = "The TryExecuteTaskInline call to the underlying scheduler succeeded, but the task body was not invoked.";
+ public const string TaskSchedulerException_ctor_DefaultMessage = "An exception was thrown by a TaskScheduler.";
+ public const string Task_MultiTaskContinuation_FireOptions = "It is invalid to exclude specific continuation kinds for continuations off of multiple tasks.";
+ public const string Task_ContinueWith_ESandLR = "The specified TaskContinuationOptions combined LongRunning and ExecuteSynchronously. Synchronous continuations should not be long running.";
+ public const string Task_MultiTaskContinuation_EmptyTaskList = "The tasks argument contains no tasks.";
+ public const string Task_MultiTaskContinuation_NullTask = "The tasks argument included a null value.";
+ public const string Task_FromAsync_PreferFairness = "It is invalid to specify TaskCreationOptions.PreferFairness in calls to FromAsync.";
+ public const string Task_FromAsync_LongRunning = "It is invalid to specify TaskCreationOptions.LongRunning in calls to FromAsync.";
+ public const string AsyncMethodBuilder_InstanceNotInitialized = "The builder was not properly initialized.";
+ public const string TaskT_TransitionToFinal_AlreadyCompleted = "An attempt was made to transition a task to a final state when it had already completed.";
+ public const string TaskT_DebuggerNoResult = "{Not yet computed}";
+ public const string OperationCanceled = "The operation was canceled.";
+ public const string CancellationToken_CreateLinkedToken_TokensIsEmpty = "No tokens were supplied.";
+ public const string CancellationTokenSource_Disposed = "The CancellationTokenSource has been disposed.";
+ public const string CancellationToken_SourceDisposed = "The CancellationTokenSource associated with this CancellationToken has been disposed.";
+ public const string TaskExceptionHolder_UnknownExceptionType = "(Internal)Expected an Exception or an IEnumerable<Exception>";
+ public const string TaskExceptionHolder_UnhandledException = "A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread.";
+ public const string Task_Delay_InvalidMillisecondsDelay = "The value needs to be either -1 (signifying an infinite timeout), 0 or a positive integer.";
+ public const string Task_Delay_InvalidDelay = "The value needs to translate in milliseconds to -1 (signifying an infinite timeout), 0 or a positive integer less than or equal to Int32.MaxValue.";
+ public const string Task_WaitMulti_NullTask = "The tasks array included at least one null element.";
+ public const string Task_ContinueWith_NotOnAnything = "The specified TaskContinuationOptions excluded all continuation kinds.";
+ public const string Task_RunSynchronously_AlreadyStarted = "RunSynchronously may not be called on a task that was already started.";
+ public const string Task_ThrowIfDisposed = "The task has been disposed.";
+ public const string Task_RunSynchronously_TaskCompleted = "RunSynchronously may not be called on a task that has already completed.";
+ public const string Task_RunSynchronously_Promise = "RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.";
+ public const string Task_RunSynchronously_Continuation = "RunSynchronously may not be called on a continuation task.";
+ public const string Task_Start_AlreadyStarted = "Start may not be called on a task that was already started.";
+ public const string Task_Start_ContinuationTask = "Start may not be called on a continuation task.";
+ public const string Task_Start_Promise = "Start may not be called on a promise-style task.";
+ public const string Task_Start_TaskCompleted = "Start may not be called on a task that has completed.";
+ public const string TaskCanceledException_ctor_DefaultMessage = "A task was canceled.";
+ public const string TaskCompletionSourceT_TrySetException_NoExceptions = "The exceptions collection was empty.";
+ public const string TaskCompletionSourceT_TrySetException_NullException = "The exceptions collection included at least one null element.";
+ public const string Argument_MinMaxValue = "'{0}' cannot be greater than {1}.";
+ public const string InvalidOperation_NullContext = "Cannot call Set on a null context";
+ public const string ExecutionContext_ExceptionInAsyncLocalNotification = "An exception was not handled in an AsyncLocal<T> notification callback.";
+ public const string InvalidOperation_WrongAsyncResultOrEndCalledMultiple = "Either the IAsyncResult object did not come from the corresponding async method on this type, or the End method was called multiple times with the same IAsyncResult.";
+ public const string SpinLock_IsHeldByCurrentThread = "Thread tracking is disabled.";
+ public const string SpinLock_TryEnter_LockRecursionException = "The calling thread already holds the lock.";
+ public const string SpinLock_Exit_SynchronizationLockException = "The calling thread does not hold the lock.";
+ public const string SpinLock_TryReliableEnter_ArgumentException = "The tookLock argument must be set to false before calling this method.";
+ public const string SpinLock_TryEnter_ArgumentOutOfRange = "The timeout must be a value between -1 and Int32.MaxValue, inclusive.";
+ public const string ManualResetEventSlim_Disposed = "The event has been disposed.";
+ public const string ManualResetEventSlim_ctor_SpinCountOutOfRange = "The spinCount argument must be in the range 0 to {0}, inclusive.";
+ public const string ManualResetEventSlim_ctor_TooManyWaiters = "There are too many threads currently waiting on the event. A maximum of {0} waiting threads are supported.";
+ public const string InvalidOperation_SendNotSupportedOnWindowsRTSynchronizationContext = "Send is not supported in the Windows Runtime SynchronizationContext";
+ public const string SemaphoreSlim_Disposed = "The semaphore has been disposed.";
+ public const string SemaphoreSlim_Release_CountWrong = "The releaseCount argument must be greater than zero.";
+ public const string SemaphoreSlim_Wait_TimeoutWrong = "The timeout must represent a value between -1 and Int32.MaxValue, inclusive.";
+ public const string SemaphoreSlim_ctor_MaxCountWrong = "The maximumCount argument must be a positive number. If a maximum is not required, use the constructor without a maxCount parameter.";
+ public const string SemaphoreSlim_ctor_InitialCountWrong = "The initialCount argument must be non-negative and less than or equal to the maximumCount.";
+ public const string ThreadLocal_ValuesNotAvailable = "The ThreadLocal object is not tracking values. To use the Values property, use a ThreadLocal constructor that accepts the trackAllValues parameter and set the parameter to true.";
+ public const string ThreadLocal_Value_RecursiveCallsToValue = "ValueFactory attempted to access the Value property of this instance.";
+ public const string ThreadLocal_Disposed = "The ThreadLocal object has been disposed.";
+ public const string LockRecursionException_WriteAfterReadNotAllowed = "Write lock may not be acquired with read lock held. This pattern is prone to deadlocks. Please ensure that read locks are released before taking a write lock. If an upgrade is necessary, use an upgrade lock in place of the read lock.";
+ public const string LockRecursionException_RecursiveWriteNotAllowed = "Recursive write lock acquisitions not allowed in this mode.";
+ public const string LockRecursionException_ReadAfterWriteNotAllowed = "A read lock may not be acquired with the write lock held in this mode.";
+ public const string LockRecursionException_RecursiveUpgradeNotAllowed = "Recursive upgradeable lock acquisitions not allowed in this mode.";
+ public const string LockRecursionException_RecursiveReadNotAllowed = "Recursive read lock acquisitions not allowed in this mode.";
+ public const string SynchronizationLockException_IncorrectDispose = "The lock is being disposed while still being used. It either is being held by a thread and/or has active waiters waiting to acquire the lock.";
+ public const string SynchronizationLockException_MisMatchedWrite = "The write lock is being released without being held.";
+ public const string LockRecursionException_UpgradeAfterReadNotAllowed = "Upgradeable lock may not be acquired with read lock held.";
+ public const string LockRecursionException_UpgradeAfterWriteNotAllowed = "Upgradeable lock may not be acquired with write lock held in this mode. Acquiring Upgradeable lock gives the ability to read along with an option to upgrade to a writer.";
+ public const string SynchronizationLockException_MisMatchedUpgrade = "The upgradeable lock is being released without being held.";
+ public const string SynchronizationLockException_MisMatchedRead = "The read lock is being released without being held.";
+ public const string InvalidOperation_TimeoutsNotSupported = "Timeouts are not supported on this stream.";
+ public const string NotSupported_SubclassOverride = "Derived classes must provide an implementation.";
+ public const string InvalidOperation_NoPublicRemoveMethod = "Cannot remove the event handler since no public remove method exists for the event.";
+ public const string InvalidOperation_NoPublicAddMethod = "Cannot add the event handler since no public add method exists for the event.";
+ public const string SerializationException = "Serialization error.";
+ public const string Serialization_NotFound = "Member '{0}' was not found.";
+ public const string Serialization_OptionalFieldVersionValue = "Version value must be positive.";
+ public const string Serialization_SameNameTwice = "Cannot add the same member twice to a SerializationInfo object.";
+ public const string NotSupported_AbstractNonCLS = "This non-CLS method is not implemented.";
+ public const string NotSupported_NoTypeInfo = "Cannot resolve {0} to a TypeInfo object.";
+ public const string ReflectionTypeLoad_LoadFailed = "Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.";
+ public const string Arg_CustomAttributeFormatException = "Binary format of the specified custom attribute was invalid.";
+ public const string Argument_InvalidMemberForNamedArgument = "The member must be either a field or a property.";
+ public const string Arg_InvalidFilterCriteriaException = "Specified filter criteria was invalid.";
+ public const string Arg_ParmArraySize = "Must specify one or more parameters.";
+ public const string Arg_MustBePointer = "Type must be a Pointer.";
+ public const string Arg_InvalidHandle = "Invalid handle.";
+ public const string Argument_InvalidEnum = "The Enum type should contain one and only one instance field.";
+ public const string Argument_MustHaveAttributeBaseClass = "Type passed in must be derived from System.Attribute or System.Attribute itself.";
+ public const string InvalidFilterCriteriaException_CritString = "A String must be provided for the filter criteria.";
+ public const string InvalidFilterCriteriaException_CritInt = "An Int32 must be provided for the filter criteria.";
+ public const string InvalidOperation_NotSupportedOnWinRTEvent = "Adding or removing event handlers dynamically is not supported on WinRT events.";
+ public const string PlatformNotSupported_ReflectionOnly = "ReflectionOnly loading is not supported on this platform.";
+ public const string MissingMember_Name = "Member '{0}' not found.";
+ public const string MissingMethod_Name = "Method '{0}' not found.";
+ public const string MissingField_Name = "Field '{0}' not found.";
+ public const string Format_StringZeroLength = "String cannot have zero length.";
+ public const string Security_CannotReadRegistryData = "The time zone ID '{0}' was found on the local computer, but the application does not have permission to read the registry information.";
+ public const string Security_InvalidAssemblyPublicKey = "Invalid assembly public key.";
+ public const string Security_RegistryPermission = "Requested registry access is not allowed.";
+ public const string ClassLoad_General = "Could not load type '{0}' from assembly '{1}'.";
+ public const string ClassLoad_RankTooLarge = "'{0}' from assembly '{1}' has too many dimensions.";
+ public const string ClassLoad_ExplicitGeneric = "Could not load type '{0}' from assembly '{1}' because generic types cannot have explicit layout.";
+ public const string ClassLoad_BadFormat = "Could not load type '{0}' from assembly '{1}' because the format is invalid.";
+ public const string ClassLoad_ValueClassTooLarge = "Array of type '{0}' from assembly '{1}' cannot be created because base value type is too large.";
+ public const string ClassLoad_ExplicitLayout = "Could not load type '{0}' from assembly '{1}' because it contains an object field at offset '{2}' that is incorrectly aligned or overlapped by a non-object field.";
+ public const string EE_MissingMethod = "Method not found: '{0}'.";
+ public const string EE_MissingField = "Field not found: '{0}'.";
+ public const string UnauthorizedAccess_RegistryKeyGeneric_Key = "Access to the registry key '{0}' is denied.";
+ public const string UnknownError_Num = "Unknown error '{0}'.";
+ public const string Argument_NeedNonGenericType = "The specified Type must not be a generic type definition.";
+ public const string Argument_NeedStructWithNoRefs = "The specified Type must be a struct containing no references.";
+ public const string ArgumentOutOfRange_AddressSpace = "The number of bytes cannot exceed the virtual address space on a 32 bit machine.";
+ public const string ArgumentOutOfRange_UIntPtrMaxMinusOne = "The length of the buffer must be less than the maximum UIntPtr value for your platform.";
+ public const string Arg_BufferTooSmall = "Not enough space available in the buffer.";
+ public const string InvalidOperation_MustCallInitialize = "You must call Initialize on this object instance before using it.";
+ public const string ArgumentException_BufferNotFromPool = "The buffer is not associated with this pool and may not be returned to it.";
+ public const string Argument_InvalidSafeBufferOffLen = "Offset and length were greater than the size of the SafeBuffer.";
+ public const string Argument_InvalidSeekOrigin = "Invalid seek origin.";
+ public const string Argument_NotEnoughBytesToRead = "There are not enough bytes remaining in the accessor to read at this position.";
+ public const string Argument_NotEnoughBytesToWrite = "There are not enough bytes remaining in the accessor to write at this position.";
+ public const string Argument_OffsetAndCapacityOutOfBounds = "Offset and capacity were greater than the size of the view.";
+ public const string Argument_UnmanagedMemAccessorWrapAround = "The UnmanagedMemoryAccessor capacity and offset would wrap around the high end of the address space.";
+ public const string ArgumentOutOfRange_StreamLength = "Stream length must be non-negative and less than 2^31 - 1 - origin.";
+ public const string ArgumentOutOfRange_UnmanagedMemStreamWrapAround = "The UnmanagedMemoryStream capacity would wrap around the high end of the address space.";
+ public const string InvalidOperation_CalledTwice = "The method cannot be called twice on the same instance.";
+ public const string IO_FixedCapacity = "Unable to expand length of this stream beyond its capacity.";
+ public const string IO_SeekBeforeBegin = "An attempt was made to move the position before the beginning of the stream.";
+ public const string IO_StreamTooLong = "Stream was too long.";
+ public const string Arg_BadDecimal = "Read an invalid decimal value from the buffer.";
+ public const string NotSupported_Reading = "Accessor does not support reading.";
+ public const string NotSupported_UmsSafeBuffer = "This operation is not supported for an UnmanagedMemoryStream created from a SafeBuffer.";
+ public const string NotSupported_Writing = "Accessor does not support writing.";
+ public const string IndexOutOfRange_UMSPosition = "Unmanaged memory stream position was beyond the capacity of the stream.";
+ public const string ObjectDisposed_StreamIsClosed = "Cannot access a closed Stream.";
+ public const string ObjectDisposed_ViewAccessorClosed = "Cannot access a closed accessor.";
+ public const string ArgumentOutOfRange_PositionLessThanCapacityRequired = "The position may not be greater or equal to the capacity of the accessor.";
+ public const string Arg_EndOfStreamException = "Attempted to read past the end of the stream.";
+ public const string ObjectDisposed_FileClosed = "Cannot access a closed file.";
+ public const string Arg_InvalidSearchPattern = "Search pattern cannot contain \\\"..\\\" to move up directories and can be contained only internally in file/directory names, as in \\\"a..b\\\".";
+ public const string ArgumentOutOfRange_FileLengthTooBig = "Specified file length was too large for the file system.";
+ public const string Argument_InvalidHandle = "'handle' has been disposed or is an invalid handle.";
+ public const string Argument_AlreadyBoundOrSyncHandle = "'handle' has already been bound to the thread pool, or was not opened for asynchronous I/O.";
+ public const string Argument_PreAllocatedAlreadyAllocated = "'preAllocated' is already in use.";
+ public const string Argument_NativeOverlappedAlreadyFree = "'overlapped' has already been freed.";
+ public const string Argument_NativeOverlappedWrongBoundHandle = "'overlapped' was not allocated by this ThreadPoolBoundHandle instance.";
+ public const string Arg_HandleNotAsync = "Handle does not support asynchronous operations. The parameters to the FileStream constructor may need to be changed to indicate that the handle was opened synchronously (that is, it was not opened for overlapped I/O).";
+ public const string ArgumentNull_Path = "Path cannot be null.";
+ public const string Argument_EmptyPath = "Empty path name is not legal.";
+ public const string Argument_InvalidFileModeAndAccessCombo = "Combining FileMode: {0} with FileAccess: {1} is invalid.";
+ public const string Argument_InvalidAppendMode = "Append access can be requested only in write-only mode.";
+ public const string IO_UnknownFileName = "[Unknown]";
+ public const string IO_FileStreamHandlePosition = "The OS handle's position is not what FileStream expected. Do not use a handle simultaneously in one FileStream and in Win32 code or another FileStream. This may cause data loss.";
+ public const string NotSupported_FileStreamOnNonFiles = "FileStream was asked to open a device that was not a file. For support for devices like 'com1:' or 'lpt1:', call CreateFile, then use the FileStream constructors that take an OS handle as an IntPtr.";
+ public const string Arg_HandleNotSync = "Handle does not support synchronous operations. The parameters to the FileStream constructor may need to be changed to indicate that the handle was opened asynchronously (that is, it was opened explicitly for overlapped I/O).";
+ public const string IO_SetLengthAppendTruncate = "Unable to truncate data that previously existed in a file opened in Append mode.";
+ public const string IO_SeekAppendOverwrite = "Unable seek backward to overwrite data that previously existed in a file opened in Append mode.";
+ public const string IO_FileTooLongOrHandleNotSync = "IO operation will not work. Most likely the file will become too long or the handle was not opened to support synchronous IO operations.";
+ public const string EventStream_FailedToStart = "Failed to start the EventStream";
+ public const string InvalidDirName_NotExists = "The directory name '{0}' does not exist.";
+ public const string IOException_INotifyInstanceSystemLimitExceeded = "The system limit on the number of inotify instances has been reached.";
+ public const string IOException_INotifyInstanceUserLimitExceeded_Value = "The configured user limit ({0}) on the number of inotify instances has been reached.";
+ public const string IOException_INotifyInstanceUserLimitExceeded = "The configured user limit on the number of inotify instances has been reached.";
+ public const string IOException_INotifyWatchesUserLimitExceeded = "The configured user limit on the number of inotify watches has been reached.";
+ public const string IOException_INotifyWatchesUserLimitExceeded_Value = "The configured user limit ({0}) on the number of inotify watches has been reached.";
public const string Arg_NonZeroLowerBound = "The lower bound of target array must be zero.";
public const string Arg_WrongType = "The value '{0}' is not of type '{1}' and cannot be used in this generic collection.";
public const string Arg_ArrayPlusOffTooSmall = "Destination array is not long enough to copy all the items in the collection. Check array index and length.";
@@ -80,7 +331,6 @@ partial class SR
public const string Serialization_MismatchedCount = "The serialized Count information doesn't match the number of items.";
public const string Serialization_MissingKeys = "The keys for this dictionary are missing.";
public const string Serialization_MissingValues = "The values for this dictionary are missing.";
- public const string ArgumentException_BufferNotFromPool = "The buffer is not associated with this pool and may not be returned to it.";
public const string net_uri_BadAuthority = "Invalid URI: The Authority/Host could not be parsed.";
public const string net_uri_BadAuthorityTerminator = "Invalid URI: The Authority/Host cannot end with a backslash character ('\\\\').";
public const string net_uri_BadFormat = "Invalid URI: The format of the URI could not be determined.";
diff --git a/mcs/class/System/darwin_net_4_x_System.dll.sources b/mcs/class/System/darwin_net_4_x_System.dll.sources
new file mode 100644
index 00000000000..1b5d917651d
--- /dev/null
+++ b/mcs/class/System/darwin_net_4_x_System.dll.sources
@@ -0,0 +1,12 @@
+#include corefx.unix.sources
+#include net_4_x_System.dll.sources
+
+../../../external/corefx/src/Common/src/Interop/OSX/Interop.Libraries.cs
+../../../external/corefx/src/Common/src/Interop/OSX/Interop.EventStream.cs
+../../../external/corefx/src/Common/src/Interop/OSX/Interop.RunLoop.cs
+../../../external/corefx/src/Common/src/Interop/OSX/Interop.CoreFoundation.cs
+../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Sync.cs
+../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.RealPath.cs
+../../../external/corefx/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.OSX.cs
+../../../external/corefx/src/Common/src/Microsoft/Win32/SafeHandles/SafeCreateHandle.OSX.cs
+../../../external/corefx/src/Common/src/Microsoft/Win32/SafeHandles/SafeEventStreamHandle.OSX.cs
diff --git a/mcs/class/System/linux_net_4_x_System.dll.sources b/mcs/class/System/linux_net_4_x_System.dll.sources
new file mode 100644
index 00000000000..df7e37d575d
--- /dev/null
+++ b/mcs/class/System/linux_net_4_x_System.dll.sources
@@ -0,0 +1,16 @@
+#include corefx.unix.sources
+#include net_4_x_System.dll.sources
+
+../../../external/corefx/src/Common/src/Interop/Linux/Interop.Libraries.cs
+../../../external/corefx/src/Common/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
+../../../external/corefx/src/Common/src/Microsoft/Win32/SafeHandles/SafeDirectoryHandle.Unix.cs
+../../../external/corefx/src/Common/src/Interop/Linux/System.Native/Interop.INotify.cs
+../../../external/corefx/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs
+../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.OpenFlags.cs
+../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.ReadDir.cs
+../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.FLock.cs
+../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Stat.cs
+../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Poll.cs
+../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Open.cs
+../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Read.cs
+../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Close.cs
diff --git a/mcs/class/System/net_4_x_System.dll.sources b/mcs/class/System/net_4_x_System.dll.sources
index 1b60069cf89..1d53ca5b8f8 100644
--- a/mcs/class/System/net_4_x_System.dll.sources
+++ b/mcs/class/System/net_4_x_System.dll.sources
@@ -142,7 +142,11 @@ System.IO/IFileWatcher.cs
System.IO/InotifyWatcher.cs
System.IO/KeventWatcher.cs
System.IO/SearchPattern.cs
-System.IO/WindowsWatcher.cs
+
+../../../external/corefx/src/Common/src/System/IO/PathInternal.CaseSensitivity.cs
+../../../external/corefx/src/System.IO.FileSystem.Watcher/src/System/IO/PatternMatcher.cs
+../../../external/corefx/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs
+System.IO/CoreFXFileSystemWatcherProxy.cs
System.IO.Ports/Handshake.cs
System.IO.Ports/ISerialStream.cs
diff --git a/mcs/class/System/win32_net_4_x_System.dll.sources b/mcs/class/System/win32_net_4_x_System.dll.sources
new file mode 100644
index 00000000000..0fd1bac9058
--- /dev/null
+++ b/mcs/class/System/win32_net_4_x_System.dll.sources
@@ -0,0 +1,11 @@
+#include net_4_x_System.dll.sources
+
+../../../external/corefx/src/Common/src/Interop/Windows/Interop.Libraries.cs
+../../../external/corefx/src/Common/src/Interop/Windows/kernel32/Interop.CreateFile.cs
+../../../external/corefx/src/Common/src/Interop/Windows/kernel32/Interop.FileOperations.cs
+../../../external/corefx/src/Common/src/Interop/Windows/kernel32/Interop.SECURITY_ATTRIBUTES.cs
+../../../external/corefx/src/Common/src/Interop/Windows/Interop.BOOL.cs
+../../../external/corefx/src/Common/src/Interop/Windows/kernel32/Interop.CloseHandle.cs
+../../../external/corefx/src/Common/src/Interop/Windows/kernel32/Interop.ReadDirectoryChangesW.cs
+../../../external/corefx/src/Common/src/System/IO/PathInternal.Windows.cs
+../../../external/corefx/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Win32.cs
diff --git a/mcs/class/System/xammac_net_4_5_System.dll.sources b/mcs/class/System/xammac_net_4_5_System.dll.sources
index beb6f2415cf..502ec37dff3 100644
--- a/mcs/class/System/xammac_net_4_5_System.dll.sources
+++ b/mcs/class/System/xammac_net_4_5_System.dll.sources
@@ -1 +1 @@
-#include net_4_x_System.dll.sources
+#include darwin_net_4_x_System.dll.sources
diff --git a/mcs/class/test-helpers/PlatformDetection.cs b/mcs/class/test-helpers/PlatformDetection.cs
index 321d8eed680..fea6b0559df 100644
--- a/mcs/class/test-helpers/PlatformDetection.cs
+++ b/mcs/class/test-helpers/PlatformDetection.cs
@@ -23,5 +23,6 @@ namespace System
return id == PlatformID.Win32Windows || id == PlatformID.Win32NT;
}
}
+ public static bool IsInAppContainer => false;
}
-}
+} \ No newline at end of file
diff --git a/mono/metadata/filewatcher.c b/mono/metadata/filewatcher.c
index f0b8b148005..a81717b994e 100644
--- a/mono/metadata/filewatcher.c
+++ b/mono/metadata/filewatcher.c
@@ -59,8 +59,13 @@ static int (*FAMNextEvent) (gpointer, gpointer);
gint
ves_icall_System_IO_FSW_SupportsFSW (void)
{
-#if HAVE_KQUEUE
- return 3;
+#if defined(__APPLE__)
+ if (getenv ("MONO_DARWIN_USE_KQUEUE_FSW"))
+ return 3; /* kqueue */
+ else
+ return 6; /* FSEvent */
+#elif HAVE_KQUEUE
+ return 3; /* kqueue */
#else
MonoDl *fam_module;
int lib_used = 4; /* gamin */
@@ -260,3 +265,42 @@ ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq_ptr, gpointer change
#endif /* #if HAVE_KQUEUE */
+#if defined(__APPLE__)
+
+#include <CoreFoundation/CFRunLoop.h>
+
+static void
+interrupt_CFRunLoop (gpointer data)
+{
+ g_assert (data);
+ CFRunLoopStop(data);
+}
+
+void
+ves_icall_CoreFX_Interop_RunLoop_CFRunLoopRun (void)
+{
+ gpointer runloop_ref = CFRunLoopGetCurrent();
+ gboolean interrupted;
+ mono_thread_info_install_interrupt (interrupt_CFRunLoop, runloop_ref, &interrupted);
+
+ if (interrupted)
+ return;
+
+ MONO_ENTER_GC_SAFE;
+ CFRunLoopRun();
+ MONO_EXIT_GC_SAFE;
+
+ mono_thread_info_uninstall_interrupt (&interrupted);
+}
+
+MONO_API char* SystemNative_RealPath(const char* path)
+{
+ assert(path != NULL);
+ return realpath(path, NULL);
+}
+
+MONO_API void SystemNative_Sync(void)
+{
+ sync();
+}
+#endif /* #if defined(__APPLE__) */
diff --git a/mono/metadata/filewatcher.h b/mono/metadata/filewatcher.h
index 2a0f8b0e62c..65f68473e3c 100644
--- a/mono/metadata/filewatcher.h
+++ b/mono/metadata/filewatcher.h
@@ -34,6 +34,12 @@ int ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, gint32 watch_descrip
int ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq, gpointer changelist, int nchanges, gpointer eventlist, int nevents);
+#if defined(__APPLE__)
+void ves_icall_CoreFX_Interop_RunLoop_CFRunLoopRun (void);
+MONO_API char* SystemNative_RealPath(const char* path);
+MONO_API void SystemNative_Sync (void);
+#endif
+
G_END_DECLS
#endif
diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h
index 100d0efeefd..0d2f5bf940f 100644
--- a/mono/metadata/icall-def.h
+++ b/mono/metadata/icall-def.h
@@ -64,6 +64,11 @@
* Limitations: "out" and "ref" arguments are not supported yet.
*/
+ #if defined(__APPLE__)
+ICALL_TYPE(CLR_INTEROP, "Interop/RunLoop", CLR_INTEROP_1)
+ICALL(CLR_INTEROP_1, "CFRunLoopRun", ves_icall_CoreFX_Interop_RunLoop_CFRunLoopRun)
+#endif
+
#ifndef DISABLE_PROCESS_HANDLING
ICALL_TYPE(NATIVEMETHODS, "Microsoft.Win32.NativeMethods", NATIVEMETHODS_1)
ICALL(NATIVEMETHODS_1, "CloseProcess", ves_icall_Microsoft_Win32_NativeMethods_CloseProcess)