public OverlappedContext() { if (OverlappedContext.completeCallback == null) { OverlappedContext.completeCallback = Fx.ThunkCallback(new IOCompletionCallback(CompleteCallback)); } if (OverlappedContext.eventCallback == null) { OverlappedContext.eventCallback = Fx.ThunkCallback(new WaitOrTimerCallback(EventCallback)); } if (OverlappedContext.cleanupCallback == null) { OverlappedContext.cleanupCallback = Fx.ThunkCallback(new WaitOrTimerCallback(CleanupCallback)); } this.bufferHolder = new object[] { OverlappedContext.dummyBuffer }; this.overlapped = new Overlapped(); this.nativeOverlapped = this.overlapped.UnsafePack(OverlappedContext.completeCallback, this.bufferHolder); // When replacing the buffer, we need to provoke the CLR to fix up the handle of the pin. this.pinnedHandle = GCHandle.FromIntPtr(*((IntPtr*)nativeOverlapped + (IntPtr.Size == 4 ? HandleOffsetFromOverlapped32 : HandleOffsetFromOverlapped64))); this.pinnedTarget = this.pinnedHandle.Target; // Create the permanently rooted holder and put it in the Overlapped. this.rootedHolder = new RootedHolder(); this.overlapped.AsyncResult = rootedHolder; }
public void SetOperationCompleted() { if (this._overlapped != null) { this._cancellationRegistration.Dispose(); this._handle = null; this._overlapped = null; } }
protected override void OnReleasePins() { if (_nativeOverlapped != null) { NativeOverlapped* nativeOverlapped = _nativeOverlapped; _nativeOverlapped = null; _boundHandle.FreeNativeOverlapped(nativeOverlapped); } }
public AsyncOperationState(AsyncSocket socketExtended, Action<uint, uint> callback) { m_socketExtended = socketExtended; m_callback = callback; m_nativeOverlapped = new Overlapped().UnsafePack(Complete, null); WSABuffer = new WSABuffer(); }
public unsafe ThreadPoolBoundHandleOverlapped(IOCompletionCallback callback, object state, object pinData, PreAllocatedOverlapped preAllocated) { _userCallback = callback; _userState = state; _preAllocated = preAllocated; _nativeOverlapped = Pack(CompletionCallback, pinData); _nativeOverlapped->OffsetLow = 0; // CLR reuses NativeOverlapped instances and does not reset these _nativeOverlapped->OffsetHigh = 0; }
internal unsafe HttpResponseStreamAsyncResult(object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, int size, bool chunked, bool sentHeaders) : base(asyncObject, userState, callback) { this.m_SentHeaders = sentHeaders; Overlapped overlapped = new Overlapped { AsyncResult = this }; if (size == 0) { this.m_DataChunks = null; this.m_pOverlapped = overlapped.Pack(s_IOCallback, null); } else { this.m_DataChunks = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK[chunked ? 3 : 1]; object[] userData = new object[1 + this.m_DataChunks.Length]; userData[this.m_DataChunks.Length] = this.m_DataChunks; int num = 0; byte[] arr = null; if (chunked) { arr = ConnectStream.GetChunkHeader(size, out num); this.m_DataChunks[0] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); this.m_DataChunks[0].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; this.m_DataChunks[0].BufferLength = (uint) (arr.Length - num); userData[0] = arr; this.m_DataChunks[1] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); this.m_DataChunks[1].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; this.m_DataChunks[1].BufferLength = (uint) size; userData[1] = buffer; this.m_DataChunks[2] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); this.m_DataChunks[2].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; this.m_DataChunks[2].BufferLength = (uint) NclConstants.CRLF.Length; userData[2] = NclConstants.CRLF; } else { this.m_DataChunks[0] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); this.m_DataChunks[0].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; this.m_DataChunks[0].BufferLength = (uint) size; userData[0] = buffer; } this.m_pOverlapped = overlapped.Pack(s_IOCallback, userData); if (chunked) { this.m_DataChunks[0].pBuffer = (byte*) Marshal.UnsafeAddrOfPinnedArrayElement(arr, num); this.m_DataChunks[1].pBuffer = (byte*) Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset); this.m_DataChunks[2].pBuffer = (byte*) Marshal.UnsafeAddrOfPinnedArrayElement(NclConstants.CRLF, 0); } else { this.m_DataChunks[0].pBuffer = (byte*) Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset); } } }
internal AsyncFileStream_AsyncResult( AsyncCallback userCallback, Object stateObject, bool isWrite ) { m_userCallback = userCallback; m_userStateObject = stateObject; m_waitHandle = new ManualResetEvent( false ); m_isWrite = isWrite; Overlapped overlapped = new Overlapped( 0, 0, IntPtr.Zero, this ); m_overlapped = overlapped.Pack( s_callback, null ); }
private Interop.HttpApi.HTTP_REQUEST* Allocate(ThreadPoolBoundHandle boundHandle, uint size) { uint newSize = size != 0 ? size : RequestBuffer == null ? 4096 : Size; if (_nativeOverlapped != null && newSize != RequestBuffer.Length) { NativeOverlapped* nativeOverlapped = _nativeOverlapped; _nativeOverlapped = null; _boundHandle.FreeNativeOverlapped(nativeOverlapped); } if (_nativeOverlapped == null) { SetBuffer(checked((int)newSize)); _boundHandle = boundHandle; _nativeOverlapped = boundHandle.AllocateNativeOverlapped(ListenerAsyncResult.IOCallback, state: _result, pinData: RequestBuffer); return (Interop.HttpApi.HTTP_REQUEST*)Marshal.UnsafeAddrOfPinnedArrayElement(RequestBuffer, 0); } return RequestBlob; }
public void AllowCancellation(SafeHandle handle, NativeOverlapped* overlapped) { Contract.Assert(handle != null, "Handle cannot be null"); Contract.Assert(!handle.IsInvalid, "Handle cannot be invalid"); Contract.Assert(overlapped != null, "Overlapped cannot be null"); Contract.Assert(this._handle == null && this._overlapped == null, "Cancellation is already allowed."); if (!_cancellationToken.CanBeCanceled) { return; } this._handle = handle; this._overlapped = overlapped; if (this._cancellationToken.IsCancellationRequested) { this.Cancel(); } else { this._cancellationRegistration = this._cancellationToken.Register(Cancel); } }
public Win32FileJournalWriter(string filename, long journalSize) { _filename = filename; _handle = Win32NativeFileMethods.CreateFile(filename, Win32NativeFileAccess.GenericWrite, Win32NativeFileShare.Read, IntPtr.Zero, Win32NativeFileCreationDisposition.OpenAlways, Win32NativeFileAttributes.Write_Through | Win32NativeFileAttributes.NoBuffering | Win32NativeFileAttributes.Overlapped, IntPtr.Zero); if (_handle.IsInvalid) throw new Win32Exception(); Win32NativeFileMethods.SetFileLength(_handle, journalSize); NumberOfAllocatedPages = journalSize/AbstractPager.PageSize; _nativeOverlapped = (NativeOverlapped*) Marshal.AllocHGlobal(sizeof (NativeOverlapped)); _nativeOverlapped->InternalLow = IntPtr.Zero; _nativeOverlapped->InternalHigh = IntPtr.Zero; }
internal void Reset(uint size) { if (size == _size) { return; } if (_size != 0) { _boundHandle.FreeNativeOverlapped(_pOverlapped); } _size = size; if (size == 0) { _pOverlapped = null; _memoryBlob = null; _backingBuffer = null; return; } _backingBuffer = new byte[checked((int)size)]; _pOverlapped = _boundHandle.AllocateNativeOverlapped(s_IOCallback, state: this, pinData: _backingBuffer); _memoryBlob = (Interop.HttpApi.HTTP_SSL_CLIENT_CERT_INFO*)Marshal.UnsafeAddrOfPinnedArrayElement(_backingBuffer, 0); }
internal void Reset(uint size) { if (size == m_Size) { return; } if (m_Size != 0) { Overlapped.Free(m_pOverlapped); } m_Size = size; if (size == 0) { m_pOverlapped = null; m_MemoryBlob = null; m_BackingBuffer = null; return; } m_BackingBuffer = new byte[checked((int) size)]; Overlapped overlapped = new Overlapped(); overlapped.AsyncResult = this; m_pOverlapped = overlapped.Pack(s_IOCallback, m_BackingBuffer); m_MemoryBlob = (UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO*) Marshal.UnsafeAddrOfPinnedArrayElement(m_BackingBuffer, 0); }
internal HttpResponseStreamAsyncResult(object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, int size, bool chunked, bool sentHeaders): base(asyncObject, userState, callback){ m_SentHeaders = sentHeaders; Overlapped overlapped = new Overlapped(); overlapped.AsyncResult = this; if (size == 0) { m_DataChunks = null; m_pOverlapped = overlapped.Pack(s_IOCallback, null); } else { m_DataChunks = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK[chunked ? 3 : 1]; GlobalLog.Print("HttpResponseStreamAsyncResult#" + ValidationHelper.HashString(this) + "::.ctor() m_pOverlapped:0x" + ((IntPtr)m_pOverlapped).ToString("x8")); object[] objectsToPin = new object[1 + m_DataChunks.Length]; objectsToPin[m_DataChunks.Length] = m_DataChunks; int chunkHeaderOffset = 0; byte[] chunkHeaderBuffer = null; if (chunked) { chunkHeaderBuffer = ConnectStream.GetChunkHeader(size, out chunkHeaderOffset); m_DataChunks[0] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); m_DataChunks[0].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; m_DataChunks[0].BufferLength = (uint)(chunkHeaderBuffer.Length - chunkHeaderOffset); objectsToPin[0] = chunkHeaderBuffer; m_DataChunks[1] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); m_DataChunks[1].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; m_DataChunks[1].BufferLength = (uint)size; objectsToPin[1] = buffer; m_DataChunks[2] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); m_DataChunks[2].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; m_DataChunks[2].BufferLength = (uint)NclConstants.CRLF.Length; objectsToPin[2] = NclConstants.CRLF; } else { m_DataChunks[0] = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); m_DataChunks[0].DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; m_DataChunks[0].BufferLength = (uint)size; objectsToPin[0] = buffer; } // This call will pin needed memory m_pOverlapped = overlapped.Pack(s_IOCallback, objectsToPin); if (chunked) { m_DataChunks[0].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(chunkHeaderBuffer, chunkHeaderOffset)); m_DataChunks[1].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset)); m_DataChunks[2].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(NclConstants.CRLF, 0)); } else { m_DataChunks[0].pBuffer = (byte*)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset)); } } }
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")); }
public ScheduledOverlapped() { #if WINDOWS_UWP || PCL throw new NotImplementedException(); #else this.nativeOverlapped = (new Overlapped()).UnsafePack( Fx.ThunkCallback(new IOCompletionCallback(IOCallback)), null); #endif }
unsafe internal static extern OverlappedData GetOverlappedFromNative(NativeOverlapped *nativeOverlappedPtr);
// call back helper internal static void PerformIOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped *pNativeOverlapped) { do { OverlappedData overlapped = OverlappedData.GetOverlappedFromNative(pNativeOverlapped); if (overlapped._callback is IOCompletionCallback iocb) { // We got here because of UnsafePack (or) Pack with EC flow suppressed iocb(errorCode, numBytes, pNativeOverlapped); } else { // We got here because of Pack var helper = (_IOCompletionCallback?)overlapped._callback; Debug.Assert(helper != null, "Should only be receiving a completion callback if a delegate was provided."); helper._errorCode = errorCode; helper._numBytes = numBytes; helper._pNativeOverlapped = pNativeOverlapped; ExecutionContext.RunInternal(helper._executionContext, IOCompletionCallback_Context_Delegate, helper); } // Quickly check the VM again, to see if a packet has arrived. OverlappedData.CheckVMForIOPacket(out pNativeOverlapped, out errorCode, out numBytes); } while (pNativeOverlapped != null); }
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; }
internal static extern uint HttpReceiveClientCertificate(CriticalHandle requestQueueHandle, ulong connectionId, uint flags, byte *pSslClientCertInfo, uint sslClientCertInfoSize, uint *pBytesReceived, NativeOverlapped *pOverlapped);
public static extern bool WriteFileGather( SafeFileHandle hFile, FileSegmentElement *aSegmentArray, uint nNumberOfBytesToWrite, IntPtr lpReserved, NativeOverlapped *lpOverlapped);
public static extern bool GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped *lpOverlapped, out uint lpNumberOfBytesTransferred, bool bWait);
internal static extern uint HttpWaitForDisconnect(CriticalHandle requestQueueHandle, ulong connectionId, NativeOverlapped *pOverlapped);
private void IOCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped) { Callback(); }
internal static extern uint HttpSendResponseEntityBody(CriticalHandle requestQueueHandle, ulong requestId, uint flags, ushort entityChunkCount, HTTP_DATA_CHUNK *pEntityChunks, uint *pBytesSent, SafeLocalFree pRequestBuffer, uint requestBufferLength, NativeOverlapped *pOverlapped, void *pLogData);
internal static extern uint HttpSendHttpResponse(CriticalHandle requestQueueHandle, ulong requestId, uint flags, HTTP_RESPONSE *pHttpResponse, void *pCachePolicy, uint *pBytesSent, SafeLocalFree pRequestBuffer, uint requestBufferLength, NativeOverlapped *pOverlapped, void *pLogData);
internal static extern uint HttpReceiveHttpRequest(CriticalHandle requestQueueHandle, ulong requestId, uint flags, HTTP_REQUEST *pRequestBuffer, uint requestBufferLength, uint *pBytesReturned, NativeOverlapped *pOverlapped);
/// <summary>Callback invoked when an asynchronous read on the directory handle completes.</summary> private unsafe void ReadDirectoryChangesCallback(uint errorCode, uint numBytes, NativeOverlapped *overlappedPointer) { AsyncReadState state = (AsyncReadState)ThreadPoolBoundHandle.GetNativeOverlappedState(overlappedPointer); try { if (IsHandleInvalid(state.DirectoryHandle)) { return; } if (errorCode != 0) { // Inside a service the first completion status is false; // need to monitor again. const int ERROR_OPERATION_ABORTED = 995; if (errorCode != ERROR_OPERATION_ABORTED) { OnError(new ErrorEventArgs(new Win32Exception((int)errorCode))); EnableRaisingEvents = false; } return; } // Ignore any events that occurred before this "session", // so we don't get changed or error events after we // told FSW to stop. Even with this check, though, there's a small // race condition, as immediately after we do the check, raising // events could be disabled. if (state.Session != Volatile.Read(ref _currentSession)) { return; } if (numBytes == 0) { NotifyInternalBufferOverflowEvent(); } else { ParseEventBufferAndNotifyForEach(state.Buffer); } } finally { // Clean up state associated with this one iteration state.ThreadPoolBinding.FreeNativeOverlapped(overlappedPointer); // Then call Monitor again to either start the next iteration or // clean up the whole operation. Monitor(state); } }
public static extern bool WriteFileEx(SafeFileHandle hFile, byte *lpBuffer, uint nNumberOfBytesToWrite, NativeOverlapped *lpOverlapped, WriteFileCompletionDelegate lpCompletionRoutine);
public void Dispose() { Disposed = true; GC.SuppressFinalize(this); if (_readHandle != null) _readHandle.Close(); _handle.Close(); if (_nativeOverlapped != null) { Marshal.FreeHGlobal((IntPtr) _nativeOverlapped); _nativeOverlapped = null; } if (_segments != null) { Marshal.FreeHGlobal((IntPtr) _segments); _segments = null; } if (DeleteOnClose) { File.Delete(_filename); } }
public static extern bool WriteFile(SafeFileHandle hFile, byte *lpBuffer, int nNumberOfBytesToWrite, out int lpNumberOfBytesWritten, NativeOverlapped *lpOverlapped);
// Will be called from the base class upon InvokeCallback() protected override void Cleanup() { if (m_pOverlapped != null) { m_MemoryBlob = null; Overlapped.Free(m_pOverlapped); m_pOverlapped = null; } GC.SuppressFinalize(this); base.Cleanup(); }
private static unsafe void CompletionPortCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped) { BaseOverlappedAsyncResult asyncResult = (BaseOverlappedAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped) !; if (asyncResult.InternalPeekCompleted) { NetEventSource.Fail(null, $"asyncResult.IsCompleted: {asyncResult}"); } if (NetEventSource.IsEnabled) { NetEventSource.Info(null, $"errorCode:{errorCode} numBytes:{numBytes} nativeOverlapped:{(IntPtr)nativeOverlapped}"); } // Complete the IO and invoke the user's callback. SocketError socketError = (SocketError)errorCode; if (socketError != SocketError.Success && socketError != SocketError.OperationAborted) { // There are cases where passed errorCode does not reflect the details of the underlined socket error. // "So as of today, the key is the difference between WSAECONNRESET and ConnectionAborted, // .e.g remote party or network causing the connection reset or something on the local host (e.g. closesocket // or receiving data after shutdown (SD_RECV)). With Winsock/TCP stack rewrite in longhorn, there may // be other differences as well." Socket?socket = asyncResult.AsyncObject as Socket; if (socket == null) { socketError = SocketError.NotSocket; } else if (socket.Disposed) { socketError = SocketError.OperationAborted; } else { try { // The async IO completed with a failure. // Here we need to call WSAGetOverlappedResult() just so GetLastSocketError() will return the correct error. SocketFlags ignore; bool success = Interop.Winsock.WSAGetOverlappedResult( socket.SafeHandle, nativeOverlapped, out numBytes, false, out ignore); if (!success) { socketError = SocketPal.GetLastSocketError(); } if (success) { NetEventSource.Fail(asyncResult, $"Unexpectedly succeeded. errorCode:{errorCode} numBytes:{numBytes}"); } } catch (ObjectDisposedException) { // Disposed check above does not always work since this code is subject to race conditions socketError = SocketError.OperationAborted; } } } // Set results and invoke callback asyncResult.CompletionCallback((int)numBytes, socketError); }
unsafe internal static extern void CheckVMForIOPacket(out NativeOverlapped *pOVERLAP, out uint errorCode, out uint numBytes);
public static unsafe extern bool ReadFile(PipeHandle hFile, // handle to file byte *lpBuffer, // data buffer int nNumberOfBytesToRead, // number of bytes to read IntPtr numBytesRead_mustBeZero, // number of bytes must be zero NativeOverlapped *lpOverlapped // overlapped buffer );
unsafe internal static extern void FreeNativeOverlapped(NativeOverlapped *nativeOverlappedPtr);
private static extern unsafe void StoreOverlappedPtrInCCW(ObjectHandleOnStack windowsRuntimeBuffer, NativeOverlapped *overlapped);
public static unsafe Overlapped Unpack(NativeOverlapped *nativeOverlappedPtr) { ArgumentNullException.ThrowIfNull(nativeOverlappedPtr); return(OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr)._overlapped !); }
private unsafe void InitializeOverlapped(ThreadPoolBoundHandle boundHandle) { _boundHandle = boundHandle; _ptrNativeOverlapped = boundHandle.AllocateNativeOverlapped(CompletionPortCallback, null, null); }
internal FileStreamAsyncResult( int numBufferedBytes, byte[] bytes, #if USE_OVERLAPPED SafeFileHandle handle, #endif AsyncCallback userCallback, Object userStateObject, bool isWrite) { _userCallback = userCallback; _userStateObject = userStateObject; _isWrite = isWrite; _numBufferedBytes = numBufferedBytes; #if USE_OVERLAPPED _handle = handle; #endif // For Synchronous IO, I could go with either a callback and using // the managed Monitor class, or I could create a handle and wait on it. ManualResetEvent waitHandle = new ManualResetEvent(false); _waitHandle = waitHandle; #if USE_OVERLAPPED // Create a managed overlapped class // We will set the file offsets later Overlapped overlapped = new Overlapped(); overlapped.AsyncResult = this; // Pack the Overlapped class, and store it in the async result var ioCallback = s_IOCallback; // cached static delegate; delay initialized due to it being SecurityCritical if (ioCallback == null) s_IOCallback = ioCallback = new IOCompletionCallback(AsyncFSCallback); _overlapped = overlapped.Pack(ioCallback, bytes); Debug.Assert(_overlapped != null, "Did Overlapped.Pack or Overlapped.UnsafePack just return a null?"); #endif }
public WorkItem(IOTaskScheduler scheduler) { _scheduler = scheduler; _pNOlap = new Overlapped().UnsafePack(Callback, null); }
internal HttpRequestStreamAsyncResult(ThreadPoolBoundHandle boundHandle, object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, uint size, uint dataAlreadyRead) : base(asyncObject, userState, callback) { _dataAlreadyRead = dataAlreadyRead; _boundHandle = boundHandle; _pOverlapped = boundHandle.AllocateNativeOverlapped(s_IOCallback, state: this, pinData: buffer); _pPinnedBuffer = (void*)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset)); }
internal unsafe void ReleaseMemory() { if(m_overlapped != null) { Overlapped.Free( m_overlapped ); m_overlapped = null; } UnpinBuffer(); }
// Will be called from the base class upon InvokeCallback() protected override void Cleanup() { if (_pOverlapped != null) { _memoryBlob = null; _boundHandle.FreeNativeOverlapped(_pOverlapped); _pOverlapped = null; _boundHandle = null; } GC.SuppressFinalize(this); base.Cleanup(); }
private static unsafe void Callback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped) { var asyncResult = (RequestStreamAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped); IOCompleted(asyncResult, errorCode, numBytes); }
/// <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); } }
/// <summary> /// Initiates the next asynchronous read operation if monitoring is still desired. /// If the directory handle has been closed due to an error or due to event monitoring /// being disabled, this cleans up state associated with the operation. /// </summary> private unsafe void Monitor(AsyncReadState state) { // This method should only ever access the directory handle via the state object passed in, and not access it // via _directoryHandle. While this function is executing asynchronously, another thread could set // EnableRaisingEvents to false and then back to true, restarting the FSW and causing a new directory handle // and thread pool binding to be stored. This function could then get into an inconsistent state by doing some // operations against the old handles and some against the new. NativeOverlapped *overlappedPointer = null; bool continueExecuting = false; try { // If shutdown has been requested, exit. The finally block will handle // cleaning up the entire operation, as continueExecuting will remain false. if (!_enabled || IsHandleInvalid(state.DirectoryHandle)) { return; } // Get the overlapped pointer to use for this iteration. overlappedPointer = state.ThreadPoolBinding.AllocateNativeOverlapped(state.PreAllocatedOverlapped); int size; continueExecuting = Interop.Kernel32.ReadDirectoryChangesW( state.DirectoryHandle, state.Buffer, // the buffer is kept pinned for the duration of the sync and async operation by the PreAllocatedOverlapped _internalBufferSize, _includeSubdirectories, (int)_notifyFilters, out size, overlappedPointer, IntPtr.Zero); } catch (ObjectDisposedException) { // Ignore. Disposing of the handle is the mechanism by which the FSW communicates // to the asynchronous operation to stop processing. } catch (ArgumentNullException) { //Ignore. The disposed handle could also manifest as an ArgumentNullException. Debug.Assert(IsHandleInvalid(state.DirectoryHandle), "ArgumentNullException from something other than SafeHandle?"); } finally { // At this point the operation has either been initiated and we'll let the callback // handle things from here, or the operation has been stopped or failed, in which case // we need to cleanup because we're no longer executing. if (!continueExecuting) { // Clean up the overlapped pointer created for this iteration if (overlappedPointer != null) { state.ThreadPoolBinding.FreeNativeOverlapped(overlappedPointer); } // Clean up the thread pool binding created for the entire operation state.PreAllocatedOverlapped.Dispose(); state.ThreadPoolBinding.Dispose(); // Finally, if the handle was for some reason changed or closed during this call, // then don't throw an exception. Otherwise, it's a valid error. if (!IsHandleInvalid(state.DirectoryHandle)) { OnError(new ErrorEventArgs(new Win32Exception())); } } } }
internal HttpRequestStreamAsyncResult(object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, uint size, uint dataAlreadyRead): base(asyncObject, userState, callback) { m_dataAlreadyRead = dataAlreadyRead; Overlapped overlapped = new Overlapped(); overlapped.AsyncResult = this; m_pOverlapped = overlapped.Pack(s_IOCallback, buffer); m_pPinnedBuffer = (void*)(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset)); }
private static unsafe void WaitCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped) { var asyncResult = (ClientCertLoader)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped); IOCompleted(asyncResult, errorCode, numBytes); }
internal unsafe DisconnectAsyncResult(HttpListener httpListener, ulong connectionId) { if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"HttpListener: {httpListener}, ConnectionId: {connectionId}"); _ownershipState = 1; _httpListener = httpListener; _connectionId = connectionId; // we can call the Unsafe API here, we won't ever call user code _nativeOverlapped = httpListener._requestQueueBoundHandle.AllocateNativeOverlapped(s_IOCallback, state: this, pinData: null); }
private static unsafe void GetAddressInfoExCallback([In] int error, [In] int bytes, [In] NativeOverlapped *overlapped) { // Can be casted directly to GetAddrInfoExContext* because the overlapped is its first field GetAddrInfoExContext *context = (GetAddrInfoExContext *)overlapped; ProcessResult((SocketError)error, context); }
internal static unsafe void StoreOverlappedInCCW(object windowsRuntimeBuffer, NativeOverlapped *overlapped) { WindowsRuntimeBufferHelper.StoreOverlappedPtrInCCW(JitHelpers.GetObjectHandleOnStack <object>(ref windowsRuntimeBuffer), overlapped); }
internal static extern uint HttpReceiveRequestEntityBody(CriticalHandle requestQueueHandle, ulong requestId, uint flags, void *pEntityBuffer, uint entityBufferLength, out uint bytesReturned, NativeOverlapped *pOverlapped);
// Method to clean up any existing Overlapped object and related state variables. private unsafe void FreeOverlapped(bool checkForShutdown) { if (!checkForShutdown || !Environment.HasShutdownStarted) { // Free the overlapped object if (_ptrNativeOverlapped != null) { _boundHandle.FreeNativeOverlapped(_ptrNativeOverlapped); _ptrNativeOverlapped = null; } if (_dataChunksGCHandle.IsAllocated) { _dataChunksGCHandle.Free(); _dataChunks = null; } } }
private unsafe int WriteFileNative(SafePipeHandle handle, ReadOnlySpan <byte> buffer, NativeOverlapped *overlapped, out int errorCode) { DebugAssertHandleValid(handle); Debug.Assert((_isAsync && overlapped != null) || (!_isAsync && overlapped == null), "Async IO parameter screwup in call to WriteFileNative."); // You can't use the fixed statement on an array of length 0. Note that async callers // check to avoid calling this first, so they can call user's callback if (buffer.Length == 0) { errorCode = 0; return(0); } int r = 0; int numBytesWritten = 0; fixed(byte *p = &buffer.DangerousGetPinnableReference()) { r = _isAsync ? Interop.Kernel32.WriteFile(handle, p, buffer.Length, IntPtr.Zero, overlapped) : Interop.Kernel32.WriteFile(handle, p, buffer.Length, out numBytesWritten, IntPtr.Zero); } if (r == 0) { errorCode = Marshal.GetLastWin32Error(); return(-1); } else { errorCode = 0; return(numBytesWritten); } }
public ScheduledOverlapped() { this.nativeOverlapped = (new Overlapped()).UnsafePack( Fx.ThunkCallback(new IOCompletionCallback(IOCallback)), null); }
public unsafe void EndReceive(uint code, uint bytes, NativeOverlapped *native) { Overlapped.Free(native); Message.Props.Free(); lock (Outstanding) Outstanding.Remove(this); if (code == 995) // operation aborted { Tcs.TrySetException(new QueueException(ErrorCode.OperationCanceled)); return; } var result = Native.GetOverlappedResult(native); try { switch (result) { case 0: Message.Props.ResizeBody(); Tcs.TrySetResult(Message); break; case (int)ErrorCode.InsufficientResources: Tcs.SetException(new OutOfMemoryException("async receive operation reported InsufficientResources")); break; case (int)ErrorCode.IOTimeout: Tcs.TrySetResult(null); break; default: // successfully completed but no enough memory if (Native.NotEnoughMemory(result)) { Message.Props.Free(); Message.Props.IncreaseBufferSize(); Props = Message.Props.Allocate(); var overlapped = new Overlapped(); var nativeOverlapped = overlapped.Pack(EndReceive, null); int res = Native.ReceiveMessage(handle, timeoutMS, action, Props, nativeOverlapped, null, cursor, IntPtr.Zero); if (res == MQ_INFORMATION_OPERATION_PENDING) // running asynchronously { return; } // call completed synchronously Message.Props.Free(); Overlapped.Free(nativeOverlapped); if (!Native.IsError(res)) { Message.Props.ResizeBody(); Tcs.TrySetResult(Message); return; } } // some other error Tcs.TrySetException(new QueueException(unchecked ((int)code))); // or do we use the result? break; } } catch (ObjectDisposedException ex) { Tcs.TrySetException(new QueueException(ErrorCode.OperationCanceled)); } }
unsafe internal static extern int ReadFile( SafeHandle handle, byte *bytes, int numBytesToRead, IntPtr numBytesRead_mustBeZero, NativeOverlapped *overlapped);
internal static unsafe partial bool GetOverlappedResult( SafeFileHandle hFile, NativeOverlapped *lpOverlapped, ref int lpNumberOfBytesTransferred, bool bWait);
public void Dispose() { Disposed = true; GC.SuppressFinalize(this); if (_readHandle != null) _readHandle.Close(); _handle.Close(); if (_nativeOverlapped != null) { Marshal.FreeHGlobal((IntPtr) _nativeOverlapped); _nativeOverlapped = null; } if (_segments != null) { Marshal.FreeHGlobal((IntPtr) _segments); _segments = null; } if (DeleteOnClose) { try { File.Delete(_filename); } catch (Exception) { // if we can't delete, nothing that we can do here. } } }
private unsafe void CompletionPortCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped) { if (errorCode == Interop.HttpApi.ERROR_SUCCESS || errorCode == Interop.HttpApi.ERROR_HANDLE_EOF) { FinishOperationSuccess((int)numBytes, false); } else { FinishOperationFailure(new HttpListenerException((int)errorCode), false); } }