internal OverlappedCache(System.Threading.Overlapped overlapped, object pinnedObjects, IOCompletionCallback callback, bool alreadyTriedCast)
 {
     this.m_Overlapped = overlapped;
     this.m_PinnedObjects = pinnedObjects;
     this.m_PinnedObjectsArray = alreadyTriedCast ? null : NclConstants.EmptyObjectArray;
     this.m_NativeOverlapped = new SafeNativeOverlapped(overlapped.UnsafePack(callback, pinnedObjects));
 }
        // SetUnmanagedStructures
        //
        // This needs to be called for overlapped IO to function properly.
        //
        // Fills in overlapped Structures used in an async overlapped Winsock call.
        // These calls are outside the runtime and are unmanaged code, so we need
        // to prepare specific structures and ints that lie in unmanaged memory
        // since the overlapped calls may complete asynchronously.
        internal void SetUnmanagedStructures(object objectsToPin)
        {
            Socket s = (Socket)AsyncObject;

            // Bind the Win32 Socket Handle to the ThreadPool
            Debug.Assert(s != null, "m_CurrentSocket is null");
            Debug.Assert(s.SafeHandle != null, "m_CurrentSocket.SafeHandle is null");

            if (s.SafeHandle.IsInvalid)
            {
                throw new ObjectDisposedException(s.GetType().FullName);
            }

            ThreadPoolBoundHandle boundHandle = s.SafeHandle.GetOrAllocateThreadPoolBoundHandle();

            unsafe
            {
                NativeOverlapped* overlapped = boundHandle.AllocateNativeOverlapped(s_ioCallback, this, objectsToPin);
                _nativeOverlapped = new SafeNativeOverlapped(s.SafeHandle, overlapped);
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print(
                        "BaseOverlappedAsyncResult#" + LoggingHash.HashString(this) +
                        "::boundHandle#" + LoggingHash.HashString(boundHandle) +
                        "::AllocateNativeOverlapped. Return=" +
                        _nativeOverlapped.DangerousGetHandle().ToString("x"));
                }
            }
        }
Beispiel #3
0
        private void Reset(uint size)
        {
            if (size == _size)
            {
                return;
            }
            if (_size != 0)
            {
                _overlapped.Dispose();
            }
            _size = size;
            if (size == 0)
            {
                _overlapped    = null;
                _memoryBlob    = null;
                _backingBuffer = null;
                return;
            }
            _backingBuffer = new byte[checked ((int)size)];
            var boundHandle = RequestContext.Server.RequestQueue.BoundHandle;

            _overlapped = new SafeNativeOverlapped(boundHandle,
                                                   boundHandle.AllocateNativeOverlapped(IOCallback, this, _backingBuffer));
            _memoryBlob = (HttpApiTypes.HTTP_SSL_CLIENT_CERT_INFO *)Marshal.UnsafeAddrOfPinnedArrayElement(_backingBuffer, 0);
        }
 internal OverlappedCache(System.Threading.Overlapped overlapped, object[] pinnedObjectsArray, IOCompletionCallback callback)
 {
     this.m_Overlapped = overlapped;
     this.m_PinnedObjects = pinnedObjectsArray;
     this.m_PinnedObjectsArray = pinnedObjectsArray;
     this.m_NativeOverlapped = new SafeNativeOverlapped(overlapped.UnsafePack(callback, pinnedObjectsArray));
 }
Beispiel #5
0
        internal void AllocateNativeRequest(uint?size = null, ulong requestId = 0)
        {
            _nativeRequestContext?.ReleasePins();
            _nativeRequestContext?.Dispose();
            //Debug.Assert(size != 0, "unexpected size");

            // We can't reuse overlapped objects
            uint newSize       = size.HasValue ? size.Value : DefaultBufferSize;
            var  backingBuffer = new byte[newSize + AlignmentPadding];

            var boundHandle      = Server.RequestQueue.BoundHandle;
            var nativeOverlapped = new SafeNativeOverlapped(boundHandle,
                                                            boundHandle.AllocateNativeOverlapped(IOCallback, this, backingBuffer));

            var requestAddress = Marshal.UnsafeAddrOfPinnedArrayElement(backingBuffer, 0);

            // TODO:
            // Apparently the HttpReceiveHttpRequest memory alignment requirements for non - ARM processors
            // are different than for ARM processors. We have seen 4 - byte - aligned buffers allocated on
            // virtual x64/x86 machines which were accepted by HttpReceiveHttpRequest without errors. In
            // these cases the buffer alignment may cause reading values at invalid offset. Setting buffer
            // alignment to 0 for now.
            //
            // _bufferAlignment = (int)(requestAddress.ToInt64() & 0x07);

            var bufferAlignment = 0;

            var nativeRequest = (HttpApiTypes.HTTP_REQUEST *)(requestAddress + bufferAlignment);

            // nativeRequest
            _nativeRequestContext = new NativeRequestContext(nativeOverlapped, bufferAlignment, nativeRequest, backingBuffer, requestId);
        }
        internal ResponseStreamAsyncResult(ResponseBody responseStream, FileStream fileStream, long offset,
                                           long count, bool chunked, CancellationToken cancellationToken)
            : this(responseStream, cancellationToken)
        {
            var boundHandle = responseStream.RequestContext.Server.RequestQueue.BoundHandle;

            _fileStream = fileStream;

            if (count == 0)
            {
                _dataChunks = null;
                _overlapped = new SafeNativeOverlapped(boundHandle,
                                                       boundHandle.AllocateNativeOverlapped(IOCallback, this, null));
            }
            else
            {
                _dataChunks = new HttpApiTypes.HTTP_DATA_CHUNK[chunked ? 3 : 1];

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

                var chunkHeaderBuffer = new ArraySegment <byte>();
                if (chunked)
                {
                    chunkHeaderBuffer                      = Helpers.GetChunkHeader(count);
                    _dataChunks[0].DataChunkType           = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                    _dataChunks[0].fromMemory.BufferLength = (uint)chunkHeaderBuffer.Count;
                    objectsToPin[0] = chunkHeaderBuffer.Array;

                    _dataChunks[1].DataChunkType       = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromFileHandle;
                    _dataChunks[1].fromFile.offset     = (ulong)offset;
                    _dataChunks[1].fromFile.count      = (ulong)count;
                    _dataChunks[1].fromFile.fileHandle = _fileStream.SafeFileHandle.DangerousGetHandle();
                    // Nothing to pin for the file handle.

                    _dataChunks[2].DataChunkType           = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                    _dataChunks[2].fromMemory.BufferLength = (uint)Helpers.CRLF.Length;
                    objectsToPin[1] = Helpers.CRLF;
                }
                else
                {
                    _dataChunks[0].DataChunkType       = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromFileHandle;
                    _dataChunks[0].fromFile.offset     = (ulong)offset;
                    _dataChunks[0].fromFile.count      = (ulong)count;
                    _dataChunks[0].fromFile.fileHandle = _fileStream.SafeFileHandle.DangerousGetHandle();
                }

                // This call will pin needed memory
                _overlapped = new SafeNativeOverlapped(boundHandle,
                                                       boundHandle.AllocateNativeOverlapped(IOCallback, this, objectsToPin));

                if (chunked)
                {
                    // These must be set after pinning with Overlapped.
                    _dataChunks[0].fromMemory.pBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(chunkHeaderBuffer.Array, chunkHeaderBuffer.Offset);
                    _dataChunks[2].fromMemory.pBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(Helpers.CRLF, 0);
                }
            }
        }
