UnsafePack() private method

private UnsafePack ( System iocb ) : System.Threading.NativeOverlapped*
iocb System
return System.Threading.NativeOverlapped*
 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));
 }
Exemplo n.º 2
0
		internal unsafe OverlappedCache(Overlapped overlapped, object pinnedObjects, IOCompletionCallback callback, bool alreadyTriedCast)
		{
			this.m_Overlapped = overlapped;
			this.m_PinnedObjects = pinnedObjects;
			this.m_PinnedObjectsArray = (alreadyTriedCast ? null : new object[0]);
			this.m_NativeOverlapped = new SafeNativeOverlapped((IntPtr)((void*)overlapped.UnsafePack(callback, pinnedObjects)));
		}
 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));
 }
Exemplo n.º 4
0
        /// <summary>
        /// Creates a <see cref="CancellationTokenSource"/> for the given <paramref name="connectionId"/> and registers it for disconnect.
        /// </summary>
        /// <param name="connectionId">The connection id.</param>
        /// <returns>A <see cref="CancellationTokenSource"/> that is registered for disconnect for the connection associated with the <paramref name="connectionId"/>.</returns>
        public CancellationToken CreateToken(ulong connectionId)
        {
            Debug.WriteLine("Server: Registering connection for disconnect for connection ID: " + connectionId);
            // Create a nativeOverlapped callback so we can register for disconnect callback
            var overlapped = new Overlapped();
            var cts = new CancellationTokenSource();
            var nativeOverlapped = overlapped.UnsafePack((errorCode, numBytes, pOVERLAP) =>
            {
                Debug.WriteLine("Server: http.sys disconnect callback fired for connection ID: " + connectionId);

                // Free the overlapped
                Overlapped.Free(pOVERLAP);

                // Pull the token out of the list and Cancel it.
                Lazy<CancellationToken> token;
                _connectionCancellationTokens.TryRemove(connectionId, out token);
                cts.Cancel();
            },
            null);

            uint hr = NativeMethods.HttpWaitForDisconnect(_requestQueueHandle, connectionId, nativeOverlapped);

            if (hr != NativeMethods.HttpErrors.ERROR_IO_PENDING &&
                hr != NativeMethods.HttpErrors.NO_ERROR)
            {
                // We got an unknown result so throw
                Debug.WriteLine("Unable to register disconnect callback");
                return CancellationToken.None;
            }

            return cts.Token;
        }
Exemplo n.º 5
0
		internal unsafe OverlappedCache(Overlapped overlapped, object[] pinnedObjectsArray, IOCompletionCallback callback)
		{
			this.m_Overlapped = overlapped;
			this.m_PinnedObjects = pinnedObjectsArray;
			this.m_PinnedObjectsArray = pinnedObjectsArray;
			this.m_NativeOverlapped = new SafeNativeOverlapped((IntPtr)((void*)overlapped.UnsafePack(callback, pinnedObjectsArray)));
		}
Exemplo n.º 6
0
        private void RegisterForDisconnect(HttpListenerContext context, Action disconnectCallback)
        {
            // Get the connection id value
            FieldInfo connectionIdField = typeof(HttpListenerRequest).GetField("m_ConnectionId", BindingFlags.Instance | BindingFlags.NonPublic);
            if (_requestQueueHandle != null && connectionIdField != null)
            {
                Debug.WriteLine("Server: Registering for disconnect");

                ulong connectionId = (ulong)connectionIdField.GetValue(context.Request);
                // Create a nativeOverlapped callback so we can register for disconnect callback
                var overlapped = new Overlapped();
                var nativeOverlapped = overlapped.UnsafePack((errorCode, numBytes, pOVERLAP) =>
                {
                    Debug.WriteLine("Server: http.sys disconnect callback fired.");

                    // Free the overlapped
                    Overlapped.Free(pOVERLAP);

                    // Mark the client as disconnected
                    disconnectCallback();
                },
                null);

                uint hr = NativeMethods.HttpWaitForDisconnect(_requestQueueHandle, connectionId, nativeOverlapped);

                if (hr != NativeMethods.HttpErrors.ERROR_IO_PENDING &&
                    hr != NativeMethods.HttpErrors.NO_ERROR)
                {
                    // We got an unknown result so throw
                    throw new InvalidOperationException("Unable to register disconnect callback");
                }
            }
            else
            {
                Debug.WriteLine("Server: Unable to resolve requestQueue handle. Disconnect notifications will be ignored");
            }
        }
