Exemplo n.º 1
0
 internal void CallUserCallback()
 {
     if (_userCallback != null)
     {
         _completedSynchronously = false;
         ThreadPool.QueueUserWorkItem(s =>
         {
             PipeAsyncResult ar = (PipeAsyncResult)s;
             ar._isComplete     = true;
             if (ar._waitHandle != null)
             {
                 ar._waitHandle.Set();
             }
             ar._userCallback(ar);
         }, this);
     }
     else
     {
         _isComplete = true;
         if (_waitHandle != null)
         {
             _waitHandle.Set();
         }
     }
 }
        unsafe private static void AsyncWaitForConnectionCallback(uint errorCode, uint numBytes, NativeOverlapped *pOverlapped)
        {
            // Unpack overlapped
            Overlapped overlapped = Overlapped.Unpack(pOverlapped);

            // Extract async result from overlapped
            PipeAsyncResult asyncResult = (PipeAsyncResult)overlapped.AsyncResult;

            // Free the pinned overlapped:
            Debug.Assert(asyncResult._overlapped == pOverlapped);
            Overlapped.Free(pOverlapped);
            asyncResult._overlapped = null;

            // Special case for when the client has already connected to us.
            if (errorCode == Interop.ERROR_PIPE_CONNECTED)
            {
                errorCode = 0;
            }

            asyncResult._errorCode = (int)errorCode;

            // Call the user-provided callback.  It can and often should
            // call EndWaitForConnection.  There's no reason to use an async
            // delegate here - we're already on a threadpool thread.
            // IAsyncResult's completedSynchronously property must return
            // false here, saying the user callback was called on another thread.
            asyncResult._completedSynchronously = false;
            asyncResult._isComplete             = true;

            // The OS does not signal this event.  We must do it ourselves.
            ManualResetEvent wh = asyncResult._waitHandle;

            if (wh != null)
            {
                Debug.Assert(!wh.GetSafeWaitHandle().IsClosed, "ManualResetEvent already closed!");
                bool r = wh.Set();
                Debug.Assert(r, "ManualResetEvent::Set failed!");
                if (!r)
                {
                    throw Win32Marshal.GetExceptionForLastWin32Error();
                }
            }

            AsyncCallback userCallback = asyncResult._userCallback;

            if (userCallback != null)
            {
                userCallback(asyncResult);
            }
        }
Exemplo n.º 3
0
        public unsafe void EndWaitForConnection(IAsyncResult asyncResult)
        {
            this.CheckConnectOperationsServer();
            if (asyncResult == null)
            {
                throw new ArgumentNullException("asyncResult");
            }
            if (!base.IsAsync)
            {
                throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeNotAsync"));
            }
            PipeAsyncResult result = asyncResult as PipeAsyncResult;

            if (result == null)
            {
                System.IO.__Error.WrongAsyncResult();
            }
            if (1 == Interlocked.CompareExchange(ref result._EndXxxCalled, 1, 0))
            {
                System.IO.__Error.EndWaitForConnectionCalledTwice();
            }
            WaitHandle handle = result._waitHandle;

            if (handle != null)
            {
                try
                {
                    handle.WaitOne();
                }
                finally
                {
                    handle.Close();
                }
            }
            NativeOverlapped *nativeOverlappedPtr = result._overlapped;

            if (nativeOverlappedPtr != null)
            {
                Overlapped.Free(nativeOverlappedPtr);
            }
            if (result._errorCode != 0)
            {
                System.IO.__Error.WinIOError(result._errorCode, string.Empty);
            }
            base.State = PipeState.Connected;
        }