Beispiel #7
0
 internal static unsafe extern SocketError WSARecv(
     IntPtr socketHandle,
     WSABuffer *buffer,
     int bufferCount,
     out int bytesTransferred,
     ref SocketFlags socketFlags,
     SafeNativeOverlapped overlapped,
     IntPtr completionRoutine);
Beispiel #8
0
 internal static extern unsafe SocketError WSASend(
     IntPtr socketHandle,
     WSABuffer *buffers,
     int bufferCount,
     out int bytesTransferred,
     SocketFlags socketFlags,
     SafeNativeOverlapped overlapped,
     IntPtr completionRoutine);
        internal ResponseStreamAsyncResult(ResponseBody responseStream, ArraySegment <byte> data, bool chunked,
                                           CancellationToken cancellationToken)
            : this(responseStream, cancellationToken)
        {
            var boundHandle = _responseStream.RequestContext.Server.RequestQueue.BoundHandle;

            object[] objectsToPin;

            if (data.Count == 0)
            {
                _dataChunks = null;
                _overlapped = new SafeNativeOverlapped(boundHandle,
                                                       boundHandle.AllocateNativeOverlapped(IOCallback, this, null));
                return;
            }

            _dataChunks     = new HttpApiTypes.HTTP_DATA_CHUNK[1 + (chunked ? 2 : 0)];
            objectsToPin    = new object[_dataChunks.Length + 1];
            objectsToPin[0] = _dataChunks;
            var currentChunk = 0;
            var currentPin   = 1;

            var chunkHeaderBuffer = new ArraySegment <byte>();

            if (chunked)
            {
                chunkHeaderBuffer = Helpers.GetChunkHeader(data.Count);
                SetDataChunk(_dataChunks, ref currentChunk, objectsToPin, ref currentPin, chunkHeaderBuffer);
            }

            SetDataChunk(_dataChunks, ref currentChunk, objectsToPin, ref currentPin, data);

            if (chunked)
            {
                SetDataChunk(_dataChunks, ref currentChunk, objectsToPin, ref currentPin, new ArraySegment <byte>(Helpers.CRLF));
            }

            // This call will pin needed memory
            _overlapped = new SafeNativeOverlapped(boundHandle,
                                                   boundHandle.AllocateNativeOverlapped(IOCallback, this, objectsToPin));

            currentChunk = 0;
            if (chunked)
            {
                _dataChunks[currentChunk].fromMemory.pBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(chunkHeaderBuffer.Array, chunkHeaderBuffer.Offset);
                currentChunk++;
            }

            _dataChunks[currentChunk].fromMemory.pBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(data.Array, data.Offset);
            currentChunk++;

            if (chunked)
            {
                _dataChunks[currentChunk].fromMemory.pBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(Helpers.CRLF, 0);
                currentChunk++;
            }
        }
Beispiel #10
0
 internal static extern SocketError WSARecvFrom(
     [In] SafeCloseSocket socketHandle,
     [In, Out] WSABuffer[] buffers,
     [In] int bufferCount,
     [Out] out int bytesTransferred,
     [In, Out] ref SocketFlags socketFlags,
     [In] IntPtr socketAddressPointer,
     [In] IntPtr socketAddressSizePointer,
     [In] SafeNativeOverlapped overlapped,
     [In] IntPtr completionRoutine);
Beispiel #11
0
 internal static extern SocketError WSASendTo(
     [In] SafeCloseSocket socketHandle,
     [In] WSABuffer[] buffersArray,
     [In] int bufferCount,
     [Out] out int bytesTransferred,
     [In] SocketFlags socketFlags,
     [In] IntPtr socketAddress,
     [In] int socketAddressSize,
     [In] SafeNativeOverlapped overlapped,
     [In] IntPtr completionRoutine);
Beispiel #12
0
 internal static unsafe extern SocketError WSARecvFrom(
     SafeCloseSocket socketHandle,
     WSABuffer *buffers,
     int bufferCount,
     out int bytesTransferred,
     ref SocketFlags socketFlags,
     IntPtr socketAddressPointer,
     IntPtr socketAddressSizePointer,
     SafeNativeOverlapped overlapped,
     IntPtr completionRoutine);
        internal RequestStreamAsyncResult(RequestStream requestStream, object userState, AsyncCallback callback, byte[] buffer, int offset, uint dataAlreadyRead, CancellationTokenRegistration cancellationRegistration)
            : this(requestStream, userState, callback)
        {
            _dataAlreadyRead = dataAlreadyRead;
            var boundHandle = requestStream.RequestContext.Server.RequestQueue.BoundHandle;

            _overlapped = new SafeNativeOverlapped(boundHandle,
                                                   boundHandle.AllocateNativeOverlapped(IOCallback, this, buffer));
            _pinnedBuffer             = (Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset));
            _cancellationRegistration = cancellationRegistration;
        }
        internal void AllocateNativeRequest(uint?size = null, ulong requestId = 0)
        {
            _nativeRequestContext?.ReleasePins();
            _nativeRequestContext?.Dispose();

            // We can't reuse overlapped objects
            var boundHandle      = Server.RequestQueue.BoundHandle;
            var nativeOverlapped = new SafeNativeOverlapped(boundHandle,
                                                            boundHandle.AllocateNativeOverlapped(IOCallback, this, pinData: null));

            // nativeRequest
            _nativeRequestContext = new NativeRequestContext(nativeOverlapped, Server.MemoryPool, size, requestId);
        }
 private void InternalFree()
 {
     this.m_Overlapped = null;
     this.m_PinnedObjects = null;
     if (this.m_NativeOverlapped != null)
     {
         if (!this.m_NativeOverlapped.IsInvalid)
         {
             this.m_NativeOverlapped.Dispose();
         }
         this.m_NativeOverlapped = null;
     }
 }
