コード例 #1
0
 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);
 }
コード例 #2
0
        private void InitThreadPoolBinding()
        {
            Debug.Assert(IsAsync);

            // This is necessary for async IO using IO Completion ports via our
            // managed Threadpool API's.  This (theoretically) calls the OS's
            // BindIoCompletionCallback method, and passes in a stub for the
            // LPOVERLAPPED_COMPLETION_ROUTINE.  This stub looks at the Overlapped
            // struct for this request and gets a delegate to a managed callback
            // from there, which it then calls on a threadpool thread.  (We allocate
            // our native OVERLAPPED structs 2 pointers too large and store EE state
            // & GC handles there, one to an IAsyncResult, the other to a delegate.)
            try
            {
                ThreadPoolBinding = ThreadPoolBoundHandle.BindHandle(this);
            }
            catch (ArgumentException ex)
            {
                if (OwnsHandle)
                {
                    // We should close the handle so that the handle is not open until SafeFileHandle GC
                    Dispose();
                }

                throw new IOException(SR.IO_BindHandleFailed, ex);
            }
        }
コード例 #3
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));
 }
コード例 #4
0
            private unsafe void InitializeOverlapped(ThreadPoolBoundHandle boundHandle)
            {
#if DEBUG
                DebugRefCountAllocNativeOverlapped();
#endif
                _boundHandle         = boundHandle;
                _ptrNativeOverlapped = boundHandle.AllocateNativeOverlapped(CompletionPortCallback, null, null);
            }
コード例 #5
0
 // 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();
 }
コード例 #6
0
        private unsafe void FreeNativeOverlapped()
        {
            // Do not call free during AppDomain shutdown, there may be an outstanding operation.
            // Overlapped will take care calling free when the native callback completes.
            IntPtr oldHandle = Interlocked.Exchange(ref handle, IntPtr.Zero);

            if (oldHandle != IntPtr.Zero && !Environment.HasShutdownStarted)
            {
                Debug.Assert(OperatingSystem.IsWindows());
                Debug.Assert(_socketHandle != null, "_socketHandle is null.");

                ThreadPoolBoundHandle?boundHandle = _socketHandle.IOCPBoundHandle;
                Debug.Assert(boundHandle != null, "SafeNativeOverlapped::FreeNativeOverlapped - boundHandle is null");

                // FreeNativeOverlapped will be called even if boundHandle was previously disposed.
                boundHandle?.FreeNativeOverlapped((NativeOverlapped *)oldHandle);
            }
        }
コード例 #7
0
        private Interop.HttpApi.HTTP_REQUEST *Allocate(ThreadPoolBoundHandle boundHandle, uint size)
        {
            uint newSize = size != 0 ? size : RequestBuffer == IntPtr.Zero ? 4096 : Size;

            if (_nativeOverlapped != null)
            {
#if DEBUG
                DebugRefCountReleaseNativeOverlapped();
#endif

                NativeOverlapped *nativeOverlapped = _nativeOverlapped;
                _nativeOverlapped = null;
                _boundHandle !.FreeNativeOverlapped(nativeOverlapped);
            }

#if DEBUG
            DebugRefCountAllocNativeOverlapped();
#endif
            SetBuffer(checked ((int)newSize));
            _boundHandle      = boundHandle;
            _nativeOverlapped = boundHandle.AllocateNativeOverlapped(ListenerAsyncResult.IOCallback, state: _result, pinData: RequestBuffer);

            return((Interop.HttpApi.HTTP_REQUEST *)RequestBuffer.ToPointer());
        }
コード例 #8
0
 internal unsafe SafeNativeOverlapped(ThreadPoolBoundHandle boundHandle, NativeOverlapped *handle)
     : base(IntPtr.Zero, true)
 {
     SetHandle((IntPtr)handle);
     _boundHandle = boundHandle;
 }
コード例 #9
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);
 }
コード例 #10
0
        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.Log.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] = default;
                    _dataChunks[0].DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                    _dataChunks[0].BufferLength  = (uint)(chunkHeaderBuffer.Length - chunkHeaderOffset);

                    objectsToPin[0] = chunkHeaderBuffer;

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

                    objectsToPin[1] = buffer;

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

                    objectsToPin[2] = s_CRLFArray;
                }
                else
                {
                    _dataChunks[0] = default;
                    _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));
                }
            }
        }
コード例 #11
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, nameof(overlapped), ex);
            }

            return(wrapper);
        }