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;
 }
Example #4
0
        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);
     }
 }
Example #7
0
 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);
     }
 }
Example #8
0
        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);
            }
        }
Example #14
0
        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);
        }
Example #15
0
            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;
 }