Beispiel #16
0
 internal static unsafe SocketError WSASend(
     IntPtr socketHandle,
     WSABuffer[] buffers,
     int bufferCount,
     out int bytesTransferred,
     SocketFlags socketFlags,
     SafeNativeOverlapped overlapped,
     IntPtr completionRoutine)
 {
     Debug.Assert(buffers != null);
     fixed(WSABuffer *buffersPtr = &buffers[0])
     {
         return(WSASend(socketHandle, buffersPtr, bufferCount, out bytesTransferred, socketFlags, overlapped, completionRoutine));
     }
 }
Beispiel #17
0
        internal static unsafe SocketError WSASend(
            SafeCloseSocket socketHandle,
            ref WSABuffer buffer,
            int bufferCount,
            out int bytesTransferred,
            SocketFlags socketFlags,
            SafeNativeOverlapped overlapped,
            IntPtr completionRoutine)
        {
            // We intentionally do NOT copy this back after the function completes:
            // We don't want to cause a race in async scenarios.
            // The WSABuffer struct should be unchanged anyway.
            WSABuffer localBuffer = buffer;

            return(WSASend(socketHandle, &localBuffer, bufferCount, out bytesTransferred, socketFlags, overlapped, completionRoutine));
        }
Beispiel #18
0
 internal static unsafe SocketError WSARecvFrom(
     SafeCloseSocket socketHandle,
     WSABuffer[] buffers,
     int bufferCount,
     out int bytesTransferred,
     ref SocketFlags socketFlags,
     IntPtr socketAddressPointer,
     IntPtr socketAddressSizePointer,
     SafeNativeOverlapped overlapped,
     IntPtr completionRoutine)
 {
     Debug.Assert(buffers != null);
     fixed(WSABuffer *buffersPtr = &buffers[0])
     {
         return(WSARecvFrom(socketHandle, buffersPtr, bufferCount, out bytesTransferred, ref socketFlags, socketAddressPointer, socketAddressSizePointer, overlapped, completionRoutine));
     }
 }
        // SetUnmanagedStructures
        //
        // This needs to be called for overlapped IO to function properly.
        //
        // Fills in overlapped Structures used in an async overlapped Winsock call.
        // These calls are outside the runtime and are unmanaged code, so we need
        // to prepare specific structures and ints that lie in unmanaged memory
        // since the overlapped calls may complete asynchronously.
        internal void SetUnmanagedStructures(object objectsToPin)
        {
            Socket s = (Socket)AsyncObject;

            // Bind the Win32 Socket Handle to the ThreadPool
            Debug.Assert(s != null, "m_CurrentSocket is null");
            Debug.Assert(s.SafeHandle != null, "m_CurrentSocket.SafeHandle is null");

            if (s.SafeHandle.IsInvalid)
            {
                throw new ObjectDisposedException(s.GetType().FullName);
            }

            ThreadPoolBoundHandle boundHandle = s.SafeHandle.GetOrAllocateThreadPoolBoundHandle();

            unsafe
            {
                NativeOverlapped* overlapped = boundHandle.AllocateNativeOverlapped(s_ioCallback, this, objectsToPin);
                _nativeOverlapped = new SafeNativeOverlapped(s.SafeHandle, overlapped);
                if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"{boundHandle}::AllocateNativeOverlapped. return={_nativeOverlapped}");
            }
        }
 // Utility cleanup routine. Frees the overlapped structure.
 // This should be overridden to free pinned and unmanaged memory in the subclass.
 // It needs to also be invoked from the subclass.
 protected virtual void ForceReleaseUnmanagedStructures()
 {
     // Free the unmanaged memory if allocated.
     if (NetEventSource.IsEnabled) NetEventSource.Enter(this);
     _nativeOverlapped.Dispose();
     _nativeOverlapped = null;
     GC.SuppressFinalize(this);
 }
        private unsafe void PrepareIOCPOperation()
        {
            Debug.Assert(_currentSocket != null, "_currentSocket is null");
            Debug.Assert(_currentSocket.SafeHandle != null, "_currentSocket.SafeHandle is null");
            Debug.Assert(!_currentSocket.SafeHandle.IsInvalid, "_currentSocket.SafeHandle is invalid");

            ThreadPoolBoundHandle boundHandle = _currentSocket.SafeHandle.GetOrAllocateThreadPoolBoundHandle();

            NativeOverlapped* overlapped = null;
            if (_preAllocatedOverlapped != null)
            {
                overlapped = boundHandle.AllocateNativeOverlapped(_preAllocatedOverlapped);
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print(
                        "SocketAsyncEventArgs#" + LoggingHash.HashString(this) +
                        "::boundHandle#" + LoggingHash.HashString(boundHandle) +
                        "::AllocateNativeOverlapped(m_PreAllocatedOverlapped=" +
                        LoggingHash.HashString(_preAllocatedOverlapped) +
                        "). Returned = " + ((IntPtr)overlapped).ToString("x"));
                }
            }
            else
            {
                overlapped = boundHandle.AllocateNativeOverlapped(CompletionPortCallback, this, null);
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print(
                        "SocketAsyncEventArgs#" + LoggingHash.HashString(this) +
                        "::boundHandle#" + LoggingHash.HashString(boundHandle) +
                        "::AllocateNativeOverlapped(pinData=null)" +
                        "). Returned = " + ((IntPtr)overlapped).ToString("x"));
                }
            }
            Debug.Assert(overlapped != null, "NativeOverlapped is null.");

            // If we already have a SafeNativeOverlapped SafeHandle and it's associated with the same
            // socket (due to the last operation that used this SocketAsyncEventArgs using the same socket),
            // then we can reuse the same SafeHandle object.  Otherwise, this is either the first operation
            // or the last operation was with a different socket, so create a new SafeHandle.
            if (_ptrNativeOverlapped?.SocketHandle == _currentSocket.SafeHandle)
            {
                _ptrNativeOverlapped.ReplaceHandle(overlapped);
            }
            else
            {
                _ptrNativeOverlapped?.Dispose();
                _ptrNativeOverlapped = new SafeNativeOverlapped(_currentSocket.SafeHandle, overlapped);
            }
        }