Exemplo n.º 4
0
        public unsafe IAsyncResult BeginWaitForConnection(AsyncCallback callback, object state)
        {
            this.CheckConnectOperationsServer();
            if (!base.IsAsync)
            {
                throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeNotAsync"));
            }
            PipeAsyncResult ar = new PipeAsyncResult {
                _handle          = base.InternalHandle,
                _userCallback    = callback,
                _userStateObject = state
            };
            ManualResetEvent event2 = new ManualResetEvent(false);

            ar._waitHandle = event2;
            NativeOverlapped *overlapped = new Overlapped(0, 0, IntPtr.Zero, ar).Pack(WaitForConnectionCallback, null);

            ar._overlapped = overlapped;
            if (!Microsoft.Win32.UnsafeNativeMethods.ConnectNamedPipe(base.InternalHandle, overlapped))
            {
                int errorCode = Marshal.GetLastWin32Error();
                if (errorCode == 0x217)
                {
                    overlapped->InternalLow = IntPtr.Zero;
                    if (base.State == PipeState.Connected)
                    {
                        throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeAlreadyConnected"));
                    }
                    ar.CallUserCallback();
                    return(ar);
                }
                if (errorCode != 0x3e5)
                {
                    System.IO.__Error.WinIOError(errorCode, string.Empty);
                }
            }
            return(ar);
        }
