public OverlappedEntry ( nuint?lpCompletionKey = null, Overlapped *lpOverlapped = null, nuint? @internal = null, uint?dwNumberOfBytesTransferred = null ) : this() { if (lpCompletionKey is not null) { LpCompletionKey = lpCompletionKey.Value; } if (lpOverlapped is not null) { LpOverlapped = lpOverlapped; } if (@internal is not null) { Internal = @internal.Value; } if (dwNumberOfBytesTransferred is not null) { DwNumberOfBytesTransferred = dwNumberOfBytesTransferred.Value; } }
public IOLoop() { Thread mthread = new Thread(delegate() { unsafe { while (true) { IntPtr[] handles = null; int count = -1; lock (ops) { count = ops.Count; handles = new IntPtr[count + 1]; fixed(IntPtr * handles_ptr = handles) { IntPtr *hptr = handles_ptr + 1; handles[0] = evt.SafeWaitHandle.DangerousGetHandle(); for (int i = 0; i < ops.Count; i++) { hptr[i] = ((Overlapped *)(ops[i].overlapped.AddrOfPinnedObject()))->hEvent; } } } WaitForMultipleObjects(count + 1, handles, false, -1); lock (ops) { List <AsyncIOOperation> toRemove = new List <AsyncIOOperation>(); foreach (var iable in ops.ToList()) //Copy list in case callback updates it. { //!= 259 Overlapped *olap = (Overlapped *)iable.overlapped.AddrOfPinnedObject(); if (olap->Internal.ToInt64() != 259) { int transferred = olap->InternalHigh.ToInt32(); iable.cb(transferred); toRemove.Add(iable); iable.buffy.Free(); iable.bytes.Free(); iable.flags.Free(); iable.overlapped.Free(); } } foreach (var iable in toRemove) { ops.Remove(iable); } } } } }); mthread.IsBackground = true; mthread.Start(); }
private unsafe void CompletionWorkerThreadProc() { { int count; do { count = Volatile.Read(ref m_completionPortRefCount); if (count < 1) { // Manager disposed before this thread started. return; } }while (Interlocked.CompareExchange(ref m_completionPortRefCount, count + 1, comparand: count) != count); } try { while (true) { FileSystemWin.IOCompletionPortDequeueResult result = FileSystemWin.GetQueuedCompletionStatus(m_completionPort); Contract.Assume( result.Status != FileSystemWin.IOCompletionPortDequeueStatus.CompletionPortClosed, "We terminate all workers before closing the port (otherwise we risk a handle-recycle race)."); Contract.Assert(result.Status == FileSystemWin.IOCompletionPortDequeueStatus.Succeeded); if (result.DequeuedOverlapped == null) { // Completion port is being closed; this is a poison message. Contract.Assume(result.CompletionKey == s_queueCloseCompletionKey); break; } // The OVERLAPPED* attached to each packet is unique to each I/O request. It should be one // that we allocated earlier with AllocateOverlapped. We took care to place a request identifier // immediately after the OVERLAPPED, so we can find the completion target. Overlapped *deqeuedOverlapped = result.DequeuedOverlapped; var taggedOverlapped = (TaggedOverlapped *)deqeuedOverlapped; ReleaseOvelappedAndQueueCompletionNotification(taggedOverlapped, result.CompletedIO); } DecrementCompletionPortRefCount(); } catch (Exception ex) { ExceptionUtilities.FailFast("Catastrophic failure in I/O completion worker", ex); throw; } }
/// <inheritdoc/> public unsafe void CancelOverlapped(SafeFileHandle handle, Overlapped *overlapped) { Contract.Requires(!handle.IsInvalid); Contract.Requires(overlapped != null); TaggedOverlapped *taggedOverlapped = (TaggedOverlapped *)overlapped; if (taggedOverlapped->EntryId == TaggedOverlapped.AvailableMarker) { return; } // Best effort. Analysis.IgnoreResult(FileSystemWin.TryCancelIoWithOverlapped(handle, overlapped, out int _)); }
public void ReceiveAsync(byte[] buffer, int offset, int count, OnIOComplete completionHandler) { unsafe { AsyncIOOperation op = new AsyncIOOperation(); op.overlapped = GCHandle.Alloc(new Overlapped(), GCHandleType.Pinned); Overlapped *overlapped = (Overlapped *)op.overlapped.AddrOfPinnedObject(); overlapped->hEvent = CreateEventW(IntPtr.Zero, true, false, IntPtr.Zero); op.buffy = GCHandle.Alloc(new WSABuf(), GCHandleType.Pinned); WSABuf *buffy = (WSABuf *)op.buffy.AddrOfPinnedObject(); op.bytes = GCHandle.Alloc(buffer, GCHandleType.Pinned); buffy->buf = op.bytes.AddrOfPinnedObject() + offset; buffy->len = (uint)count; op.flags = GCHandle.Alloc(0, GCHandleType.Pinned); int r = WSARecv(Handle, new IntPtr(buffy), 1, IntPtr.Zero, op.flags.AddrOfPinnedObject(), new IntPtr(overlapped), IntPtr.Zero); int a = WSAGetLastError(); op.fd = Handle; op.cb = completionHandler; IOLoop.dispatch_loop.Post(op); } }
/// <inheritdoc /> public unsafe void Cancel(Overlapped *overlapped) => m_ioCompletionManager.CancelOverlapped(m_handle, overlapped);
/// <inheritdoc /> public unsafe void Cancel(Overlapped *overlapped) => throw new NotImplementedException();
public static unsafe extern int WriteFile(IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToWrite, uint *lpNumberOfBytesWritten, Overlapped *lpOverlapped);
public static unsafe extern int ReadFile(IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToRead, uint *nNumberOfReadBytes, Overlapped *lpOverlapped);