Beispiel #22
0
 internal static extern uint HttpSendResponseEntityBody(SafeHandle requestQueueHandle, ulong requestId, uint flags, ushort entityChunkCount, HTTP_DATA_CHUNK *pEntityChunks, uint *pBytesSent, IntPtr pReserved1, uint Reserved2, SafeNativeOverlapped pOverlapped, IntPtr pLogData);
Beispiel #23
0
 internal static extern uint HttpReceiveHttpRequest(SafeHandle requestQueueHandle, ulong requestId, uint flags, HTTP_REQUEST *pRequestBuffer, uint requestBufferLength, uint *pBytesReturned, SafeNativeOverlapped pOverlapped);
Beispiel #24
0
 internal static extern uint HttpReceiveRequestEntityBody(SafeHandle requestQueueHandle, ulong requestId, uint flags, IntPtr pEntityBuffer, uint entityBufferLength, out uint bytesReturned, SafeNativeOverlapped pOverlapped);
        internal OverlappedCache(Overlapped overlapped, object[] pinnedObjectsArray, IOCompletionCallback callback)
        {
            m_Overlapped = overlapped;
            m_PinnedObjects = pinnedObjectsArray;
            m_PinnedObjectsArray = pinnedObjectsArray;

            unsafe
            {
                m_NativeOverlapped = new SafeNativeOverlapped(overlapped.UnsafePack(callback, pinnedObjectsArray));
            }
        }
        // Cleans up any existing Overlapped object and related state variables.
        private void FreeOverlapped(bool checkForShutdown)
        {
            if (!checkForShutdown || !Environment.HasShutdownStarted)
            {
                // Free the overlapped object.
                if (_ptrNativeOverlapped != null && !_ptrNativeOverlapped.IsInvalid)
                {
                    _ptrNativeOverlapped.Dispose();
                    _ptrNativeOverlapped = null;
                }

                // Free the preallocated overlapped object. This in turn will unpin
                // any pinned buffers.
                if (_preAllocatedOverlapped != null)
                {
                    _preAllocatedOverlapped.Dispose();
                    _preAllocatedOverlapped = null;

                    _pinState = PinState.None;
                    _pinnedAcceptBuffer = null;
                    _pinnedSingleBuffer = null;
                    _pinnedSingleBufferOffset = 0;
                    _pinnedSingleBufferCount = 0;
                }

                // Free any allocated GCHandles.
                if (_socketAddressGCHandle.IsAllocated)
                {
                    _socketAddressGCHandle.Free();
                    _pinnedSocketAddress = null;
                }

                if (_wsaMessageBufferGCHandle.IsAllocated)
                {
                    _wsaMessageBufferGCHandle.Free();
                    _ptrWSAMessageBuffer = IntPtr.Zero;
                }

                if (_wsaRecvMsgWSABufferArrayGCHandle.IsAllocated)
                {
                    _wsaRecvMsgWSABufferArrayGCHandle.Free();
                    _ptrWSARecvMsgWSABufferArray = IntPtr.Zero;
                }

                if (_controlBufferGCHandle.IsAllocated)
                {
                    _controlBufferGCHandle.Free();
                    _ptrControlBuffer = IntPtr.Zero;
                }
            }
        }
        private unsafe void PrepareIOCPOperation()
        {
            Debug.Assert(_currentSocket != null, "_currentSocket is null");
            Debug.Assert(_currentSocket.SafeHandle != null, "_currentSocket.SafeHandle is null");
            Debug.Assert(!_currentSocket.SafeHandle.IsInvalid, "_currentSocket.SafeHandle is invalid");

            ThreadPoolBoundHandle boundHandle = _currentSocket.SafeHandle.GetOrAllocateThreadPoolBoundHandle();

            NativeOverlapped* overlapped = null;
            if (_preAllocatedOverlapped != null)
            {
                overlapped = boundHandle.AllocateNativeOverlapped(_preAllocatedOverlapped);
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print(
                        "SocketAsyncEventArgs#" + LoggingHash.HashString(this) +
                        "::boundHandle#" + LoggingHash.HashString(boundHandle) +
                        "::AllocateNativeOverlapped(m_PreAllocatedOverlapped=" +
                        LoggingHash.HashString(_preAllocatedOverlapped) +
                        "). Returned = " + ((IntPtr)overlapped).ToString("x"));
                }
            }
            else
            {
                overlapped = boundHandle.AllocateNativeOverlapped(CompletionPortCallback, this, null);
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print(
                        "SocketAsyncEventArgs#" + LoggingHash.HashString(this) +
                        "::boundHandle#" + LoggingHash.HashString(boundHandle) +
                        "::AllocateNativeOverlapped(pinData=null)" +
                        "). Returned = " + ((IntPtr)overlapped).ToString("x"));
                }
            }

            Debug.Assert(overlapped != null, "NativeOverlapped is null.");
            _ptrNativeOverlapped = new SafeNativeOverlapped(_currentSocket.SafeHandle, overlapped);
        }
Beispiel #28
0
        // Method to setup an Overlapped object with with multiple buffers pinned.        
        unsafe private void SetupOverlappedMultiple() {
            
            ArraySegment<byte>[] tempList = new ArraySegment<byte>[m_BufferList.Count];
            m_BufferList.CopyTo(tempList, 0);

            // Alloc new Overlapped.
            m_Overlapped = new Overlapped();

            // Number of things to pin is number of buffers.
            // Ensure we have properly sized object array.
            if(m_ObjectsToPin == null || (m_ObjectsToPin.Length != tempList.Length)) {
                m_ObjectsToPin = new object[tempList.Length];
            }

            // Fill in object array.
            for(int i = 0; i < (tempList.Length); i++) {
                m_ObjectsToPin[i] = tempList[i].Array;
            }

            if(m_WSABufferArray == null || m_WSABufferArray.Length != tempList.Length) {
                m_WSABufferArray = new WSABuffer[tempList.Length];
            }

            // Pin buffers and fill in WSABuffer descriptor pointers and lengths
#if SOCKETTHREADPOOL
            m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback);
            m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, m_ObjectsToPin));
#else
            m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, m_ObjectsToPin));
#endif
            for(int i = 0; i < tempList.Length; i++) {
                ArraySegment<byte> localCopy = tempList[i];
                ValidationHelper.ValidateSegment(localCopy);
                m_WSABufferArray[i].Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(localCopy.Array, localCopy.Offset);
                m_WSABufferArray[i].Length = localCopy.Count;
            }
            m_PinState = PinState.MultipleBuffer;
        }