Exemplo n.º 5
0
        private static unsafe void AsyncWaitForConnectionCallback(uint errorCode, uint numBytes, NativeOverlapped *pOverlapped)
        {
            PipeAsyncResult asyncResult = (PipeAsyncResult)Overlapped.Unpack(pOverlapped).AsyncResult;

            if (errorCode == 0x217)
            {
                errorCode = 0;
            }
            asyncResult._errorCode = (int)errorCode;
            asyncResult._completedSynchronously = false;
            asyncResult._isComplete             = true;
            ManualResetEvent event2 = asyncResult._waitHandle;

            if ((event2 != null) && !event2.Set())
            {
                System.IO.__Error.WinIOError();
            }
            AsyncCallback callback = asyncResult._userCallback;

            if (callback != null)
            {
                callback(asyncResult);
            }
        }
        private unsafe void EndWaitForConnection(IAsyncResult asyncResult)
        {
            CheckConnectOperationsServerWithHandle();

            if (asyncResult == null)
            {
                throw new ArgumentNullException("asyncResult");
            }
            if (!IsAsync)
            {
                throw new InvalidOperationException(SR.InvalidOperation_PipeNotAsync);
            }

            PipeAsyncResult afsar = asyncResult as PipeAsyncResult;

            if (afsar == null)
            {
                throw __Error.GetWrongAsyncResult();
            }

            // Ensure we can't get into any races by doing an interlocked
            // CompareExchange here.  Avoids corrupting memory via freeing the
            // NativeOverlapped class or GCHandle twice.  --
            if (1 == Interlocked.CompareExchange(ref afsar._EndXxxCalled, 1, 0))
            {
                throw __Error.GetEndWaitForConnectionCalledTwice();
            }

            IOCancellationHelper cancellationHelper = afsar.AsyncState as IOCancellationHelper;

            if (cancellationHelper != null)
            {
                cancellationHelper.SetOperationCompleted();
            }

            // Obtain the WaitHandle, but don't use public property in case we
            // delay initialize the manual reset event in the future.
            WaitHandle wh = afsar._waitHandle;

            if (wh != null)
            {
                // We must block to ensure that ConnectionIOCallback has completed,
                // and we should close the WaitHandle in here.  AsyncFSCallback
                // and the hand-ported imitation version in COMThreadPool.cpp
                // are the only places that set this event.
                using (wh)
                {
                    wh.WaitOne();
                    Debug.Assert(afsar._isComplete == true, "NamedPipeServerStream::EndWaitForConnection - AsyncFSCallback didn't set _isComplete to true!");
                }
            }

            // We should have freed the overlapped and set it to null either in the Begin
            // method (if ConnectNamedPipe completed synchronously) or in AsyncWaitForConnectionCallback.
            // If it is not nulled out, we should not be past the above wait:
            Debug.Assert(afsar._overlapped == null);

            // Now check for any error during the read.
            if (afsar._errorCode != 0)
            {
                if (afsar._errorCode == Interop.mincore.Errors.ERROR_OPERATION_ABORTED)
                {
                    if (cancellationHelper != null)
                    {
                        cancellationHelper.ThrowIOOperationAborted();
                    }
                }
                throw Win32Marshal.GetExceptionForWin32Error(afsar._errorCode);
            }

            // Success
            State = PipeState.Connected;
        }
        private unsafe IAsyncResult BeginWaitForConnection(AsyncCallback callback, Object state)
        {
            CheckConnectOperationsServerWithHandle();

            if (!IsAsync)
            {
                throw new InvalidOperationException(SR.InvalidOperation_PipeNotAsync);
            }

            // Create and store async stream class library specific data in the
            // async result
            PipeAsyncResult asyncResult = new PipeAsyncResult();

            asyncResult._threadPoolBinding = _threadPoolBinding;
            asyncResult._userCallback      = callback;
            asyncResult._userStateObject   = state;

            IOCancellationHelper cancellationHelper = state as IOCancellationHelper;

            // Create wait handle and store in async result
            ManualResetEvent waitHandle = new ManualResetEvent(false);

            asyncResult._waitHandle = waitHandle;

            NativeOverlapped *intOverlapped = _threadPoolBinding.AllocateNativeOverlapped((errorCode, numBytes, pOverlapped) =>
            {
                // Unpack overlapped, free the pinned overlapped, and complete the operation
                PipeAsyncResult ar = (PipeAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
                Debug.Assert(ar._overlapped == pOverlapped);
                ar._threadPoolBinding.FreeNativeOverlapped(pOverlapped);
                ar._overlapped = null;
                AsyncWaitForConnectionCallback(errorCode, numBytes, ar);
            }, asyncResult, null);

            asyncResult._overlapped = intOverlapped;

            if (!Interop.mincore.ConnectNamedPipe(InternalHandle, intOverlapped))
            {
                int errorCode = Marshal.GetLastWin32Error();

                if (errorCode == Interop.mincore.Errors.ERROR_IO_PENDING)
                {
                    if (cancellationHelper != null)
                    {
                        cancellationHelper.AllowCancellation(InternalHandle, intOverlapped);
                    }
                    return(asyncResult);
                }

                // WaitForConnectionCallback will not be called because we completed synchronously.
                // Either the pipe is already connected, or there was an error. Unpin and free the overlapped again.
                _threadPoolBinding.FreeNativeOverlapped(intOverlapped);
                asyncResult._overlapped = null;

                // Did the client already connect to us?
                if (errorCode == Interop.mincore.Errors.ERROR_PIPE_CONNECTED)
                {
                    if (State == PipeState.Connected)
                    {
                        throw new InvalidOperationException(SR.InvalidOperation_PipeAlreadyConnected);
                    }
                    asyncResult.CallUserCallback();
                    return(asyncResult);
                }

                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }
            // will set state to Connected when EndWait is called
            if (cancellationHelper != null)
            {
                cancellationHelper.AllowCancellation(InternalHandle, intOverlapped);
            }

            return(asyncResult);
        }
Exemplo n.º 8
0
        public unsafe IAsyncResult BeginWaitForConnection(AsyncCallback callback, Object state) {
            CheckConnectOperationsServer();

            if (!IsAsync) {
                throw new InvalidOperationException(SR.GetString(SR.InvalidOperation_PipeNotAsync));
            }

            // Create and store async stream class library specific data in the 
            // async result
            PipeAsyncResult asyncResult = new PipeAsyncResult();
            asyncResult._handle = InternalHandle;
            asyncResult._userCallback = callback;
            asyncResult._userStateObject = state;

            IOCancellationHelper cancellationHelper = state as IOCancellationHelper;

            // Create wait handle and store in async result
            ManualResetEvent waitHandle = new ManualResetEvent(false);
            asyncResult._waitHandle = waitHandle;

            // Create a managed overlapped class
            // We will set the file offsets later
            Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, asyncResult);

            // Pack the Overlapped class, and store it in the async result
            NativeOverlapped* intOverlapped = overlapped.Pack(WaitForConnectionCallback, null);
            asyncResult._overlapped = intOverlapped;

            if (!UnsafeNativeMethods.ConnectNamedPipe(InternalHandle, intOverlapped)) {
                int errorCode = Marshal.GetLastWin32Error();

                if (errorCode == UnsafeNativeMethods.ERROR_IO_PENDING) {
                    if (cancellationHelper != null) {
                        cancellationHelper.AllowCancellation(InternalHandle, intOverlapped);
                    }
                    return asyncResult;
                }

                // WaitForConnectionCallback will not be called becasue we completed synchronously.
                // Either the pipe is already connected, or there was an error. Unpin and free the overlapped again.
                Overlapped.Free(intOverlapped);
                asyncResult._overlapped = null;

                // Did the client already connect to us?
                if (errorCode == UnsafeNativeMethods.ERROR_PIPE_CONNECTED) {

                    if (State == PipeState.Connected) {
                        throw new InvalidOperationException(SR.GetString(SR.InvalidOperation_PipeAlreadyConnected));
                    }
                    asyncResult.CallUserCallback();
                    return asyncResult;
                }
                
                __Error.WinIOError(errorCode, String.Empty);                
            }
            // will set state to Connected when EndWait is called
            if (cancellationHelper != null) {
                cancellationHelper.AllowCancellation(InternalHandle, intOverlapped);
            }

            return asyncResult;
        }
        private unsafe IAsyncResult BeginWaitForConnection(AsyncCallback callback, Object state)
        {
            CheckConnectOperationsServerWithHandle();

            if (!IsAsync)
            {
                throw new InvalidOperationException(SR.InvalidOperation_PipeNotAsync);
            }

            // Create and store async stream class library specific data in the
            // async result
            PipeAsyncResult asyncResult = new PipeAsyncResult();

            asyncResult._handle          = InternalHandle;
            asyncResult._userCallback    = callback;
            asyncResult._userStateObject = state;

            IOCancellationHelper cancellationHelper = state as IOCancellationHelper;

            // Create wait handle and store in async result
            ManualResetEvent waitHandle = new ManualResetEvent(false);

            asyncResult._waitHandle = waitHandle;

            // Create a managed overlapped class
            // We will set the file offsets later
            Overlapped overlapped = new Overlapped();

            overlapped.OffsetLow   = 0;
            overlapped.OffsetHigh  = 0;
            overlapped.AsyncResult = asyncResult;

            // Pack the Overlapped class, and store it in the async result
            NativeOverlapped *intOverlapped = overlapped.Pack(s_WaitForConnectionCallback, null);

            asyncResult._overlapped = intOverlapped;
            if (!Interop.mincore.ConnectNamedPipe(InternalHandle, intOverlapped))
            {
                int errorCode = Marshal.GetLastWin32Error();

                if (errorCode == Interop.ERROR_IO_PENDING)
                {
                    if (cancellationHelper != null)
                    {
                        cancellationHelper.AllowCancellation(InternalHandle, intOverlapped);
                    }
                    return(asyncResult);
                }

                // WaitForConnectionCallback will not be called because we completed synchronously.
                // Either the pipe is already connected, or there was an error. Unpin and free the overlapped again.
                Overlapped.Free(intOverlapped);
                asyncResult._overlapped = null;

                // Did the client already connect to us?
                if (errorCode == Interop.ERROR_PIPE_CONNECTED)
                {
                    if (State == PipeState.Connected)
                    {
                        throw new InvalidOperationException(SR.InvalidOperation_PipeAlreadyConnected);
                    }
                    asyncResult.CallUserCallback();
                    return(asyncResult);
                }

                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }
            // will set state to Connected when EndWait is called
            if (cancellationHelper != null)
            {
                cancellationHelper.AllowCancellation(InternalHandle, intOverlapped);
            }

            return(asyncResult);
        }
 public unsafe IAsyncResult BeginWaitForConnection(AsyncCallback callback, object state)
 {
     this.CheckConnectOperationsServer();
     if (!base.IsAsync)
     {
         throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeNotAsync"));
     }
     PipeAsyncResult ar = new PipeAsyncResult {
         _handle = base.InternalHandle,
         _userCallback = callback,
         _userStateObject = state
     };
     ManualResetEvent event2 = new ManualResetEvent(false);
     ar._waitHandle = event2;
     NativeOverlapped* overlapped = new Overlapped(0, 0, IntPtr.Zero, ar).Pack(WaitForConnectionCallback, null);
     ar._overlapped = overlapped;
     if (!Microsoft.Win32.UnsafeNativeMethods.ConnectNamedPipe(base.InternalHandle, overlapped))
     {
         int errorCode = Marshal.GetLastWin32Error();
         if (errorCode == 0x217)
         {
             overlapped->InternalLow = IntPtr.Zero;
             if (base.State == PipeState.Connected)
             {
                 throw new InvalidOperationException(System.SR.GetString("InvalidOperation_PipeAlreadyConnected"));
             }
             ar.CallUserCallback();
             return ar;
         }
         if (errorCode != 0x3e5)
         {
             System.IO.__Error.WinIOError(errorCode, string.Empty);
         }
     }
     return ar;
 }
