freebsd-ports/lang/mono/files/patch-mcs_class_System_System.IO_KeventWatcher.cs
Romain Tartière 5c80951022 - Update lang/mono to 2.6.4;
- Update a bunch of C# ports as well (audio/taglib-sharp, deskutils/tomboy,
  devel/mono-tools, devel/monodevelop, devel/monodevelop-boo,
  devel/monodevelop-database, devel/monodevelop-java, devel/monodevelop-vala,
  graphics/f-spot, lang/boo [1], lang/mono-basic, mail/gmime24, gmime24-sharp,
  multimedia/banshee, multimedia/banshee-mirage, multimedia/moonlight,
  www/mod_mono, www/webkit-sharp, www/xsp, x11-toolkits/gnome-desktop-sharp20,
  x11-toolkits/gtk-sharp20, x11-toolkits/libgdiplus).

PR:		ports/143657 [1]
Submitted by:	glewis [1]
2010-06-01 12:41:30 +00:00

196 lines
5.3 KiB
C#

$FreeBSD$
https://bugzilla.novell.com/show_bug.cgi?id=542485
--- mcs/class/System/System.IO/KeventWatcher.cs.orig
+++ mcs/class/System/System.IO/KeventWatcher.cs
@@ -38,11 +38,11 @@
namespace System.IO {
struct kevent : IDisposable {
- public int ident;
+ public IntPtr ident;
public short filter;
public ushort flags;
public uint fflags;
- public int data;
+ public IntPtr data;
public IntPtr udata;
public void Dispose ()
@@ -53,8 +53,8 @@
}
struct timespec {
- public int tv_sec;
- public int tv_usec;
+ public IntPtr tv_sec;
+ public IntPtr tv_usec;
}
class KeventFileData {
@@ -88,6 +88,31 @@
static Thread thread;
static int conn;
static bool stop;
+
+ /* Flags */
+
+ const int EV_ADD = 0x0001; /* add event to kq (implies enable) */
+ const int EV_DELETE = 0x0002; /* delete event from kq */
+ const int EV_ENABLE = 0x0004; /* enable event */
+ const int EV_DISABLE = 0x0008; /* disable event (not reported) */
+ const int EV_ONESHOT = 0x0010; /* only report one occurrence */
+ const int EV_CLEAR = 0x0020; /* clear event state after reporting */
+ const int EV_EOF = 0x8000; /* EOF detected */
+ const int EV_ERROR = 0x4000; /* error, data contains errno */
+
+ /* System defined filters */
+ const int EVFILT_READ = -1;
+ const int EVFILT_VNODE = -4; /* attached to vnodes */
+
+ /* Events */
+
+ const int NOTE_DELETE = 0x0001; /* vnode was removed */
+ const int NOTE_WRITE = 0x0002; /* data contents changed */
+ const int NOTE_EXTEND = 0x0004; /* size increased */
+ const int NOTE_ATTRIB = 0x0008; /* attributes changed */
+ const int NOTE_LINK = 0x0010; /* link count changed */
+ const int NOTE_RENAME = 0x0020; /* vnode was renamed */
+ const int NOTE_REVOKE = 0x0040; /* vnode access was revoked */
private KeventWatcher ()
{
@@ -142,9 +167,9 @@
data.Enabled = true;
lock (this) {
+ stop = false;
StartMonitoringDirectory (data);
watches [fsw] = data;
- stop = false;
}
}
}
@@ -162,20 +187,23 @@
kevent ev = new kevent();
ev.udata = IntPtr.Zero;
timespec nullts = new timespec();
- nullts.tv_sec = 0;
- nullts.tv_usec = 0;
+ nullts.tv_sec = IntPtr.Zero;
+ nullts.tv_usec = IntPtr.Zero;
if (fd > 0) {
- ev.ident = fd;
- ev.filter = -4;
- ev.flags = 1 | 4 | 20;
- ev.fflags = 20 | 2 | 1 | 8;
- ev.data = 0;
+ ev.ident = (IntPtr)fd;
+ ev.filter = EVFILT_VNODE;
+ ev.flags = EV_ADD | EV_ENABLE | EV_CLEAR;
+ ev.fflags = NOTE_RENAME | NOTE_WRITE | NOTE_DELETE | NOTE_ATTRIB;
+ ev.data = IntPtr.Zero;
ev.udata = Marshal.StringToHGlobalAuto (data.Directory);
kevent outev = new kevent();
outev.udata = IntPtr.Zero;
- kevent (conn, ref ev, 1, ref outev, 0, ref nullts);
+ int ret = kevent (conn, ref ev, 1, ref outev, 0, ref nullts);
+ if ((ret == -1) || ((ev.flags & EV_ERROR) > 0)) {
+ return;
+ }
data.ev = ev;
- requests [fd] = data;
+ requests [(IntPtr)fd] = data;
}
if (!data.IncludeSubdirs)
@@ -204,31 +232,35 @@
static void StopMonitoringDirectory (KeventData data)
{
- close(data.ev.ident);
+ close((int)(data.ev.ident));
}
void Monitor ()
{
-
+
while (!stop) {
kevent ev = new kevent();
ev.udata = IntPtr.Zero;
kevent nullev = new kevent();
nullev.udata = IntPtr.Zero;
timespec ts = new timespec();
- ts.tv_sec = 0;
- ts.tv_usec = 0;
+ ts.tv_sec = IntPtr.Zero;
+ ts.tv_usec = IntPtr.Zero;
int haveEvents;
lock (this) {
haveEvents = kevent (conn, ref nullev, 0, ref ev, 1, ref ts);
}
- if (haveEvents > 0) {
- // Restart monitoring
- KeventData data = (KeventData) requests [ev.ident];
- StopMonitoringDirectory (data);
- StartMonitoringDirectory (data);
- ProcessEvent (ev);
+ if (haveEvents != 0) {
+ if ((haveEvents == -1) || ((ev.flags & EV_ERROR) > 0)) {
+ Error ();
+ } else {
+ // Restart monitoring
+ KeventData data = (KeventData) requests [(IntPtr)(ev.ident)];
+ StopMonitoringDirectory (data);
+ StartMonitoringDirectory (data);
+ ProcessEvent (ev);
+ }
} else {
System.Threading.Thread.Sleep (500);
}
@@ -240,10 +272,18 @@
}
}
+ void Error ()
+ {
+ // Something went wrong. Stop the thread.
+ lock (this) {
+ stop = true;
+ }
+ }
+
void ProcessEvent (kevent ev)
{
lock (this) {
- KeventData data = (KeventData) requests [ev.ident];
+ KeventData data = (KeventData) requests [(IntPtr)(ev.ident)];
if (!data.Enabled)
return;
@@ -265,7 +305,7 @@
data.DirEntries [fsi.FullName] = new KeventFileData(fsi, fsi.LastAccessTime, fsi.LastWriteTime);
if (fsw.IncludeSubdirectories && fsi is DirectoryInfo) {
data.Directory = filename;
- requests [ev.ident] = data;
+ requests [(IntPtr)(ev.ident)] = data;
ProcessEvent(ev);
}
PostEvent(filename, fsw, fa, changedFsi);
@@ -348,10 +388,10 @@
[DllImport ("libc")]
extern static int close(int fd);
- [DllImport ("libc")]
+ [DllImport ("libc", SetLastError=true)]
extern static int kqueue();
- [DllImport ("libc")]
+ [DllImport ("libc", SetLastError=true)]
extern static int kevent(int kqueue, ref kevent ev, int nchanges, ref kevent evtlist, int nevents, ref timespec ts);
}
}