Beispiel #29
0
        // Method to clean up any existing Overlapped object and related state variables.
        private void FreeOverlapped(bool checkForShutdown) {
            if (!checkForShutdown || !NclUtilities.HasShutdownStarted) {

                // Free the overlapped object

                if(m_PtrNativeOverlapped != null && !m_PtrNativeOverlapped.IsInvalid) {
                    m_PtrNativeOverlapped.Dispose();
                    m_PtrNativeOverlapped = null;
                    m_Overlapped = null;
                    m_PinState = PinState.None;
                    m_PinnedAcceptBuffer = null;
                    m_PinnedSingleBuffer = null;
                    m_PinnedSingleBufferOffset = 0;
                    m_PinnedSingleBufferCount = 0;
                }

                // Free any alloc'd GCHandles
                
                if(m_SocketAddressGCHandle.IsAllocated) {
                    m_SocketAddressGCHandle.Free();
                }
                if(m_WSAMessageBufferGCHandle.IsAllocated) {
                    m_WSAMessageBufferGCHandle.Free();
                }
                if(m_WSARecvMsgWSABufferArrayGCHandle.IsAllocated) {
                    m_WSARecvMsgWSABufferArrayGCHandle.Free();
                }
                if(m_ControlBufferGCHandle.IsAllocated) {
                    m_ControlBufferGCHandle.Free();
                }
            }
        }
        private unsafe void PrepareIOCPOperation()
        {
            Debug.Assert(_currentSocket != null, "_currentSocket is null");
            Debug.Assert(_currentSocket.SafeHandle != null, "_currentSocket.SafeHandle is null");
            Debug.Assert(!_currentSocket.SafeHandle.IsInvalid, "_currentSocket.SafeHandle is invalid");

            ThreadPoolBoundHandle boundHandle = _currentSocket.SafeHandle.GetOrAllocateThreadPoolBoundHandle();

            NativeOverlapped* overlapped = null;
            if (_preAllocatedOverlapped != null)
            {
                overlapped = boundHandle.AllocateNativeOverlapped(_preAllocatedOverlapped);
                if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"boundHandle:{boundHandle}, PreAllocatedOverlapped:{_preAllocatedOverlapped}, Returned:{(IntPtr)overlapped}");
            }
            else
            {
                overlapped = boundHandle.AllocateNativeOverlapped(CompletionPortCallback, this, null);
               if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"boundHandle:{boundHandle}, AllocateNativeOverlapped(pinData=null), Returned:{(IntPtr)overlapped}");
            }
            Debug.Assert(overlapped != null, "NativeOverlapped is null.");

            // If we already have a SafeNativeOverlapped SafeHandle and it's associated with the same
            // socket (due to the last operation that used this SocketAsyncEventArgs using the same socket),
            // then we can reuse the same SafeHandle object.  Otherwise, this is either the first operation
            // or the last operation was with a different socket, so create a new SafeHandle.
            if (_ptrNativeOverlapped?.SocketHandle == _currentSocket.SafeHandle)
            {
                _ptrNativeOverlapped.ReplaceHandle(overlapped);
            }
            else
            {
                _ptrNativeOverlapped?.Dispose();
                _ptrNativeOverlapped = new SafeNativeOverlapped(_currentSocket.SafeHandle, overlapped);
            }
        }
 internal static extern unsafe uint CancelIoEx(SafeHandle handle, SafeNativeOverlapped overlapped);
 internal static unsafe partial uint CancelIoEx(SafeHandle handle, SafeNativeOverlapped overlapped);
Beispiel #33
0
        // Method to setup an Overlapped object with either m_Buffer or m_AcceptBuffer pinned.        
        unsafe private void SetupOverlappedSingle(bool pinSingleBuffer) {
            
            // Alloc new Overlapped.
            m_Overlapped = new Overlapped();

            // Pin buffer, get native pointers, and fill in WSABuffer descriptor.
            if(pinSingleBuffer) {
                if(m_Buffer != null) {
#if SOCKETTHREADPOOL
                    m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback);
                    m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, m_Buffer));
#else
                    m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, m_Buffer));
#endif
                    m_PinnedSingleBuffer = m_Buffer;
                    m_PinnedSingleBufferOffset = m_Offset;
                    m_PinnedSingleBufferCount = m_Count;
                    m_PtrSingleBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(m_Buffer, m_Offset);
                    m_PtrAcceptBuffer = IntPtr.Zero;
                    m_WSABuffer.Pointer = m_PtrSingleBuffer;
                    m_WSABuffer.Length = m_Count;
                    m_PinState = PinState.SingleBuffer;
                } else {
#if SOCKETTHREADPOOL
                    m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback);
                    m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, null));
#else
                    m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, null));
#endif
                    m_PinnedSingleBuffer = null;
                    m_PinnedSingleBufferOffset = 0;
                    m_PinnedSingleBufferCount = 0;
                    m_PtrSingleBuffer = IntPtr.Zero;
                    m_PtrAcceptBuffer = IntPtr.Zero;
                    m_WSABuffer.Pointer = m_PtrSingleBuffer;
                    m_WSABuffer.Length = m_Count;
                    m_PinState = PinState.NoBuffer;
                }
            } else {
#if SOCKETTHREADPOOL
                m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback);
                m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, m_AcceptBuffer));
#else
                m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, m_AcceptBuffer));
#endif
                m_PinnedAcceptBuffer = m_AcceptBuffer;
                m_PtrAcceptBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(m_AcceptBuffer, 0);
                m_PtrSingleBuffer = IntPtr.Zero;
                m_PinState = PinState.SingleAcceptBuffer;
            }
        }
        private void InternalFree()
        {
            m_Overlapped = null;
            m_PinnedObjects = null;

            if (m_NativeOverlapped != null)
            {
                if (!m_NativeOverlapped.IsInvalid)
                {
                    m_NativeOverlapped.Dispose();
                }
                m_NativeOverlapped = null;
            }
        }