Exemplo n.º 11
0
        unsafe private static void AsyncWaitForConnectionCallback(uint errorCode, uint numBytes, PipeAsyncResult asyncResult)
        {
            // Special case for when the client has already connected to us.
            if (errorCode == Interop.mincore.Errors.ERROR_PIPE_CONNECTED)
            {
                errorCode = 0;
            }

            asyncResult._errorCode = (int)errorCode;

            // Call the user-provided callback.  It can and often should
            // call EndWaitForConnection.  There's no reason to use an async 
            // delegate here - we're already on a threadpool thread.  
            // IAsyncResult's completedSynchronously property must return
            // false here, saying the user callback was called on another thread.
            asyncResult._completedSynchronously = false;
            asyncResult._isComplete = true;

            // The OS does not signal this event.  We must do it ourselves.
            ManualResetEvent wh = asyncResult._waitHandle;
            if (wh != null)
            {
                Debug.Assert(!wh.GetSafeWaitHandle().IsClosed, "ManualResetEvent already closed!");
                bool r = wh.Set();
                Debug.Assert(r, "ManualResetEvent::Set failed!");
                if (!r)
                {
                    throw Win32Marshal.GetExceptionForLastWin32Error();
                }
            }

            AsyncCallback userCallback = asyncResult._userCallback;

            if (userCallback != null)
            {
                userCallback(asyncResult);
            }
        }
