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)); }
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)); }
/// <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; }
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))); }
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"); } }
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; }
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; }
// 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)); }
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); }
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); } }
// 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; } }
// 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; }
/// <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); } }