Beispiel #35
0
        // Method to setup an Overlapped object for SendPacketsAsync.        
        unsafe private void SetupOverlappedSendPackets() {

            int index;

            // Alloc new Overlapped.
            m_Overlapped = new Overlapped();

            // Alloc native descriptor.
            m_SendPacketsDescriptor = 
                new UnsafeNclNativeMethods.OSSOCK.TransmitPacketsElement[m_SendPacketsElementsFileCount + m_SendPacketsElementsBufferCount];

            // Number of things to pin is number of buffers + 1 (native descriptor).
            // Ensure we have properly sized object array.
            if(m_ObjectsToPin == null || (m_ObjectsToPin.Length != m_SendPacketsElementsBufferCount + 1)) {
                m_ObjectsToPin = new object[m_SendPacketsElementsBufferCount + 1];
            }

            // Fill in objects to pin array. Native descriptor buffer first and then user specified buffers.
            m_ObjectsToPin[0] = m_SendPacketsDescriptor;
            index = 1;
            foreach(SendPacketsElement spe in m_SendPacketsElementsInternal) {                
                if(spe != null && spe.m_Buffer != null && spe.m_Count > 0) {
                    m_ObjectsToPin[index] = spe.m_Buffer;
                    index++;
                }
            }

            // Pin buffers
#if SOCKETTHREADPOOL
            m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback);
            m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, m_ObjectsToPin));
#else
            m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, m_ObjectsToPin));
#endif

            // Get pointer to native descriptor.
            m_PtrSendPacketsDescriptor = Marshal.UnsafeAddrOfPinnedArrayElement(m_SendPacketsDescriptor, 0);
            
            // Fill in native descriptor.
            int descriptorIndex = 0;
            int fileIndex = 0;
            foreach(SendPacketsElement spe in m_SendPacketsElementsInternal) {
                if (spe != null) {
                    if(spe.m_Buffer != null && spe.m_Count > 0) {
                        // a buffer
                        m_SendPacketsDescriptor[descriptorIndex].buffer = Marshal.UnsafeAddrOfPinnedArrayElement(spe.m_Buffer, spe.m_Offset);
                        m_SendPacketsDescriptor[descriptorIndex].length = (uint)spe.m_Count;
                        m_SendPacketsDescriptor[descriptorIndex].flags = spe.m_Flags;
                        descriptorIndex++;
                    } else if (spe.m_FilePath != null) {
                        // a file
                        m_SendPacketsDescriptor[descriptorIndex].fileHandle = m_SendPacketsFileHandles[fileIndex].DangerousGetHandle();
                        m_SendPacketsDescriptor[descriptorIndex].fileOffset = spe.m_Offset;
                        m_SendPacketsDescriptor[descriptorIndex].length = (uint)spe.m_Count;
                        m_SendPacketsDescriptor[descriptorIndex].flags = spe.m_Flags;
                        fileIndex++;
                        descriptorIndex++;
                    }
                }
            }

            m_PinState = PinState.SendPackets;
        }
        //
        // This method is called after an asynchronous call is made for the user,
        // it checks and acts accordingly if the IO:
        // 1) completed synchronously.
        // 2) was pended.
        // 3) failed.
        //
        internal unsafe SocketError CheckAsyncCallOverlappedResult(SocketError errorCode)
        {
#if DEBUG
            m_SavedErrorCode = errorCode;
#endif

            //
            // Check if the Async IO call:
            // 1) was pended.
            // 2) completed synchronously.
            // 3) failed.
            //
            if (m_UseOverlappedIO)
            {
                //
                // we're using overlapped IO under Win9x (or NT with registry setting overriding
                // completion port usage)
                //
                switch (errorCode) {

                case 0:
                case SocketError.IOPending:

                    //
                    // the Async IO call was pended:
                    // Queue our event to the thread pool.
                    //
                    GlobalLog.Assert(m_UnmanagedBlob != null, "BaseOverlappedAsyncResult#{0}::CheckAsyncCallOverlappedResult()|Unmanaged blob isn't allocated.", ValidationHelper.HashString(this));
                    ThreadPool.UnsafeRegisterWaitForSingleObject(
                                                          m_OverlappedEvent,
                                                          new WaitOrTimerCallback(OverlappedCallback),
                                                          this,
                                                          -1,
                                                          true );

                    //
                    // we're done, completion will be asynchronous
                    // in the callback. return
                    //
                    return SocketError.Success;

                default:
                    //
                    // the Async IO call failed:
                    // set the number of bytes transferred to -1 (error)
                    //
                    ErrorCode = (int)errorCode;
                    Result = -1;
                    ReleaseUnmanagedStructures();
                    break;
                }
            }
            else
            {
#if DEBUG
                OverlappedCache cache = m_Cache;
                if (cache != null)
                {
                    SafeNativeOverlapped nativeOverlappedPtr = cache.NativeOverlapped;
                    if (nativeOverlappedPtr != null)
                        m_IntermediateNativeOverlapped = nativeOverlappedPtr;
                }
#endif
                //
                // We're using completion ports under WinNT.  Release one reference on the structures for
                // the main thread.
                //
                ReleaseUnmanagedStructures();

                switch (errorCode) {
                //
                // ignore cases in which a completion packet will be queued:
                // we'll deal with this IO in the callback
                //
                case 0:
                case SocketError.IOPending:
                    //
                    // ignore, do nothing
                    //
                    return SocketError.Success;

                    //
                    // in the remaining cases a completion packet will NOT be queued:
                    // we'll have to call the callback explicitly signaling an error
                    //
                default:
                    //
                    // call the callback with error code
                    //
                    ErrorCode = (int)errorCode;
                    Result = -1;

                    // The AsyncResult must be cleared since the callback isn't going to be called.
                    // Not doing so leads to a leak where the pinned cached OverlappedData continues to point to the async result object,
                    // which points to the Socket (as well as user data) and to the OverlappedCache, preventing the OverlappedCache
                    // finalizer from freeing the pinned OverlappedData.
                    if (m_Cache != null)
                    {
                        // Could be null only if SetUnmanagedStructures weren't called.
                        m_Cache.Overlapped.AsyncResult = null;
                    }

                    ReleaseUnmanagedStructures();  // Additional release for the completion that won't happen.
                    break;
                }
            }
            return errorCode;
        }
        private void CompleteIOCPOperation()
        {
            // TODO #4900: Optimization to remove callbacks if the operations are completed synchronously:
            //       Use SetFileCompletionNotificationModes(FILE_SKIP_COMPLETION_PORT_ON_SUCCESS).

            // If SetFileCompletionNotificationModes(FILE_SKIP_COMPLETION_PORT_ON_SUCCESS) is not set on this handle
            // it is guaranteed that the IOCP operation will be completed in the callback even if Socket.Success was 
            // returned by the Win32 API.

            // Required to allow another IOCP operation for the same handle.
            if (_ptrNativeOverlapped != null)
            {
                _ptrNativeOverlapped.Dispose();
                _ptrNativeOverlapped = null;
            }
        }
 private void FreeOverlapped(bool checkForShutdown)
 {
     if (!checkForShutdown || !NclUtilities.HasShutdownStarted)
     {
         if ((this.m_PtrNativeOverlapped != null) && !this.m_PtrNativeOverlapped.IsInvalid)
         {
             this.m_PtrNativeOverlapped.Dispose();
             this.m_PtrNativeOverlapped = null;
             this.m_Overlapped = null;
             this.m_PinState = PinState.None;
             this.m_PinnedAcceptBuffer = null;
             this.m_PinnedSingleBuffer = null;
             this.m_PinnedSingleBufferOffset = 0;
             this.m_PinnedSingleBufferCount = 0;
         }
         if (this.m_SocketAddressGCHandle.IsAllocated)
         {
             this.m_SocketAddressGCHandle.Free();
         }
         if (this.m_WSAMessageBufferGCHandle.IsAllocated)
         {
             this.m_WSAMessageBufferGCHandle.Free();
         }
         if (this.m_WSARecvMsgWSABufferArrayGCHandle.IsAllocated)
         {
             this.m_WSARecvMsgWSABufferArrayGCHandle.Free();
         }
         if (this.m_ControlBufferGCHandle.IsAllocated)
         {
             this.m_ControlBufferGCHandle.Free();
         }
     }
 }
        // Utility cleanup routine. Frees the overlapped structure.
        // This should be overriden to free pinned and unmanaged memory in the subclass.
        // It needs to also be invoked from the subclass.
        protected virtual void ForceReleaseUnmanagedStructures()
        {
            // Free the unmanaged memory if allocated.
            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Print(
                    "BaseOverlappedAsyncResult#" + LoggingHash.HashString(this) +
                    "::ForceReleaseUnmanagedStructures");
            }

            _nativeOverlapped.Dispose();
            _nativeOverlapped = null;
            GC.SuppressFinalize(this);
        }
 private void SetupOverlappedMultiple()
 {
     this.m_Overlapped = new Overlapped();
     ArraySegment<byte>[] array = new ArraySegment<byte>[this.m_BufferList.Count];
     this.m_BufferList.CopyTo(array, 0);
     if ((this.m_ObjectsToPin == null) || (this.m_ObjectsToPin.Length != array.Length))
     {
         this.m_ObjectsToPin = new object[array.Length];
     }
     for (int i = 0; i < array.Length; i++)
     {
         this.m_ObjectsToPin[i] = array[i].Array;
     }
     if ((this.m_WSABufferArray == null) || (this.m_WSABufferArray.Length != array.Length))
     {
         this.m_WSABufferArray = new WSABuffer[array.Length];
     }
     this.m_PtrNativeOverlapped = new SafeNativeOverlapped(this.m_Overlapped.UnsafePack(new IOCompletionCallback(this.CompletionPortCallback), this.m_ObjectsToPin));
     for (int j = 0; j < array.Length; j++)
     {
         ArraySegment<byte> segment = array[j];
         ValidationHelper.ValidateSegment(segment);
         this.m_WSABufferArray[j].Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(segment.Array, segment.Offset);
         this.m_WSABufferArray[j].Length = segment.Count;
     }
     this.m_PinState = PinState.MultipleBuffer;
 }