Exemplo n.º 12
0
        private unsafe IAsyncResult BeginWaitForConnection(AsyncCallback callback, Object state)
        {
            CheckConnectOperationsServerWithHandle();

            if (!IsAsync)
            {
                throw new InvalidOperationException(SR.InvalidOperation_PipeNotAsync);
            }

            // Create and store async stream class library specific data in the 
            // async result
            PipeAsyncResult asyncResult = new PipeAsyncResult();
            asyncResult._threadPoolBinding = _threadPoolBinding;
            asyncResult._userCallback = callback;
            asyncResult._userStateObject = state;

            IOCancellationHelper cancellationHelper = state as IOCancellationHelper;

            // Create wait handle and store in async result
            ManualResetEvent waitHandle = new ManualResetEvent(false);
            asyncResult._waitHandle = waitHandle;

            NativeOverlapped* intOverlapped = _threadPoolBinding.AllocateNativeOverlapped((errorCode, numBytes, pOverlapped) =>
            {
                // Unpack overlapped, free the pinned overlapped, and complete the operation
                PipeAsyncResult ar = (PipeAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
                Debug.Assert(ar._overlapped == pOverlapped);
                ar._threadPoolBinding.FreeNativeOverlapped(pOverlapped);
                ar._overlapped = null;
                AsyncWaitForConnectionCallback(errorCode, numBytes, ar);
            }, asyncResult, null);
            asyncResult._overlapped = intOverlapped;

            if (!Interop.mincore.ConnectNamedPipe(InternalHandle, intOverlapped))
            {
                int errorCode = Marshal.GetLastWin32Error();

                if (errorCode == Interop.mincore.Errors.ERROR_IO_PENDING)
                {
                    if (cancellationHelper != null)
                    {
                        cancellationHelper.AllowCancellation(InternalHandle, intOverlapped);
                    }
                    return asyncResult;
                }

                // WaitForConnectionCallback will not be called because we completed synchronously.
                // Either the pipe is already connected, or there was an error. Unpin and free the overlapped again.
                _threadPoolBinding.FreeNativeOverlapped(intOverlapped);
                asyncResult._overlapped = null;

                // Did the client already connect to us?
                if (errorCode == Interop.mincore.Errors.ERROR_PIPE_CONNECTED)
                {
                    if (State == PipeState.Connected)
                    {
                        throw new InvalidOperationException(SR.InvalidOperation_PipeAlreadyConnected);
                    }
                    asyncResult.CallUserCallback();
                    return asyncResult;
                }

                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }
            // will set state to Connected when EndWait is called
            if (cancellationHelper != null)
            {
                cancellationHelper.AllowCancellation(InternalHandle, intOverlapped);
            }

            return asyncResult;
        }