Inheritance: System.IDisposable
 internal ListenerClientCertAsyncResult(ThreadPoolBoundHandle boundHandle, object asyncObject, object userState, AsyncCallback callback, uint size) : base(asyncObject, userState, callback)
 {
     // we will use this overlapped structure to issue async IO to ul
     // the event handle will be put in by the BeginHttpApi2.ERROR_SUCCESS() method
     _boundHandle = boundHandle;
     Reset(size);
 }
Example #2
0
        private static unsafe void OnNativeIOCompleted(IntPtr instance, IntPtr context, IntPtr overlappedPtr, uint ioResult, UIntPtr numberOfBytesTransferred, IntPtr ioPtr)
        {
            Win32ThreadPoolNativeOverlapped *overlapped = (Win32ThreadPoolNativeOverlapped *)overlappedPtr;

            ThreadPoolBoundHandle boundHandle = overlapped->Data._boundHandle;

            if (boundHandle == null)
            {
                throw new InvalidOperationException(SR.Argument_NativeOverlappedAlreadyFree);
            }

            boundHandle.Release();

            Win32ThreadPoolNativeOverlapped.CompleteWithCallback(ioResult, (uint)numberOfBytesTransferred, overlapped);
        }
Example #3
0
 private Interop.HttpApi.HTTP_REQUEST* Allocate(ThreadPoolBoundHandle boundHandle, uint size)
 {
     uint newSize = size != 0 ? size : RequestBuffer == null ? 4096 : Size;
     if (_nativeOverlapped != null && newSize != RequestBuffer.Length)
     {
         NativeOverlapped* nativeOverlapped = _nativeOverlapped;
         _nativeOverlapped = null;
         _boundHandle.FreeNativeOverlapped(nativeOverlapped);
     }
     if (_nativeOverlapped == null)
     {
         SetBuffer(checked((int)newSize));
         _boundHandle = boundHandle;
         _nativeOverlapped = boundHandle.AllocateNativeOverlapped(ListenerAsyncResult.IOCallback, state: _result, pinData: RequestBuffer);
         return (Interop.HttpApi.HTTP_REQUEST*)Marshal.UnsafeAddrOfPinnedArrayElement(RequestBuffer, 0);
     }
     return RequestBlob;
 }
Example #4
0
        public unsafe void FreeNativeOverlapped(NativeOverlapped *overlapped)
        {
            if (overlapped == null)
            {
                throw new ArgumentNullException("overlapped");
            }
            ThreadPoolBoundHandleOverlapped overlappedWrapper = ThreadPoolBoundHandle.GetOverlappedWrapper(overlapped, this);

            if (overlappedWrapper._boundHandle != this)
            {
                throw new ArgumentException("Wrong bound handle", "overlapped");
            }
            if (overlappedWrapper._preAllocated != null)
            {
                overlappedWrapper._preAllocated.Release();
                return;
            }
            Overlapped.Free(overlapped);
        }
        // Binds the Socket Win32 Handle to the ThreadPool's CompletionPort.
        public ThreadPoolBoundHandle GetOrAllocateThreadPoolBoundHandle()
        {
            if (_released)
            {
                // Keep the exception message pointing at the external type.
                throw new ObjectDisposedException(typeof(Socket).FullName);
            }

            // Check to see if the socket native _handle is already
            // bound to the ThreadPool's completion port.
            if (_iocpBoundHandle == null)
            {
                lock (_iocpBindingLock)
                {
                    if (_iocpBoundHandle == null)
                    {
                        // Bind the socket native _handle to the ThreadPool.
                        if (GlobalLog.IsEnabled)
                        {
                            GlobalLog.Print("SafeCloseSocket#" + LoggingHash.HashString(this) + "::BindToCompletionPort() calling ThreadPool.BindHandle()");
                        }

                        try
                        {
                            // The handle (this) may have been already released:
                            // E.g.: The socket has been disposed in the main thread. A completion callback may
                            //       attempt starting another operation.
                            _iocpBoundHandle = ThreadPoolBoundHandle.BindHandle(this);
                        }
                        catch (Exception exception)
                        {
                            if (ExceptionCheck.IsFatal(exception)) throw;
                            CloseAsIs();
                            throw;
                        }
                    }
                }
            }

            return _iocpBoundHandle;
        }
 // Will be called from the base class upon InvokeCallback()
 protected override void Cleanup()
 {
     if (_pOverlapped != null)
     {
         _memoryBlob = null;
         _boundHandle.FreeNativeOverlapped(_pOverlapped);
         _pOverlapped = null;
         _boundHandle = null;
     }
     GC.SuppressFinalize(this);
     base.Cleanup();
 }
        private static unsafe Win32ThreadPoolNativeOverlapped.OverlappedData GetOverlappedData(Win32ThreadPoolNativeOverlapped* overlapped, ThreadPoolBoundHandle expectedBoundHandle)
        {
            Win32ThreadPoolNativeOverlapped.OverlappedData data = overlapped->Data;

            if (data._boundHandle == null)
                throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, "overlapped");

            if (expectedBoundHandle != null && data._boundHandle != expectedBoundHandle)
                throw new ArgumentException(SR.Argument_NativeOverlappedWrongBoundHandle, "overlapped");

            return data;
        }
        private static unsafe ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped* overlapped, ThreadPoolBoundHandle expectedBoundHandle)
        {
            ThreadPoolBoundHandleOverlapped wrapper;
            try
            {
                wrapper = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped);
            }
            catch (NullReferenceException ex)
            {
                throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, "overlapped", ex);
            }

            return wrapper;
        }