Beispiel #41
0
        internal bool TransmitPackets(SafeCloseSocket socketHandle, IntPtr packetArray, int elementCount, int sendSize, SafeNativeOverlapped overlapped)
        {
            EnsureDynamicWinsockMethods();
            TransmitPacketsDelegate transmitPackets = _dynamicWinsockMethods.GetDelegate<TransmitPacketsDelegate>(socketHandle);

            // UseDefaultWorkerThread = 0.
            return transmitPackets(socketHandle, packetArray, elementCount, sendSize, overlapped, 0);
        }
 private void SetupOverlappedSendPackets()
 {
     this.m_Overlapped = new Overlapped();
     this.m_SendPacketsDescriptor = new UnsafeNclNativeMethods.OSSOCK.TransmitPacketsElement[this.m_SendPacketsElementsFileCount + this.m_SendPacketsElementsBufferCount];
     if ((this.m_ObjectsToPin == null) || (this.m_ObjectsToPin.Length != (this.m_SendPacketsElementsBufferCount + 1)))
     {
         this.m_ObjectsToPin = new object[this.m_SendPacketsElementsBufferCount + 1];
     }
     this.m_ObjectsToPin[0] = this.m_SendPacketsDescriptor;
     int index = 1;
     foreach (SendPacketsElement element in this.m_SendPacketsElementsInternal)
     {
         if ((element.m_Buffer != null) && (element.m_Count > 0))
         {
             this.m_ObjectsToPin[index] = element.m_Buffer;
             index++;
         }
     }
     this.m_PtrNativeOverlapped = new SafeNativeOverlapped(this.m_Overlapped.UnsafePack(new IOCompletionCallback(this.CompletionPortCallback), this.m_ObjectsToPin));
     this.m_PtrSendPacketsDescriptor = Marshal.UnsafeAddrOfPinnedArrayElement(this.m_SendPacketsDescriptor, 0);
     int num2 = 0;
     int num3 = 0;
     foreach (SendPacketsElement element2 in this.m_SendPacketsElementsInternal)
     {
         if (element2 != null)
         {
             if ((element2.m_Buffer != null) && (element2.m_Count > 0))
             {
                 this.m_SendPacketsDescriptor[num2].buffer = Marshal.UnsafeAddrOfPinnedArrayElement(element2.m_Buffer, element2.m_Offset);
                 this.m_SendPacketsDescriptor[num2].length = (uint) element2.m_Count;
                 this.m_SendPacketsDescriptor[num2].flags = element2.m_Flags;
                 num2++;
             }
             else if ((element2.m_FilePath != null) && (element2.m_FilePath.Length != 0))
             {
                 this.m_SendPacketsDescriptor[num2].fileHandle = this.m_SendPacketsFileHandles[num3].DangerousGetHandle();
                 this.m_SendPacketsDescriptor[num2].fileOffset = element2.m_Offset;
                 this.m_SendPacketsDescriptor[num2].length = (uint) element2.m_Count;
                 this.m_SendPacketsDescriptor[num2].flags = element2.m_Flags;
                 num3++;
                 num2++;
             }
         }
     }
     this.m_PinState = PinState.SendPackets;
 }