Exemplo n.º 7
0
        internal unsafe IAsyncResult BeginRead(byte[] data, int offset, int size, AsyncCallback callback, object state)
        {
            PipeAsyncResult asyncResult = new PipeAsyncResult(callback);
            // 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;
            intOverlapped = overlapped.UnsafePack(IOCallback, data);
            asyncResult._overlapped = intOverlapped;
            bool status;

            // pin the buffer and read data with overlapped
            fixed(byte* p = data) {
                    status = NativePipe.ReadFile(_handle, p + offset, size, IntPtr.Zero, intOverlapped);
            }
            if (!status)
            {
                int error = Marshal.GetLastWin32Error();
                // For pipes, when they hit EOF, they will come here.
                if (error == NativePipe.ERROR_BROKEN_PIPE) {
                    // Not an error, but EOF.  AsyncFSCallback will NOT be 
                    // called.  Call the user callback here.
                    asyncResult.CallUserCallback();                 
                    // EndRead will free the Overlapped struct correctly.
                }
                else if (error != NativePipe.ERROR_IO_PENDING)
                    throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ReadFailure"), GetMessage(error)));
            }
            return asyncResult;
        }
 public unsafe OverlappedIOCallback(WaitCallback callback, ExceptionCallback exceptionCallback)
 {
     Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, null);
     this.nativeOverlapped = overlapped.UnsafePack(new IOCompletionThunk(this.IOCallback, exceptionCallback).ThunkFrame, null);
     this.callback = callback;
 }
Exemplo n.º 9
0
        private unsafe CancellationToken CreateToken(ulong connectionId)
        {
            // Create a nativeOverlapped callback so we can register for disconnect callback
            var overlapped = new Overlapped();
            var cts = new CancellationTokenSource();
            CancellationToken returnToken = cts.Token;

            NativeOverlapped* nativeOverlapped = overlapped.UnsafePack(
                (errorCode, numBytes, overlappedPtr) =>
                {
                    // Free the overlapped
                    Overlapped.Free(overlappedPtr);

                    if (errorCode != NativeMethods.HttpErrors.NO_ERROR)
                    {
                        LogHelper.LogException(_logger, "IOCompletionCallback", new Win32Exception((int)errorCode));
                    }

                    // Pull the token out of the list and Cancel it.
                    ConnectionCancellation cancellation;
                    _connectionCancellationTokens.TryRemove(connectionId, out cancellation);

                    bool success = ThreadPool.UnsafeQueueUserWorkItem(CancelToken, cts);
                    Debug.Assert(success, "Unable to queue disconnect notification.");
                },
                null);

            uint hr = NativeMethods.HttpWaitForDisconnect(_requestQueueHandle, connectionId, nativeOverlapped);

            if (hr != NativeMethods.HttpErrors.ERROR_IO_PENDING &&
                hr != NativeMethods.HttpErrors.NO_ERROR)
            {
                // We got an unknown result, assume the connection has been closed.
                Overlapped.Free(nativeOverlapped);
                ConnectionCancellation cancellation;
                _connectionCancellationTokens.TryRemove(connectionId, out cancellation);
                LogHelper.LogException(_logger, "HttpWaitForDisconnect", new Win32Exception((int)hr));
                cts.Cancel();
                cts.Dispose();
            }

            return returnToken;
        }
Exemplo n.º 10
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;
        }
 private unsafe void InitializeOverlapped()
 {
     m_Overlapped = new Overlapped();
     m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, null));
 }
Exemplo n.º 12
0
        private void ReceiveLoop()
        {
            _listener.BeginGetContext(ar =>
            {
                HttpListenerContext context;
                try
                {
                    context = _listener.EndGetContext(ar);
                }
                catch (Exception)
                {
                    return;
                }

                var cts = new CancellationTokenSource();

                // Get the connection id value
                var connectionIdField = typeof(HttpListenerRequest).GetField("m_ConnectionId", BindingFlags.Instance | BindingFlags.NonPublic);
                if (_requestQueueHandle != null && connectionIdField != null)
                {
                    ulong connectionId = (ulong)connectionIdField.GetValue(context.Request);
                    // Create a nativeOverlapped callback so we can register for disconnect callback
                    var overlapped = new Overlapped();
                    var nativeOverlapped = overlapped.UnsafePack((errorCode, numBytes, pOVERLAP) =>
                    {
                        // Free the overlapped
                        Overlapped.Free(pOVERLAP);

                        // Mark the client as disconnected
                        cts.Cancel();
                    },
                    null);

                    uint hr = NativeMethods.HttpWaitForDisconnect(_requestQueueHandle, connectionId, nativeOverlapped);

                    if (hr != NativeMethods.HttpErrors.ERROR_IO_PENDING &&
                        hr != NativeMethods.HttpErrors.NO_ERROR)
                    {
                        // We got an unknown result so throw
                        throw new InvalidOperationException("Unable to register disconnect callback");
                    }
                }
                else
                {
                    Debug.WriteLine("Unable to resolve requestQueue handle. Disconnect notifications will be ignored");
                }

                ReceiveLoop();

                // Process the request async
                ProcessRequestAsync(context, cts.Token).ContinueWith(task =>
                {
                    if (task.IsFaulted)
                    {
                        Exception ex = task.Exception.GetBaseException();
                        context.Response.ServerError(ex).Catch();

                        Debug.WriteLine(ex.Message);
                    }

                    context.Response.CloseSafe();
                });

            }, null);
        }