Example #9
0
 internal AsyncRequestContext(ThreadPoolBoundHandle boundHandle, ListenerAsyncResult result)
 {
     _result = result;
     BaseConstruction(Allocate(boundHandle, 0));
 }
Example #10
0
 /// <summary>Initializes the handle to be used asynchronously.</summary>
 /// <param name="handle">The handle.</param>
 private void InitializeAsyncHandle(SafePipeHandle handle)
 {
     // If the handle is of async type, bind the handle to the ThreadPool so that we can use 
     // the async operations (it's needed so that our native callbacks get called).
     _threadPoolBinding = ThreadPoolBoundHandle.BindHandle(handle);
 }
 private unsafe void InitializeOverlapped(ThreadPoolBoundHandle boundHandle)
 {
     _boundHandle = boundHandle;
     _ptrNativeOverlapped = boundHandle.AllocateNativeOverlapped(CompletionPortCallback, null, null);
 }
Example #12
0
        private unsafe static ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped *overlapped, ThreadPoolBoundHandle expectedBoundHandle)
        {
            ThreadPoolBoundHandleOverlapped result;

            try
            {
                result = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped);
            }
            catch (NullReferenceException ex)
            {
                throw new ArgumentException("Already freed", "overlapped", ex);
            }
            return(result);
        }
        private unsafe static ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped *overlapped, ThreadPoolBoundHandle expectedBoundHandle)
        {
            ThreadPoolBoundHandleOverlapped result;

            try
            {
                result = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped);
            }
            catch (NullReferenceException innerException)
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_NativeOverlappedAlreadyFree"), "overlapped", innerException);
            }
            return(result);
        }
Example #14
0
 internal void Reset(ThreadPoolBoundHandle boundHandle, ulong requestId, uint size)
 {
     SetBlob(Allocate(boundHandle, size));
     RequestBlob->RequestId = requestId;
 }
Example #15
0
            internal AsyncReadState(int session, byte[] buffer, SafeFileHandle handle, ThreadPoolBoundHandle binding)
            {
                Debug.Assert(buffer != null);
                Debug.Assert(handle != null);
                Debug.Assert(binding != null);

                Session = session;
                Buffer = buffer;
                DirectoryHandle = handle;
                ThreadPoolBinding = binding;
            }
            // Method called to prepare for a native async http.sys call.
            // This method performs the tasks common to all http.sys operations.
            internal void StartOperationCommon(WebSocketHttpListenerDuplexStream currentStream, ThreadPoolBoundHandle boundHandle)
            {
                // Change status to "in-use".
                if (Interlocked.CompareExchange(ref _operating, InProgress, Free) != Free)
                {
                    // If it was already "in-use" check if Dispose was called.
                    if (_disposeCalled)
                    {
                        // Dispose was called - throw ObjectDisposed.
                        throw new ObjectDisposedException(GetType().FullName);
                    }

                    Debug.Assert(false, "Only one outstanding async operation is allowed per HttpListenerAsyncEventArgs instance.");
                    // Only one at a time.
                    throw new InvalidOperationException();
                }

                // HttpSendResponseEntityBody can return ERROR_INVALID_PARAMETER if the InternalHigh field of the overlapped
                // is not IntPtr.Zero, so we have to reset this field because we are reusing the Overlapped.
                // When using the IAsyncResult based approach of HttpListenerResponseStream the Overlapped is reinitialized
                // for each operation by the CLR when returned from the OverlappedDataCache.

                InitializeOverlapped(boundHandle);

                _exception = null;
                _bytesTransferred = 0;
            }