Beispiel #43
0
 internal static extern uint HttpReceiveClientCertificate(SafeHandle requestQueueHandle, ulong connectionId, uint flags, byte *pSslClientCertInfo, uint sslClientCertInfoSize, uint *pBytesReceived, SafeNativeOverlapped pOverlapped);
 private void SetupOverlappedSingle(bool pinSingleBuffer)
 {
     this.m_Overlapped = new Overlapped();
     if (pinSingleBuffer)
     {
         if (this.m_Buffer != null)
         {
             this.m_PtrNativeOverlapped = new SafeNativeOverlapped(this.m_Overlapped.UnsafePack(new IOCompletionCallback(this.CompletionPortCallback), this.m_Buffer));
             this.m_PinnedSingleBuffer = this.m_Buffer;
             this.m_PinnedSingleBufferOffset = this.m_Offset;
             this.m_PinnedSingleBufferCount = this.m_Count;
             this.m_PtrSingleBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(this.m_Buffer, this.m_Offset);
             this.m_PtrAcceptBuffer = IntPtr.Zero;
             this.m_WSABuffer.Pointer = this.m_PtrSingleBuffer;
             this.m_WSABuffer.Length = this.m_Count;
             this.m_PinState = PinState.SingleBuffer;
         }
         else
         {
             this.m_PtrNativeOverlapped = new SafeNativeOverlapped(this.m_Overlapped.UnsafePack(new IOCompletionCallback(this.CompletionPortCallback), null));
             this.m_PinnedSingleBuffer = null;
             this.m_PinnedSingleBufferOffset = 0;
             this.m_PinnedSingleBufferCount = 0;
             this.m_PtrSingleBuffer = IntPtr.Zero;
             this.m_PtrAcceptBuffer = IntPtr.Zero;
             this.m_WSABuffer.Pointer = this.m_PtrSingleBuffer;
             this.m_WSABuffer.Length = this.m_Count;
             this.m_PinState = PinState.NoBuffer;
         }
     }
     else
     {
         this.m_PtrNativeOverlapped = new SafeNativeOverlapped(this.m_Overlapped.UnsafePack(new IOCompletionCallback(this.CompletionPortCallback), this.m_AcceptBuffer));
         this.m_PinnedAcceptBuffer = this.m_AcceptBuffer;
         this.m_PtrAcceptBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(this.m_AcceptBuffer, 0);
         this.m_PtrSingleBuffer = IntPtr.Zero;
         this.m_PinState = PinState.SingleAcceptBuffer;
     }
 }
Beispiel #45
0
 internal static extern uint HttpSendHttpResponse(SafeHandle requestQueueHandle, ulong requestId, uint flags, HTTP_RESPONSE_V2 *pHttpResponse, HTTP_CACHE_POLICY *pCachePolicy, uint *pBytesSent, IntPtr pReserved1, uint Reserved2, SafeNativeOverlapped pOverlapped, IntPtr pLogData);
        private unsafe CancellationToken CreateDisconnectToken(ulong connectionId)
        {
            LogHelper.LogDebug(_logger, "CreateDisconnectToken", "Registering connection for disconnect for connection ID: " + connectionId);

            // Create a nativeOverlapped callback so we can register for disconnect callback
            var cts         = new CancellationTokenSource();
            var returnToken = cts.Token;

            SafeNativeOverlapped nativeOverlapped = null;
            var boundHandle = _requestQueue.BoundHandle;

            nativeOverlapped = new SafeNativeOverlapped(boundHandle, boundHandle.AllocateNativeOverlapped(
                                                            (errorCode, numBytes, overlappedPtr) =>
            {
                LogHelper.LogDebug(_logger, "CreateDisconnectToken", "http.sys disconnect callback fired for connection ID: " + connectionId);

                // Free the overlapped
                nativeOverlapped.Dispose();

                // Pull the token out of the list and Cancel it.
                ConnectionCancellation token;
                _connectionCancellationTokens.TryRemove(connectionId, out token);
                try
                {
                    cts.Cancel();
                }
                catch (AggregateException exception)
                {
                    LogHelper.LogException(_logger, "CreateDisconnectToken Callback", exception);
                }
            },
                                                            null, null));

            uint statusCode;

            try
            {
                statusCode = HttpApi.HttpWaitForDisconnectEx(requestQueueHandle: _requestQueue.Handle,
                                                             connectionId: connectionId, reserved: 0, overlapped: nativeOverlapped);
            }
            catch (Win32Exception exception)
            {
                statusCode = (uint)exception.NativeErrorCode;
                LogHelper.LogException(_logger, "CreateDisconnectToken", exception);
            }

            if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING &&
                statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
            {
                // We got an unknown result, assume the connection has been closed.
                nativeOverlapped.Dispose();
                ConnectionCancellation ignored;
                _connectionCancellationTokens.TryRemove(connectionId, out ignored);
                LogHelper.LogDebug(_logger, "HttpWaitForDisconnectEx", new Win32Exception((int)statusCode));
                cts.Cancel();
            }

            if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && HttpSysListener.SkipIOCPCallbackOnSuccess)
            {
                // IO operation completed synchronously - callback won't be called to signal completion
                nativeOverlapped.Dispose();
                ConnectionCancellation ignored;
                _connectionCancellationTokens.TryRemove(connectionId, out ignored);
                cts.Cancel();
            }

            return(returnToken);
        }
Beispiel #47
0
 internal static extern uint HttpWaitForDisconnectEx(SafeHandle requestQueueHandle, ulong connectionId, uint reserved, SafeNativeOverlapped overlapped);
Beispiel #48
0
        private bool TransmitPackets(SafeCloseSocket socketHandle, IntPtr packetArray, int elementCount, int sendSize, SafeNativeOverlapped overlapped, TransmitFileOptions flags)
        {
            EnsureDynamicWinsockMethods();
            TransmitPacketsDelegate transmitPackets = m_DynamicWinsockMethods.GetDelegate<TransmitPacketsDelegate>(socketHandle);

            return transmitPackets(socketHandle, packetArray, elementCount, sendSize, overlapped, flags);
        }
Beispiel #49
0
 internal static partial uint HttpReceiveClientCertificate(SafeHandle requestQueueHandle, ulong connectionId, uint flags, HTTP_SSL_CLIENT_CERT_INFO *pSslClientCertInfo, uint sslClientCertInfoSize, uint *pBytesReceived, SafeNativeOverlapped pOverlapped);
 private unsafe void InitializeOverlapped()
 {
     m_Overlapped          = new Overlapped();
     m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, null));
 }