//
// Copyright (C) Tim Coleman, 2002
// (c) 2003 Ximian, Inc. (http://www.ximian.com)
-// (c) 2004 Novell, Inc. (http://www.novell.com)
+// Copyright (C) 2004, 2006 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.
//
-using System;
using System.ComponentModel;
+using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Security.Permissions;
using System.Threading;
namespace System.IO {
[DefaultEvent("Changed")]
+#if NET_2_0
+ [IODescription ("")]
+#endif
public class FileSystemWatcher : Component, ISupportInitialize {
#region Fields
bool disposed;
string mangledFilter;
static IFileWatcher watcher;
+ static object lockobj = new object ();
#endregion // Fields
InitWatcher ();
}
+ [EnvironmentPermission (SecurityAction.Assert, Read="MONO_MANAGED_WATCHER")]
void InitWatcher ()
{
- lock (typeof (FileSystemWatcher)) {
+ lock (lockobj) {
if (watcher != null)
return;
int mode = 0;
if (managed == null)
mode = InternalSupportsFSW ();
-
+
bool ok = false;
- if (mode == 2)
- ok = FAMWatcher.GetInstance (out watcher);
- else if (mode == 1)
+ switch (mode) {
+ case 1: // windows
ok = DefaultWatcher.GetInstance (out watcher);
//ok = WindowsWatcher.GetInstance (out watcher);
+ break;
+ case 2: // libfam
+ ok = FAMWatcher.GetInstance (out watcher, false);
+ break;
+ case 3: // kevent
+ ok = KeventWatcher.GetInstance (out watcher);
+ break;
+ case 4: // libgamin
+ ok = FAMWatcher.GetInstance (out watcher, true);
+ break;
+ case 5: // inotify
+ ok = InotifyWatcher.GetInstance (out watcher, true);
+ break;
+ }
+
+ if (mode == 0 || !ok) {
+ if (String.Compare (managed, "disabled", true) == 0)
+ NullFileWatcher.GetInstance (out watcher);
+ else
+ DefaultWatcher.GetInstance (out watcher);
+ }
- if (mode == 0 || !ok)
- DefaultWatcher.GetInstance (out watcher);
+ ShowWatcherInfo ();
}
}
+ [Conditional ("DEBUG"), Conditional ("TRACE")]
+ void ShowWatcherInfo ()
+ {
+ Console.WriteLine ("Watcher implementation: {0}", watcher != null ? watcher.GetType ().ToString () : "<none>");
+ }
+
#endregion // Constructors
#region Properties
[DefaultValue(null)]
[IODescription("The object used to marshal the event handler calls resulting from a directory change")]
+#if NET_2_0
+ [Browsable (false)]
+#endif
public ISynchronizeInvoke SynchronizingObject {
get { return synchronizingObject; }
set { synchronizingObject = value; }
#region Methods
- [MonoTODO]
public void BeginInit ()
{
- throw new NotImplementedException ();
+ // Not necessary in Mono
}
protected override void Dispose (bool disposing)
Stop ();
}
- [MonoTODO]
public void EndInit ()
{
- throw new NotImplementedException ();
+ // Not necessary in Mono
}
- private void RaiseEvent (Delegate ev, EventArgs arg)
+ enum EventType {
+ FileSystemEvent,
+ ErrorEvent,
+ RenameEvent
+ }
+ private void RaiseEvent (Delegate ev, EventArgs arg, EventType evtype)
{
if (ev == null)
return;
- object [] args = new object [] {this, arg};
-
if (synchronizingObject == null) {
- ev.DynamicInvoke (args);
+ switch (evtype) {
+ case EventType.RenameEvent:
+ ((RenamedEventHandler)ev).BeginInvoke (this, (RenamedEventArgs) arg, null, null);
+ break;
+ case EventType.ErrorEvent:
+ ((ErrorEventHandler)ev).BeginInvoke (this, (ErrorEventArgs) arg, null, null);
+ break;
+ case EventType.FileSystemEvent:
+ ((FileSystemEventHandler)ev).BeginInvoke (this, (FileSystemEventArgs) arg, null, null);
+ break;
+ }
return;
}
- synchronizingObject.BeginInvoke (ev, args);
+ synchronizingObject.BeginInvoke (ev, new object [] {this, arg});
}
protected void OnChanged (FileSystemEventArgs e)
{
- RaiseEvent (Changed, e);
+ RaiseEvent (Changed, e, EventType.FileSystemEvent);
}
protected void OnCreated (FileSystemEventArgs e)
{
- RaiseEvent (Created, e);
+ RaiseEvent (Created, e, EventType.FileSystemEvent);
}
protected void OnDeleted (FileSystemEventArgs e)
{
- RaiseEvent (Deleted, e);
+ RaiseEvent (Deleted, e, EventType.FileSystemEvent);
}
protected void OnError (ErrorEventArgs e)
{
- RaiseEvent (Error, e);
+ RaiseEvent (Error, e, EventType.ErrorEvent);
}
protected void OnRenamed (RenamedEventArgs e)
{
- RaiseEvent (Renamed, e);
+ RaiseEvent (Renamed, e, EventType.RenameEvent);
}
public WaitForChangedResult WaitForChanged (WatcherChangeTypes changeType)
}
lastData.OldName = filename;
lastData.ChangeType = WatcherChangeTypes.Renamed;
- renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, path, null, filename);
+ renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, path, filename, "");
break;
case FileAction.RenamedNewName:
lastData.Name = filename;
lastData.ChangeType = WatcherChangeTypes.Renamed;
- if (renamed != null) {
- renamed.SetName (filename);
- } else {
- renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, path, filename, null);
+ if (renamed == null) {
+ renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, path, "", filename);
}
OnRenamed (renamed);
renamed = null;
/* 0 -> not supported */
/* 1 -> windows */
/* 2 -> FAM */
+ /* 3 -> Kevent */
+ /* 4 -> gamin */
+ /* 5 -> inotify */
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern int InternalSupportsFSW ();
-
- /*[MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern IntPtr InternalOpenDirectory (string path, IntPtr reserved);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern IntPtr InternalCloseDirectory (IntPtr handle);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern bool InternalReadDirectoryChanges (IntPtr handle,
- byte [] buffer,
- bool includeSubdirectories,
- NotifyFilters notifyFilter,
- out NativeOverlapped overlap,
- OverlappedHandler overlappedCallback);
-
- */
}
}
+