View | Details | Raw Unified | Return to bug 206593 | Differences between
and this patch

Collapse All | Expand All

(-)mcs/class/System/System.IO/KeventWatcher.cs (-21 / +22 lines)
Lines 232-239 Link Here
232
					conn = -1;
232
					conn = -1;
233
				}
233
				}
234
234
235
				if (!thread.Join (2000))
235
				while (!thread.Join (2000))
236
					thread.Abort ();
236
					thread.Interrupt ();
237
237
238
				requestStop = false;
238
				requestStop = false;
239
				started = false;
239
				started = false;
Lines 374-394 Link Here
374
			while (!requestStop) {
374
			while (!requestStop) {
375
				var changes = CreateChangeList (ref newFds);
375
				var changes = CreateChangeList (ref newFds);
376
376
377
				// We are calling an icall, so have to marshal manually
377
				int numEvents = kevent_notimeout (conn, changes, changes.Length, eventBuffer, eventBuffer.Length, IntPtr.Zero);
378
				// Marshal in
379
				int ksize = Marshal.SizeOf<kevent> ();
380
				var changesNative = Marshal.AllocHGlobal (ksize * changes.Length);
381
				for (int i = 0; i < changes.Length; ++i)
382
					Marshal.StructureToPtr (changes [i], changesNative + (i * ksize), false);
383
				var eventBufferNative = Marshal.AllocHGlobal (ksize * eventBuffer.Length);
384
385
				int numEvents = kevent_notimeout (ref conn, changesNative, changes.Length, eventBufferNative, eventBuffer.Length);
386
387
				// Marshal out
388
				Marshal.FreeHGlobal (changesNative);
389
				for (int i = 0; i < numEvents; ++i)
390
					eventBuffer [i] = Marshal.PtrToStructure<kevent> (eventBufferNative + (i * ksize));
391
				Marshal.FreeHGlobal (eventBufferNative);
392
378
393
				if (numEvents == -1) {
379
				if (numEvents == -1) {
394
					// Stop () signals us to stop by closing the connection
380
					// Stop () signals us to stop by closing the connection
Lines 401-406 Link Here
401
387
402
					continue;
388
					continue;
403
				}
389
				}
390
404
				retries = 0;
391
				retries = 0;
405
392
406
				for (var i = 0; i < numEvents; i++) {
393
				for (var i = 0; i < numEvents; i++) {
Lines 428-435 Link Here
428
					}
415
					}
429
416
430
					if ((kevt.fflags & FilterFlags.VNodeRename) == FilterFlags.VNodeRename) {
417
					if ((kevt.fflags & FilterFlags.VNodeRename) == FilterFlags.VNodeRename) {
431
							UpdatePath (pathData);
418
						/* We can simply remove the entire subtree here, as
432
					} 
419
						   the move will trigger a directory update and thus
420
						   a re-scan at the new location, which will cause any
421
						   children to be re-added. */
422
						removeQueue.Add (pathData);
423
						if (pathData.IsDirectory) {
424
							var prefix = pathData.Path + Path.DirectorySeparatorChar;
425
							foreach (var path in pathsDict.Keys)
426
								if (path.StartsWith (prefix)) {
427
									removeQueue.Add (pathsDict [path]);
428
								}
429
						}
430
						PostEvent (FileAction.RenamedOldName, pathData.Path);
431
					}
433
432
434
					if ((kevt.fflags & FilterFlags.VNodeWrite) == FilterFlags.VNodeWrite) {
433
					if ((kevt.fflags & FilterFlags.VNodeWrite) == FilterFlags.VNodeWrite) {
435
						if (pathData.IsDirectory) //TODO: Check if dirs trigger Changed events on .NET
434
						if (pathData.IsDirectory) //TODO: Check if dirs trigger Changed events on .NET
Lines 626-631 Link Here
626
			if (action == FileAction.RenamedNewName) {
625
			if (action == FileAction.RenamedNewName) {
627
				string newName = (newPath.Length > fullPathNoLastSlash.Length) ? newPath.Substring (fullPathNoLastSlash.Length + 1) : String.Empty;
626
				string newName = (newPath.Length > fullPathNoLastSlash.Length) ? newPath.Substring (fullPathNoLastSlash.Length + 1) : String.Empty;
628
				renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, fsw.Path, newName, name);
627
				renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, fsw.Path, newName, name);
628
			} else if (action == FileAction.RenamedOldName) {
629
				renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, fsw.Path, null, name);
629
			}
630
			}
630
				
631
				
631
			fsw.DispatchEvents (action, name, ref renamed);
632
			fsw.DispatchEvents (action, name, ref renamed);
Lines 695-702 Link Here
695
		[DllImport ("libc", SetLastError=true)]
696
		[DllImport ("libc", SetLastError=true)]
696
		extern static int kevent (int kq, [In]kevent[] ev, int nchanges, [Out]kevent[] evtlist, int nevents, [In] ref timespec time);
697
		extern static int kevent (int kq, [In]kevent[] ev, int nchanges, [Out]kevent[] evtlist, int nevents, [In] ref timespec time);
697
698
698
		[MethodImplAttribute(MethodImplOptions.InternalCall)]
699
		[DllImport ("libc", EntryPoint="kevent", SetLastError=true)]
699
		extern static int kevent_notimeout (ref int kq, IntPtr ev, int nchanges, IntPtr evtlist, int nevents);
700
		extern static int kevent_notimeout (int kq, [In]kevent[] ev, int nchanges, [Out]kevent[] evtlist, int nevents, IntPtr ptr);
700
	}
701
	}
701
702
702
	class KeventWatcher : IFileWatcher
703
	class KeventWatcher : IFileWatcher

Return to bug 206593