static void CompleteCallback(uint error, uint numBytes, NativeOverlapped *nativeOverlapped) { // Empty out the AsyncResult ASAP to close the leak window. Overlapped overlapped = Overlapped.Unpack(nativeOverlapped); OverlappedContext pThis = ((RootedHolder)overlapped.AsyncResult).ThisHolder; Fx.Assert(pThis != null, "Overlapped.AsyncResult not set. I/O completed multiple times, or cancelled I/O completed."); Fx.Assert(object.ReferenceEquals(pThis.overlapped, overlapped), "CompleteCallback completed with corrupt OverlappedContext.overlapped."); Fx.Assert(object.ReferenceEquals(pThis.rootedHolder, overlapped.AsyncResult), "CompleteCallback completed with corrupt OverlappedContext.rootedHolder."); pThis.rootedHolder.ThisHolder = null; Fx.Assert(pThis.bufferPtr == null || pThis.bufferPtr == (byte *)Marshal.UnsafeAddrOfPinnedArrayElement((byte[])pThis.bufferHolder[0], 0), "Buffer moved during bound async operation!"); // Release the pin. pThis.bufferPtr = null; pThis.bufferHolder[0] = OverlappedContext.dummyBuffer; OverlappedIOCompleteCallback callback = pThis.pendingCallback; pThis.pendingCallback = null; Fx.Assert(callback != null, "PendingCallback not set. I/O completed multiple times, or cancelled I/O completed."); callback(true, (int)error, checked ((int)numBytes)); }
public void CancelAsyncOperation() { this.rootedHolder.ThisHolder = null; if (this.registration != null) { this.registration.Unregister(null); this.registration = null; } this.bufferPtr = null; this.bufferHolder[0] = OverlappedContext.dummyBuffer; this.pendingCallback = null; }
public unsafe void CancelAsyncOperation() { this.rootedHolder.ThisHolder = null; if (this.registration != null) { this.registration.Unregister(null); this.registration = null; } this.bufferPtr = null; this.bufferHolder[0] = dummyBuffer; this.pendingCallback = null; }
private static unsafe void CompleteCallback(uint error, uint numBytes, System.Threading.NativeOverlapped *nativeOverlapped) { OverlappedContext thisHolder = ((RootedHolder)Overlapped.Unpack(nativeOverlapped).AsyncResult).ThisHolder; thisHolder.rootedHolder.ThisHolder = null; thisHolder.bufferPtr = null; thisHolder.bufferHolder[0] = dummyBuffer; OverlappedIOCompleteCallback pendingCallback = thisHolder.pendingCallback; thisHolder.pendingCallback = null; pendingCallback(true, (int)error, (int)numBytes); }
public void StartAsyncOperation(byte[] buffer, OverlappedIOCompleteCallback callback, bool bound) { if (callback == null) { throw Fx.AssertAndThrow("StartAsyncOperation called with null callback."); } if (this.pendingCallback != null) { throw Fx.AssertAndThrow("StartAsyncOperation called while another is in progress."); } if (this.syncOperationPending) { throw Fx.AssertAndThrow("StartAsyncOperation called while a [....] operation was already pending."); } if (this.nativeOverlapped == null) { throw Fx.AssertAndThrow("StartAsyncOperation called on freed OverlappedContext."); } this.pendingCallback = callback; if (buffer != null) { Fx.Assert(object.ReferenceEquals(this.bufferHolder[0], OverlappedContext.dummyBuffer), "StartAsyncOperation: buffer holder corrupted."); this.bufferHolder[0] = buffer; this.pinnedHandle.Target = this.pinnedTarget; this.bufferPtr = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); } if (bound) { this.overlapped.EventHandleIntPtr = IntPtr.Zero; // For completion ports, the back-reference is this member. this.rootedHolder.ThisHolder = this; } else { // Need to do this since we register the wait before posting the I/O. if (this.completionEvent != null) { this.completionEvent.Reset(); } this.overlapped.EventHandleIntPtr = EventHandle; // For unbound, the back-reference is this registration. this.registration = ThreadPool.UnsafeRegisterWaitForSingleObject(this.completionEvent, OverlappedContext.eventCallback, this, Timeout.Infinite, true); } }
public PendingAccept(PipeConnectionListener listener, PipeHandle pipeHandle, bool isBoundToCompletionPort, AsyncCallback callback, object state) : base(callback, state) { this.pipeHandle = pipeHandle; this.result = pipeHandle; this.listener = listener; this.onAcceptComplete = new OverlappedIOCompleteCallback(this.OnAcceptComplete); this.overlapped = new OverlappedContext(); this.isBoundToCompletionPort = isBoundToCompletionPort; if (!Thread.CurrentThread.IsThreadPoolThread) { if (onStartAccept == null) { onStartAccept = new Action <object>(PipeConnectionListener.PendingAccept.OnStartAccept); } ActionItem.Schedule(onStartAccept, this); } else { this.StartAccept(true); } }
public unsafe void StartAsyncOperation(byte[] buffer, OverlappedIOCompleteCallback callback, bool bound) { if (callback == null) { throw Fx.AssertAndThrow("StartAsyncOperation called with null callback."); } if (this.pendingCallback != null) { throw Fx.AssertAndThrow("StartAsyncOperation called while another is in progress."); } if (this.syncOperationPending) { throw Fx.AssertAndThrow("StartAsyncOperation called while a sync operation was already pending."); } if (this.nativeOverlapped == null) { throw Fx.AssertAndThrow("StartAsyncOperation called on freed OverlappedContext."); } this.pendingCallback = callback; if (buffer != null) { this.bufferHolder[0] = buffer; this.pinnedHandle.Target = this.pinnedTarget; this.bufferPtr = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); } if (bound) { this.overlapped.EventHandleIntPtr = IntPtr.Zero; this.rootedHolder.ThisHolder = this; } else { if (this.completionEvent != null) { this.completionEvent.Reset(); } this.overlapped.EventHandleIntPtr = this.EventHandle; this.registration = ThreadPool.UnsafeRegisterWaitForSingleObject(this.completionEvent, eventCallback, this, -1, true); } }
private static unsafe void EventCallback(object state, bool timedOut) { OverlappedContext context = state as OverlappedContext; if (timedOut) { if ((context == null) || (context.rootedHolder == null)) { DiagnosticUtility.FailFast("Can't prevent heap corruption."); } context.rootedHolder.ThisHolder = context; } else { context.registration = null; context.bufferPtr = null; context.bufferHolder[0] = dummyBuffer; OverlappedIOCompleteCallback pendingCallback = context.pendingCallback; context.pendingCallback = null; pendingCallback(false, 0, 0); } }
public PipeConnection(PipeHandle pipe, int connectionBufferSize, bool isBoundToCompletionPort, bool autoBindToCompletionPort) { if (pipe == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("pipe"); } if (pipe.IsInvalid) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("pipe"); } this.closeState = CloseState.Open; this.exceptionEventType = TraceEventType.Error; this.isBoundToCompletionPort = isBoundToCompletionPort; this.autoBindToCompletionPort = autoBindToCompletionPort; this.pipe = pipe; this.readBufferSize = connectionBufferSize; this.writeBufferSize = connectionBufferSize; this.readOverlapped = new OverlappedContext(); this.writeOverlapped = new OverlappedContext(); this.atEOFEvent = new ManualResetEvent(false); this.onAsyncReadComplete = new OverlappedIOCompleteCallback(this.OnAsyncReadComplete); this.onAsyncWriteComplete = new OverlappedIOCompleteCallback(this.OnAsyncWriteComplete); }
static void EventCallback(object state, bool timedOut) { OverlappedContext pThis = state as OverlappedContext; Fx.Assert(pThis != null, "OverlappedContext.EventCallback registered wait doesn't have an OverlappedContext as state."); if (timedOut) { Fx.Assert("OverlappedContext.EventCallback registered wait timed out."); // Turn this into a leak. Don't let ourselves get cleaned up - could scratch the heap. if (pThis == null || pThis.rootedHolder == null) { // We're doomed to do a wild write and corrupt the process. DiagnosticUtility.FailFast("Can't prevent heap corruption."); } pThis.rootedHolder.ThisHolder = pThis; return; } pThis.registration = null; Fx.Assert(pThis.bufferPtr == null || pThis.bufferPtr == (byte *)Marshal.UnsafeAddrOfPinnedArrayElement((byte[])pThis.bufferHolder[0], 0), "Buffer moved during unbound async operation!"); // Release the pin. pThis.bufferPtr = null; pThis.bufferHolder[0] = OverlappedContext.dummyBuffer; OverlappedIOCompleteCallback callback = pThis.pendingCallback; pThis.pendingCallback = null; Fx.Assert(callback != null, "PendingCallback not set. I/O completed multiple times, or cancelled I/O completed."); callback(false, 0, 0); }
public PendingAccept(PipeConnectionListener listener, PipeHandle pipeHandle, bool isBoundToCompletionPort, AsyncCallback callback, object state) : base(callback, state) { this.pipeHandle = pipeHandle; this.result = pipeHandle; this.listener = listener; this.onAcceptComplete = new OverlappedIOCompleteCallback(this.OnAcceptComplete); this.overlapped = new OverlappedContext(); this.isBoundToCompletionPort = isBoundToCompletionPort; if (!Thread.CurrentThread.IsThreadPoolThread) { if (onStartAccept == null) { onStartAccept = new Action<object>(PipeConnectionListener.PendingAccept.OnStartAccept); } ActionItem.Schedule(onStartAccept, this); } else { this.StartAccept(true); } }
public unsafe void StartAsyncOperation(byte[] buffer, OverlappedIOCompleteCallback callback, bool bound) { if (callback == null) { throw Fx.AssertAndThrow("StartAsyncOperation called with null callback."); } if (this.pendingCallback != null) { throw Fx.AssertAndThrow("StartAsyncOperation called while another is in progress."); } if (this.syncOperationPending) { throw Fx.AssertAndThrow("StartAsyncOperation called while a sync operation was already pending."); } if (this.nativeOverlapped == null) { throw Fx.AssertAndThrow("StartAsyncOperation called on freed OverlappedContext."); } this.pendingCallback = callback; if (buffer != null) { this.bufferHolder[0] = buffer; this.pinnedHandle.Target = this.pinnedTarget; this.bufferPtr = (byte*) Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); } if (bound) { this.overlapped.EventHandleIntPtr = IntPtr.Zero; this.rootedHolder.ThisHolder = this; } else { if (this.completionEvent != null) { this.completionEvent.Reset(); } this.overlapped.EventHandleIntPtr = this.EventHandle; this.registration = ThreadPool.UnsafeRegisterWaitForSingleObject(this.completionEvent, eventCallback, this, -1, true); } }
public void StartAsyncOperation(byte[] buffer, OverlappedIOCompleteCallback callback, bool bound) { if (callback == null) { throw Fx.AssertAndThrow("StartAsyncOperation called with null callback."); } if (this.pendingCallback != null) { throw Fx.AssertAndThrow("StartAsyncOperation called while another is in progress."); } if (this.syncOperationPending) { throw Fx.AssertAndThrow("StartAsyncOperation called while a [....] operation was already pending."); } if (this.nativeOverlapped == null) { throw Fx.AssertAndThrow("StartAsyncOperation called on freed OverlappedContext."); } this.pendingCallback = callback; if (buffer != null) { Fx.Assert(object.ReferenceEquals(this.bufferHolder[0], OverlappedContext.dummyBuffer), "StartAsyncOperation: buffer holder corrupted."); this.bufferHolder[0] = buffer; this.pinnedHandle.Target = this.pinnedTarget; this.bufferPtr = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); } if (bound) { this.overlapped.EventHandleIntPtr = IntPtr.Zero; // For completion ports, the back-reference is this member. this.rootedHolder.ThisHolder = this; } else { // Need to do this since we register the wait before posting the I/O. if (this.completionEvent != null) { this.completionEvent.Reset(); } this.overlapped.EventHandleIntPtr = EventHandle; // For unbound, the back-reference is this registration. this.registration = ThreadPool.UnsafeRegisterWaitForSingleObject(this.completionEvent, OverlappedContext.eventCallback, this, Timeout.Infinite, true); } }
private unsafe AsyncReadResult BeginReadCore(int offset, int size, TimeSpan timeout, WaitCallback callback, object state) { bool flag = true; lock (this.ThisLock) { this.ThrowIfClosed(); this.asyncReadState = state; this.asyncReadCallback = callback; this.asyncReadPending = true; this.SetReadTimeout(timeout, false, false); } try { if (this.socket.UseOnlyOverlappedIO) { try { IAsyncResult asyncResult = this.socket.BeginReceive(this.AsyncReadBuffer, offset, size, SocketFlags.None, this.onReceive, null); if (!asyncResult.CompletedSynchronously) { flag = false; return(AsyncReadResult.Queued); } this.asyncReadSize = this.socket.EndReceive(asyncResult); flag = false; return(AsyncReadResult.Completed); } catch (SocketException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(this.ConvertReceiveException(exception, TimeSpan.MaxValue), this.ExceptionEventType); } } if (this.readCallback == null) { try { this.socket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, null, null); } catch (SocketException exception2) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(this.ConvertReceiveException(exception2, TimeSpan.MaxValue), this.ExceptionEventType); } this.readCallback = new OverlappedIOCompleteCallback(this.AsyncReadCallback); } bool flag2 = true; try { int num = 0; int errorCode = 0; lock (this.ThisLock) { UnsafeNativeMethods.WSABuffer buffer; this.ThrowIfClosed(); buffer.length = Math.Min(this.AsyncReadBuffer.Length - offset, size); this.asyncReadOverlapped.StartAsyncOperation(this.AsyncReadBuffer, this.readCallback, true); buffer.buffer = (IntPtr)(this.asyncReadOverlapped.BufferPtr + offset); num = UnsafeNativeMethods.WSARecv(this.socket.Handle, &buffer, 1, out bytesTransferred, ref socketFlags, this.asyncReadOverlapped.NativeOverlapped, IntPtr.Zero); if (num == -1) { errorCode = Marshal.GetLastWin32Error(); } } if (((num == -1) && (errorCode != 0x3e5)) && (errorCode != 0xea)) { flag2 = false; SocketException socketException = new SocketException(errorCode); throw DiagnosticUtility.ExceptionUtility.ThrowHelper(this.ConvertReceiveException(socketException, TimeSpan.MaxValue), this.ExceptionEventType); } } finally { if (!flag2) { this.asyncReadOverlapped.CancelAsyncOperation(); } } flag = false; } catch (ObjectDisposedException exception4) { Exception objA = this.ConvertObjectDisposedException(exception4, TransferOperation.Read); if (object.ReferenceEquals(objA, exception4)) { throw; } throw DiagnosticUtility.ExceptionUtility.ThrowHelper(objA, this.ExceptionEventType); } finally { if (flag) { this.AbortRead(); } } return(AsyncReadResult.Queued); }
public unsafe PendingAccept(PipeConnectionListener listener, PipeHandle pipeHandle, bool isBoundToCompletionPort, AsyncCallback callback, object state) : base(callback, state) { this.pipeHandle = pipeHandle; this.result = pipeHandle; this.listener = listener; onAcceptComplete = new OverlappedIOCompleteCallback(OnAcceptComplete); overlapped = new OverlappedContext(); this.isBoundToCompletionPort = isBoundToCompletionPort; if (TD.PipeConnectionAcceptStartIsEnabled()) { this.eventTraceActivity = new EventTraceActivity(); TD.PipeConnectionAcceptStart(this.eventTraceActivity, this.listener.pipeUri != null ? this.listener.pipeUri.ToString() : string.Empty); } if (!Thread.CurrentThread.IsThreadPoolThread) { if (onStartAccept == null) { onStartAccept = new Action<object>(OnStartAccept); } ActionItem.Schedule(onStartAccept, this); } else { StartAccept(true); } }
private unsafe AsyncReadResult BeginReadCore(int offset, int size, TimeSpan timeout, WaitCallback callback, object state) { bool flag = true; lock (this.ThisLock) { this.ThrowIfClosed(); this.asyncReadState = state; this.asyncReadCallback = callback; this.asyncReadPending = true; this.SetReadTimeout(timeout, false, false); } try { if (this.socket.UseOnlyOverlappedIO) { try { IAsyncResult asyncResult = this.socket.BeginReceive(this.AsyncReadBuffer, offset, size, SocketFlags.None, this.onReceive, null); if (!asyncResult.CompletedSynchronously) { flag = false; return AsyncReadResult.Queued; } this.asyncReadSize = this.socket.EndReceive(asyncResult); flag = false; return AsyncReadResult.Completed; } catch (SocketException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(this.ConvertReceiveException(exception, TimeSpan.MaxValue), this.ExceptionEventType); } } if (this.readCallback == null) { try { this.socket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, null, null); } catch (SocketException exception2) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(this.ConvertReceiveException(exception2, TimeSpan.MaxValue), this.ExceptionEventType); } this.readCallback = new OverlappedIOCompleteCallback(this.AsyncReadCallback); } bool flag2 = true; try { int num = 0; int errorCode = 0; lock (this.ThisLock) { UnsafeNativeMethods.WSABuffer buffer; this.ThrowIfClosed(); buffer.length = Math.Min(this.AsyncReadBuffer.Length - offset, size); this.asyncReadOverlapped.StartAsyncOperation(this.AsyncReadBuffer, this.readCallback, true); buffer.buffer = (IntPtr) (this.asyncReadOverlapped.BufferPtr + offset); num = UnsafeNativeMethods.WSARecv(this.socket.Handle, &buffer, 1, out bytesTransferred, ref socketFlags, this.asyncReadOverlapped.NativeOverlapped, IntPtr.Zero); if (num == -1) { errorCode = Marshal.GetLastWin32Error(); } } if (((num == -1) && (errorCode != 0x3e5)) && (errorCode != 0xea)) { flag2 = false; SocketException socketException = new SocketException(errorCode); throw DiagnosticUtility.ExceptionUtility.ThrowHelper(this.ConvertReceiveException(socketException, TimeSpan.MaxValue), this.ExceptionEventType); } } finally { if (!flag2) { this.asyncReadOverlapped.CancelAsyncOperation(); } } flag = false; } catch (ObjectDisposedException exception4) { Exception objA = this.ConvertObjectDisposedException(exception4, TransferOperation.Read); if (object.ReferenceEquals(objA, exception4)) { throw; } throw DiagnosticUtility.ExceptionUtility.ThrowHelper(objA, this.ExceptionEventType); } finally { if (flag) { this.AbortRead(); } } return AsyncReadResult.Queued; }