Exemplo n.º 13
0
 internal unsafe DisconnectAsyncResult(HttpListener httpListener, ulong connectionId) {
     GlobalLog.Print("DisconnectAsyncResult#" + ValidationHelper.HashString(this) + "::.ctor() httpListener#" + ValidationHelper.HashString(httpListener) + " connectionId:" + connectionId);
     m_OwnershipState = 1;
     m_HttpListener = httpListener;
     m_ConnectionId = connectionId;
     Overlapped overlapped = new Overlapped();
     overlapped.AsyncResult = this;
     // we can call the Unsafe API here, we won't ever call user code
     m_NativeOverlapped = overlapped.UnsafePack(s_IOCallback, null);
     GlobalLog.Print("DisconnectAsyncResult#" + ValidationHelper.HashString(this) + "::.ctor() overlapped#" + ValidationHelper.HashString(overlapped) + " nativeOverlapped:" + ((IntPtr)m_NativeOverlapped).ToString("x"));
 }
        internal OverlappedCache(Overlapped overlapped, object pinnedObjects, IOCompletionCallback callback, bool alreadyTriedCast)
        {
            m_Overlapped = overlapped;
            m_PinnedObjects = pinnedObjects;
            m_PinnedObjectsArray = alreadyTriedCast ? null : NclConstants.EmptyObjectArray;

            unsafe
            {
                m_NativeOverlapped = (IntPtr) overlapped.UnsafePack(callback, pinnedObjects);
            }
        }
        internal OverlappedCache(Overlapped overlapped, object[] pinnedObjectsArray, IOCompletionCallback callback)
        {
            m_Overlapped = overlapped;
            m_PinnedObjects = pinnedObjectsArray;
            m_PinnedObjectsArray = pinnedObjectsArray;

            unsafe
            {
                m_NativeOverlapped = (IntPtr) overlapped.UnsafePack(callback, pinnedObjectsArray);
            }
        }
Exemplo n.º 16
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;
            }
        }
Exemplo n.º 17
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;
        }
Exemplo n.º 18
0
		/// <summary>
		/// Create instance, automatically allocates NativeOverlapped structure
		/// </summary>
		/// <param name="callback">User specified callback</param>
		/// <param name="state">User specified state</param>
		/// <param name="fileOffset">Start position</param>
		/// <param name="userData">An object or array of objects representing the input or output buffer for the operation. Buffer is pinned until object is disposed.</param>
		public AsyncJob(AsyncCallback callback, object state, UInt64 fileOffset, object userData) {
			_callback = callback;
			_state = state;
			Overlapped ov = new Overlapped(unchecked((int)(fileOffset & 0xFFFFFFFF)), unchecked((int)((fileOffset >> 32) & 0xFFFFFFFF)), IntPtr.Zero, this);
			unsafe { _nativeOverlapped = ov.UnsafePack(completionCallback, userData); }
		}
 private unsafe FileStreamAsyncResult BeginWriteCore(byte[] bytes, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
 {
     NativeOverlapped* overlappedPtr;
     FileStreamAsyncResult ar = new FileStreamAsyncResult {
         _handle = this._handle,
         _userCallback = userCallback,
         _userStateObject = stateObject,
         _isWrite = true
     };
     ManualResetEvent event2 = new ManualResetEvent(false);
     ar._waitHandle = event2;
     Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, ar);
     if (userCallback != null)
     {
         overlappedPtr = overlapped.Pack(IOCallback, bytes);
     }
     else
     {
         overlappedPtr = overlapped.UnsafePack(null, bytes);
     }
     ar._overlapped = overlappedPtr;
     if (this.CanSeek)
     {
         long length = this.Length;
         if (this._exposedHandle)
         {
             this.VerifyOSHandlePosition();
         }
         if ((this._pos + numBytes) > length)
         {
             this.SetLengthCore(this._pos + numBytes);
         }
         overlappedPtr->OffsetLow = (int) this._pos;
         overlappedPtr->OffsetHigh = (int) (this._pos >> 0x20);
         this.SeekCore((long) numBytes, SeekOrigin.Current);
     }
     int hr = 0;
     if ((this.WriteFileNative(this._handle, bytes, offset, numBytes, overlappedPtr, out hr) == -1) && (numBytes != -1))
     {
         if (hr == 0xe8)
         {
             ar.CallUserCallback();
             return ar;
         }
         if (hr == 0x3e5)
         {
             return ar;
         }
         if (!this._handle.IsClosed && this.CanSeek)
         {
             this.SeekCore(0L, SeekOrigin.Current);
         }
         if (hr == 0x26)
         {
             __Error.EndOfFile();
             return ar;
         }
         __Error.WinIOError(hr, string.Empty);
     }
     return ar;
 }
        internal void Pack(object pinnedObjects)
        {
            if (this.nativeOverlapped != null)
            {
                // If we reach this condition, we have a bug in a derived AsyncResult class.
                // It attempted to initiate a new async I/O operation before the previous
                // one completed. This is a fatal condition, so we cannot continue execution.
                DiagnosticUtility.FailFast("Must allow previous I/O to complete before packing");
            }

            GC.ReRegisterForFinalize(this);

            Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, this);
            if (this.callback == null)
            {
                this.nativeOverlapped = overlapped.UnsafePack(
                    IOCompletionCallback,
                    pinnedObjects);
            }
            else
            {
                this.nativeOverlapped = overlapped.Pack(
                    IOCompletionCallback,
                    pinnedObjects);
            }
        }