changeset 110:5e717aac4c1d

Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
author Ivo Smits <Ivo@UCIS.nl>
date Fri, 07 Nov 2014 18:33:34 +0100
parents 2b5e7bb9b979
children df53bdd49507
files Remoting/RemotingManager.cs Windows/WindowsNamedPipe.cs
diffstat 2 files changed, 14 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/Remoting/RemotingManager.cs	Wed Sep 03 21:44:26 2014 +0200
+++ b/Remoting/RemotingManager.cs	Fri Nov 07 18:33:34 2014 +0100
@@ -17,7 +17,7 @@
 	public class RemotingManager {
 		Dictionary<UInt32, PendingRemoteCall> pendingCalls = new Dictionary<uint, PendingRemoteCall>();
 		Dictionary<Thread, UInt32> waitingCallThreads = new Dictionary<Thread, UInt32>();
-		Boolean Closed = false;
+		public Boolean Closed { get; private set; }
 
 		IDictionary<String, Object> incomingCallContext = new Dictionary<String, Object>();
 		[ThreadStatic]
@@ -25,6 +25,7 @@
 
 		public event Action<String> OnDebugLog;
 		public event Action<Exception> OnErrorLog;
+		public event Action<RemotingManager> OnClosed;
 
 		private void DebugLog(String text, params Object[] args) {
 			if (OnDebugLog != null) OnDebugLog(String.Format(text, args));
@@ -42,6 +43,7 @@
 		public RemotingManager(PacketStream stream, Object localRoot) {
 			this.stream = stream;
 			this.LocalRoot = localRoot;
+			this.Closed = false;
 			stream.BeginReadPacketFast(ReceiveCallback, null);
 		}
 
@@ -135,6 +137,7 @@
 					streamChannels.Clear();
 				}
 				ErrorLog(ex);
+				if (OnClosed != null) OnClosed(this);
 			}
 		}
 		private void SendObject(Object obj) {
--- a/Windows/WindowsNamedPipe.cs	Wed Sep 03 21:44:26 2014 +0200
+++ b/Windows/WindowsNamedPipe.cs	Fri Nov 07 18:33:34 2014 +0100
@@ -28,6 +28,9 @@
 		static extern unsafe bool ConnectNamedPipe(SafeFileHandle hNamedPipe, NativeOverlapped* lpOverlapped);
 		[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
 		static extern unsafe bool GetNamedPipeInfo(SafeFileHandle hNamedPipe, out UInt32 lpFlags, IntPtr lpOutBufferSize, IntPtr lpInBufferSize, IntPtr lpMaxInstances);
+		[DllImport("kernel32.dll")]
+		[return: MarshalAs(UnmanagedType.Bool)]
+		static extern bool CancelIo(SafeFileHandle hFile);
 
 		const UInt32 PIPE_ACCESS_DUPLEX = 0x00000003;
 		const UInt32 FILE_FLAG_OVERLAPPED = 0x40000000;
@@ -60,6 +63,9 @@
 		}
 
 		public unsafe void WaitForClient() {
+			WaitForClient(-1);
+		}
+		public unsafe void WaitForClient(int millisecondsTimeout) {
 			uint nread;
 			using (ManualResetEvent evt = new ManualResetEvent(false)) {
 				NativeOverlapped overlapped = new NativeOverlapped();
@@ -67,7 +73,10 @@
 				if (!ConnectNamedPipe(PipeHandle, &overlapped)) {
 					int err = Marshal.GetLastWin32Error();
 					if (err != 997) throw new Win32Exception(err);
-					evt.WaitOne();
+					if (!evt.WaitOne(millisecondsTimeout)) {
+						CancelIo(PipeHandle);
+						throw new TimeoutException("The operation timed out");
+					}
 					if (!GetOverlappedResult(PipeHandle, &overlapped, out nread, false)) throw new Win32Exception(Marshal.GetLastWin32Error());
 				}
 			}