Example #17
0
        private static unsafe ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped *overlapped, ThreadPoolBoundHandle expectedBoundHandle)
        {
            ThreadPoolBoundHandleOverlapped wrapper;

            try
            {
                wrapper = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped);
            }
            catch (NullReferenceException ex)
            {
                throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, "overlapped", ex);
            }

            return(wrapper);
        }
Example #18
0
        private static unsafe ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped *overlapped, ThreadPoolBoundHandle expectedBoundHandle)
        {
            ThreadPoolBoundHandleOverlapped wrapper;

            try
            {
                wrapper = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped);
            }
            catch (NullReferenceException ex)
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_NativeOverlappedAlreadyFree"), nameof(overlapped), ex);
            }

            return(wrapper);
        }
Example #19
0
 internal HttpRequestStreamAsyncResult(ThreadPoolBoundHandle boundHandle, object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, uint size, uint dataAlreadyRead) : base(asyncObject, userState, callback)
 {
     _dataAlreadyRead = dataAlreadyRead;
     _boundHandle = boundHandle;
     _pOverlapped = boundHandle.AllocateNativeOverlapped(s_IOCallback, state: this, pinData: buffer);
     _pPinnedBuffer = (void*)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset));
 }
Example #20
0
        private static unsafe Win32ThreadPoolNativeOverlapped.OverlappedData GetOverlappedData(Win32ThreadPoolNativeOverlapped *overlapped, ThreadPoolBoundHandle expectedBoundHandle)
        {
            Win32ThreadPoolNativeOverlapped.OverlappedData data = overlapped->Data;

            if (data._boundHandle == null)
            {
                throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, nameof(overlapped));
            }

            if (expectedBoundHandle != null && data._boundHandle != expectedBoundHandle)
            {
                throw new ArgumentException(SR.Argument_NativeOverlappedWrongBoundHandle, nameof(overlapped));
            }

            return(data);
        }
        internal HttpResponseStreamAsyncResult(object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, int size, bool chunked, bool sentHeaders, ThreadPoolBoundHandle boundHandle) : base(asyncObject, userState, callback)
        {
            _boundHandle = boundHandle;
            _sentHeaders = sentHeaders;

            if (size == 0)
            {
                _dataChunks = null;
                _pOverlapped = boundHandle.AllocateNativeOverlapped(s_IOCallback, state: this, pinData: null);
            }
            else
            {
                _dataChunks = new Interop.HttpApi.HTTP_DATA_CHUNK[chunked ? 3 : 1];

                if (NetEventSource.IsEnabled) NetEventSource.Info(this, "m_pOverlapped:0x" + ((IntPtr)_pOverlapped).ToString("x8"));

                object[] objectsToPin = new object[1 + _dataChunks.Length];
                objectsToPin[_dataChunks.Length] = _dataChunks;


                int chunkHeaderOffset = 0;
                byte[] chunkHeaderBuffer = null;
                if (chunked)
                {
                    chunkHeaderBuffer = GetChunkHeader(size, out chunkHeaderOffset);

                    _dataChunks[0] = new Interop.HttpApi.HTTP_DATA_CHUNK();
                    _dataChunks[0].DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                    _dataChunks[0].BufferLength = (uint)(chunkHeaderBuffer.Length - chunkHeaderOffset);

                    objectsToPin[0] = chunkHeaderBuffer;

                    _dataChunks[1] = new Interop.HttpApi.HTTP_DATA_CHUNK();
                    _dataChunks[1].DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                    _dataChunks[1].BufferLength = (uint)size;

                    objectsToPin[1] = buffer;

                    _dataChunks[2] = new Interop.HttpApi.HTTP_DATA_CHUNK();
                    _dataChunks[2].DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                    _dataChunks[2].BufferLength = (uint)s_CRLFArray.Length;

                    objectsToPin[2] = s_CRLFArray;
                }
                else
                {
                    _dataChunks[0] = new Interop.HttpApi.HTTP_DATA_CHUNK();
                    _dataChunks[0].DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                    _dataChunks[0].BufferLength = (uint)size;

                    objectsToPin[0] = buffer;
                }

                // This call will pin needed memory
                _pOverlapped = boundHandle.AllocateNativeOverlapped(s_IOCallback, state: this, pinData: objectsToPin);

                if (chunked)
                {
                    _dataChunks[0].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(chunkHeaderBuffer, chunkHeaderOffset));
                    _dataChunks[1].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset));
                    _dataChunks[2].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(s_CRLFArray, 0));
                }
                else
                {
                    _dataChunks[0].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset));
                }
            }
        }